Willkommen Gast. Bitte einloggen oder registrieren.
März 15, 2025, 19:53:43
Übersicht Ungelesene Beitrge auflisten Hilfe Suche Spiele Mitgliederkarte Kalender Login Registrieren

Schnellsuche
+  MODDING-FAQ FORUM
|-+  Alles rund ums Modden
| |-+  Elektronik, Elektrik (Moderator: TzA)
| | |-+  Taster als Schalter via AVR
  « vorheriges nächstes »
0 Mitglieder und 0 Gäste betrachten dieses Thema.
Seiten: 1 ... 8 9 10 11 12 [13] 14 15 16 17 nach unten Drucken
Autor Thema: Taster als Schalter via AVR  (Gelesen 152110 mal)
PoWl
Dremelfreund

*

Karma: +0/-0
Offline Offline
Beiträge: 140


Atmel AVR Mikrocontroller


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #180 am: November 22, 2007, 17:21:56 »

richtig Ich nehme an du sendest ASCII an deinen PC, dann mach alle häkchen bis auf das bei Ascii weg dann hast du nicht mehr die farbigen Balken. Dann machst noch bei new line at [CR] dann wird immer n zeilenumbruch gemacht wenn du ascii 13 an den PC schickst. Dann noch das häkchen bei show newline chars wegmachen.
Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #181 am: November 22, 2007, 23:04:17 »

Soooo... um mal zu meinem UART Problem zurück zu kommen... Dank HTerm weis ich nun das mein µC zwar sendet aber immer nur zwei Werte. Entweder den Wert 0 oder 128 Cheesy
Die Folge ist relativ willkürlich... bimmelt bei irgendwem da ein total offensichtlicher fehler?

EDIT:
Problem gelöst. bzw. ein neuer µC löste das Problem Cheesy

EDIT2:
Also entweder schrotte ich die µC's andauernd aus einem unerklärlichem Grund oder es liegt nicht am µC weil der neue welche rgerade noch funktioniert hat funktioniert nun auch nicht mehr. Er sendet nur noch den Wert 10000000
Er sendet zwar jedes mal dann wenn er soll aber nur diesen Wert. auch wenn ich das Register mit einem eindeutigen Wert belege!

EDIT3: Verdammt ich kann dieses dumme € Zeichen nicht mehr sehen! Cheesy dafür funktioniert der Empfang schonmal provisorisch...
« Letzte Änderung: November 22, 2007, 23:39:54 von Fabeulous » Gespeichert
Reisi
Lötkolbenfreak

*

Karma: +2/-0
Offline Offline
Beiträge: 190



Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #182 am: November 23, 2007, 14:04:19 »

... bimmelt bei irgendwem da ein total offensichtlicher fehler?
Ja, falsche Taktquelle! Der interne Oszillator ist für UART viel zu ungenau.
Gespeichert
PoWl
Dremelfreund

*

Karma: +0/-0
Offline Offline
Beiträge: 140


Atmel AVR Mikrocontroller


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #183 am: November 23, 2007, 14:16:00 »

sicher dass mit den fusebits alles in ordnung is?
Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #184 am: November 23, 2007, 18:06:37 »

Hey ihr seit gut! Cheesy Ne ich hab natürlich nach dem Wechsel des µC's vergessen die FuseBits zu setzen...
Danke!

EDIT:

So ich habe wieder meine Probleme mit den Fuse Bits.
Ich habe ein 8 Mhz Quarz. Ist ja ein External Crystal richtig?
Also müsste CKSEl auf 1111 aber ich weis nicht mehr was dieses Sut bedeutet und welchen Wert es haben muss? Wäre nett wenn ihr mir das nochmal erklären könntet... Embarrassed

EDIT2:
So ich habe mich etzt für CKSEL 1111 und SUT(hab gerade gelernt das bedeutet Start Up Time) 00
Also der µC läuft
aber nun blinken alle LED's willkürlich vor sich hin und ich weis mal wieder nicht warum sie das tun...

EDIT3:
Also ich bin schonmal soweit das ich weis das es am Quelltext liegen muss...

EDIT4:
Also heute reize ich die Editier funktion aus...
War wohl die richtige Einstellung. Wobei der Empfang wohl irgendwie nich beinträchtigt wird.
Ich habe jetzt folgendes Programm als Testprogramm genommen:
Code:
.include "m8def.inc"

.def temp = r16

.equ F_CPU = 8000000        ; Systemtakt in Hz
.equ BAUD  = 9600           ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

        ; Stackpointer initialisieren
        ldi temp, LOW(RAMEND)
        out SPL, temp
        ldi temp, HIGH(RAMEND)
        out SPH, temp

        ; Baudrate einstellen
        ldi temp, HIGH(UBRR_VAL)
        out UBRRH, temp
        ldi temp, LOW(UBRR_VAL)
        out UBRRL, temp

        ; Frame-Format: 8 Bit
        ldi temp, (1<<URSEL)|(3<<UCSZ0)
        out UCSRC, temp

        sbi UCSRB,TXEN                    ; TX aktivieren

loop:   ldi temp, 'T'
        rcall serout                      ; Unterprogramm aufrufen
        ldi temp, 'e'
        rcall serout                      ; Unterprogramm aufrufen
        ldi temp, 's'
        rcall serout                      ; ...
        ldi temp, 't'
        rcall serout
        ldi temp, '!'
        rcall serout
        ldi temp, 10
        rcall serout
        ldi temp, 13
        rcall serout
        rjmp loop

serout:
        sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste
                                          ; Byte bereit ist
        rjmp serout
        out UDR, temp
        ret                               ; zurück zum Hauptprogramm

Das ist das Testprogramm von Microcontroller.net welches einfach das Werto "Test" in einer Endlosschliefe an den PC sendet...

UNd in HTerm bekomme ich das als Ergebnis
Code:
<\0>.W’¨ˆUÍÑ…)5Q•ÍQ•Í…)5Q•ÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…)5Q•åTest!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
TTest!<\n><\r>
Test!<\n><\r>
TTest!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test¡<\n>Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
TTest!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
TesTest!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n>Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n>Test!<\n><\r>
Tµ.UÖ<23>W’¨ˆUÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…) ... 5Q•ÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…)5Q•ÍÑ…)5QeTest!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n><\r>
Test!<\n>

Kann sich jemand von euch erklären warum zwischenzeitlich so zerhackstückelte Wörter dabei sind?

EDIT5:
So nun habe ich mein altes Programm wieder laufen. Aber die LED's gehen willkürlich an und aus. Wenn ich jedoch auf interne Taktquelle stelle(also Standardeinstellung) läuft der Code problemlos)
Außerdem wird per UART die ganze Zeit ein byte mit dem Wert 255 gesendet!

EDIT6:
So nochmal sorry das das ganze sich hier so ausbnreitet. Aber ich will euch ja nur auf dem neusten Stand halten... Embarrassed
Also das mit den LED's liegt an meinen schleifen. Also die Schleifen die pürfen ob eine Taste geprüft wurde und welche dann den Zustand der betreffenden LED umdrehen.

Ich poste euch mal meinen aktuellen Code. (Bitte die Dateiendung durch .asm ersetzen)
Die "Schleife1" bis "Schleife7" sind das Problem aber ich weis nicht warum weil den ist es doch eigentlich egal mit welchem Takt die laufen oder nicht?

* Relaiskarte.gif (2.26 KB - runtergeladen 2 Mal.)
« Letzte Änderung: November 28, 2007, 20:04:02 von Crawler » Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #185 am: November 24, 2007, 19:30:16 »

Also ich habe heute nochmal geschaut.
Selbst wenn ich den Code drastisch dezimiere bliebt das Problem.
Ich hab nun den folgenden Code ausprobiert:
Code:
.include "m8def.inc"
.def temp1      = r16
.def temp2  = r17
.def tast_neu  = r18
.def tast_alt  = r19
.def temp_send  = r20
.def alter_taster_status= r21



ldi    temp1, 0b00111111  ;PORTC -> Ausgang
out    DDRC, temp1

ldi    temp1, 0b00011111 ;PORTB -> Pull-Up Widerstände ein
out    PORTB, temp1

ldi    temp1, 0b00001100 ;PORTD -> Ausgang und Eingang
out    DDRD, temp1

ldi    temp1, 0b11100000 ;PORTD -> Pull-Up Widerstände ein
out    PORTD, temp1





haupt:



sbic PIND, 7 ; Wenn aktuelles Bit=0  springe zur Sprungmarke schleife_1
rjmp haupt


pruefen_0:
sbis PORTD, 2 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_0 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_0 ; Wenn es 1 ist tu das(Ausschalten)

an_0:
sbi PORTD, 2 ; Einschalten :P
rjmp haupt


aus_0:
cbi PORTD, 2 ; Ausschalten :P

      rjmp  haupt


Dieser Code soll halt auf ein "LOW" an PinD 7 warten. Wenn dieses "da ist" soll halt der Zustand an PORTD 2 invertiert werden(LED aus oder an(je nach dem wie der vorherige Zustand war)). Aber stattdessen geht die LED willkürlich an und aus. Wenn ich allerdings wieder die Standard taktquelle einstelle dann funktioniert der Code problemlos.
Ich weis echt nicht woran das liegen kann weil ich ja garkeine Stellen im Code habe welche vom Takt abhängig sind. Und wenn ich die falsche Taktquelle hätte dürfte der µC doch garnicht mehr programmierbar sein oder?
Bitte helft mir. Ich weis echt nicht woran das noch liegen kann! Ist eventuell der µC kaputt?
Danke schonmal!

EDIT:
Kann es sein das ich auch noch CKOPT=1 setzen muss?
« Letzte Änderung: November 24, 2007, 19:42:02 von Fabeulous » Gespeichert
PoWl
Dremelfreund

*

Karma: +0/-0
Offline Offline
Beiträge: 140


Atmel AVR Mikrocontroller


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #186 am: November 25, 2007, 02:05:49 »

wir müssten uns jetzt intensiver mit dem problemchen beschäftigen, ich persönlich hab dazu keine zeit. Wenn du mit µCs arbeiten willst musst du damit rechnen dass es öfter mal passiert dass da irgendwelche kuriosen fehler auftreten die man erstmal aufspüren muss. Am besten ist immer das programm auf das nötigste reduzieren, das mit diesem fehler zu tun hat und gucken ob er dann immernoch auftritt. Das hast du ja gemacht. Hab mir den code nicht angeschaut.

Ich empfehl dir dass du im Datenblatt mal guckst was es mit CKOPT, SUT und CKSEL bits auf sich hat. Das könnten wir dir zwar auch erklären aber du solltest lernen selbst mit dem Datenblatt zurecht zu kommen. :-)

mfg PoWl
Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #187 am: November 27, 2007, 00:25:23 »

So ich wollte mich mal kurz melden. Dank Google Datenblatt und Co bin ich nun zu dem Schluss gekommen das CKOPT aktiviert bzw. gesetzt werden muss. Wenn ich das richtig verstanden hatte und mein Englisch ausreicht dann aktiviert das wohl eine Art verstärker welchen man für ein Quarz benötigt. Stimmt das?

Ich habe mich natürlich direkt ans Programmieren gesetzt bzw. saß bis gerade noch dran.
Nun funktioniert die Ausgabe des aktuellen LED Statuses an den PC. Also der PC bekommt ca. 2 mal in der Sekunde gesagt welche LED's an sind und welche aus sind.

Und das schalten der LED's über den PC funktioniert auch.

Leider hat der erhöhte Takt meine etwas provisorische und unasgereifte Tasterentprellung zerhauen. Ich werde mir da nun was vernünftiges überlegen. habe mich gerade durch Timer und deren Interrupts gekampft und ich hab da schon ein paar Ideen. Aber nun werde ich erstmal ins Bett gehen. Denn in 5 Stunden und 40 minutenb muss ich wieder aufstehen! In diesem Sinne gute Nacht! Tongue

EDIT:
So hier mal der von mir gestern gebastelte Code.
Wie man sieht habe ich das ganze Nun mit Interrupts gelöst. Durch einen Timer Overflow wird ca. 2 mal in der Sekunde der aktuelle Status der LED's an den PC übertragen.

Das Empfangen funktioniert auch mit einem Interrupt. Ich denke hier ist (euch sowieso) klar wie das geht! Cheesy
Code:
.include "m8def.inc"
.def temp1      = r16
.def temp2  = r17
.def temp_send  = r18
.def temp_empfangen = r19
.def alter_taster_status= r20
.def timer0_zaehler = r21


.equ F_CPU = 8000000        ; Systemtakt in Hz
.equ BAUD  = 9600           ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

.org 0x0000
        rjmp    main                  ; Reset Handler

.org OVF0addr
        rjmp    timer0_overflow       ; Timer Overflow Handler

.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp int_rxc



main:
ldi    temp1, 0b00111111  ;PORTC -> Ausgang
out    DDRC, temp1
ldi    temp1, 0b00011111 ;PORTB -> Pull-Up Widerstände ein
out    PORTB, temp1
ldi    temp1, 0b00001100 ;PORTD -> Ausgang und Eingang
out    DDRD, temp1
ldi    temp1, 0b11100000 ;PORTD -> Pull-Up Widerstände ein
out    PORTD, temp1
;Timer Einstelungen -----------------------------------------------------
ldi     temp1, 0b00000101      ; CS00 setzen: Teiler 1024
        out     TCCR0, temp1
        ldi     temp1, 0b00000001      ; TOIE0: Interrupt bei Timer Overflow
        out     TIMSK, temp1

ldi timer0_zaehler, 0
;Timer Einstelungen -----------------------------------------------------
       
ldi     temp1, LOW(RAMEND)     ; Stackpointer initialisieren
        out     SPL, temp1
        ldi     temp1, HIGH(RAMEND)
        out     SPH, temp1

;UART Einstelungen -----------------------------------------------------
; Baudrate einstellen
        ldi temp1, HIGH(UBRR_VAL)
        out UBRRH, temp1
        ldi temp1, LOW(UBRR_VAL)
        out UBRRL, temp1

; Frame-Format: 8 Bit
        ldi temp1, (1<<URSEL)|(3<<UCSZ0)
        out UCSRC, temp1


        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB,TXEN   ; TX (Senden) aktivieren
sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
;UART Einstelungen -----------------------------------------------------

sei
warten:



ldi  temp1, $FF             ; ein bisschen warten ...
wait1:
      ldi  temp2, $FF
wait2:

      dec  temp2
      brne wait2
      dec  temp1
      brne wait1



haupt:






      rjmp  haupt

;Senden ----------------------------------------------------

timer0_overflow:
cpi timer0_zaehler, 15 ; 2 Mal pro (ca. 1) Sekunde wird der aktuelle Status an den PC gesendet

brne timer0_weiter

ldi  temp_send, 0
        in   temp_send, PIND            ; PINB -> temp2 (00011111)
swap temp_send
        andi temp_send, 0b11000000

sbic PORTC, 0
ori temp_send, 0b00100000
sbic PORTC, 1
ori temp_send, 0b00010000
sbic PORTC, 2
ori temp_send, 0b00001000
sbic PORTC, 3
ori temp_send, 0b00000100
sbic PORTC, 4
ori temp_send, 0b00000010
sbic PORTC, 5
ori temp_send, 0b00000001
                     ; Timer 0 Overflow Handler
serout:
        sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste
                                          ; Byte bereit ist
        rjmp serout
        out UDR, temp_send
ldi timer0_zaehler, 0

rjmp timer0_weiter1

timer0_weiter:
inc timer0_zaehler
timer0_weiter1:

        reti

;Senden ----------------------------------------------------



;Empfangen -------------------------------------------------

int_rxc:
        in temp_empfangen, UDR ;Einlesen des empfangenen bytes in temp_empfangen

sbrs temp_empfangen, 6 ; Wenn aktuelles bit 7 = 1 übersrpinge den nächsten befehl
rjmp schleife_UART_1

sbis PORTD, 2 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_0 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_0 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_0:
sbi PORTD, 2 ; Einschalten :P
rjmp schleife_UART_1


aus_UART_0:
cbi PORTD, 2 ; Ausschalten :P


schleife_UART_1:
sbrs temp_empfangen, 7 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_2

sbis PORTD, 3 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_1 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_1 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_1:
sbi PORTD, 3 ; Einschalten :P
rjmp schleife_UART_2

aus_UART_1:
cbi PORTD, 3 ; Ausschalten :P

schleife_UART_2:
sbrs temp_empfangen, 5 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_3

sbis PORTC, 0 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_2 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_2 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_2:
sbi PORTC, 0 ; Einschalten :P
rjmp schleife_UART_3

aus_UART_2:
cbi PORTC, 0 ; Ausschalten :P

schleife_UART_3:
sbrs temp_empfangen, 4 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_4

sbis PORTC, 1 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_3 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_3 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_3:
sbi PORTC, 1 ; Einschalten :P
rjmp schleife_UART_4
aus_UART_3:
cbi PORTC, 1 ; Ausschalten :P

schleife_UART_4:
sbrs temp_empfangen, 3 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_5

sbis PORTC, 2 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_4 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_4 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_4:
sbi PORTC, 2 ; Einschalten :P
rjmp schleife_UART_5

aus_UART_4:
cbi PORTC, 2 ; Ausschalten :P

schleife_UART_5:
sbrs temp_empfangen, 2 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_6

sbis PORTC, 3 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_5 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_5 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_5:
sbi PORTC, 3 ; Einschalten :P
rjmp schleife_UART_6

aus_UART_5:
cbi PORTC, 3 ; Ausschalten :P

schleife_UART_6:
sbrs temp_empfangen, 1 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp schleife_UART_7

sbis PORTC, 4 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_6 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_6 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_6:
sbi PORTC, 4 ; Einschalten :P
rjmp schleife_UART_7

aus_UART_6:
cbi PORTC, 4 ; Ausschalten :P


schleife_UART_7:
sbrs temp_empfangen, 0 ; Wenn aktuelles Bit=0  springe zur Sprungmarke weiter_D
rjmp ende

sbis PORTC, 5 ; Prüfe ob das aktuelle(index=zaehler) Bit am PORTD 1 ist
rjmp an_UART_7 ; Wenn es 0 ist tu das(Einschalten)
rjmp aus_UART_7 ; Wenn es 1 ist tu das(Ausschalten)

an_UART_7:
sbi PORTC, 5 ; Einschalten :P
rjmp ende

aus_UART_7:
cbi PORTC, 5 ; Ausschalten :P




ende:
        reti                              ; Interrupt beenden

;Empfangen -------------------------------------------------

An den teilen aus "haupt" und "warten" arbeite ich nun...
« Letzte Änderung: November 27, 2007, 23:16:28 von Fabeulous » Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #188 am: November 28, 2007, 00:11:47 »

So ich hab ein problem(mal wieder) Cheesy
Google war auch nciht sehr aussagekräftig bzw. unverständlich.
Ich habe hier sonne Interrupr Vektortabelle:

Code:
.org 0x0000
        rjmp    main                  ; Reset Handler

.org OC1Aaddr
        rjmp timer1_compare      ; Timer Compare Handler

.org OVF0addr
        rjmp    timer0_overflow       ; Timer Overflow Handler

.org URXCaddr                           ; Interruptvektor für UART-Empfang
        rjmp int_rxc

Wenn ich das so schreibe klappt das assemblieren. Jedoch wird der Overflow INterrupt vom Timer0 ignoriert. Wenn ich das ganze so schreibe:

Code:
.org 0x0000
        rjmp    main                  ; Reset Handler

.org OVF0addr
        rjmp    timer0_overflow       ; Timer Overflow Handler

.org URXCaddr                           ; Interruptvektor für UART-Empfang
        rjmp int_rxc

.org OC1Aaddr
        rjmp timer1_compare      ; Timer Compare Handler

Klappt das assemblieren garnicht. Ich hab zwar eine erklärung dafür gefunden. Jedoch war die recht bescheiden und mir wurde auch keien Lösung ersichtlich... Kann man keine zwei Timer gleichzeitig laufen lassen?

P.S.: Die Tasterentprellung ist auch fertig. Ich bin also bis auf diese Sache mit dem µC Quelltext durch...

Gespeichert
PoWl
Dremelfreund

*

Karma: +0/-0
Offline Offline
Beiträge: 140


Atmel AVR Mikrocontroller


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #189 am: November 28, 2007, 07:55:16 »

springst du danach auch schön ans ende der interrupt vektoren? wenn du die adressen durcheinander belegst und am ende eine, die am anfang, vor nachfolgenden steht, und dein programmcode beginnt, dann würde dieser ja die anderen vektoren überschreiben.

//Edit: was hab ich da bitte geschrieben, das kappiert ja kein Schwein :-D, gemeint ist dass wenn der programmcode schon am anfang des  interruptvektorbereich anfängt und man dann einen späteren interruptvektor belegen möchte, es hier einen konflikt gibt, da dieser dann doppelt belegt/überschrieben würde.

ist der ovf0 interrupt überhaupt aktiviert?

ausserdem wärs nett wenn du uns sagst was für ne fehlermeldung der ausspuckt. :-)
« Letzte Änderung: November 28, 2007, 17:52:54 von PoWl » Gespeichert
OlafSt
Global Moderator

*

Karma: +13/-0
Offline Offline
Geschlecht: Männlich
Beiträge: 2138


Master of STLCD and LISA III


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #190 am: November 28, 2007, 07:58:45 »

Außerdem zerstört irgendwas an deinen Posts oder deiner Signatur nachhaltig das Layout hier... Wirf doch bitte mal einen kritischen Blick darauf
Gespeichert

Erstens: Lies was da steht. Zweitens: Denk drüber nach. Drittens: Dann erst fragen
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #191 am: November 28, 2007, 17:38:49 »

Erstmal Sorry wenn meine größeren Quelltextpostings hier doof aussehen. ICh versuche das in Zukunft zu vermeiden.

Also das mit dem Fehler hat sich erledigt. Ich habe aber immernoch das Problem das ich nicht Timer0 und Timer1 gleichzeitig benutzen kann.
Timer0 ist bei mir für das Senden des aktuellen Statuses zuständig. Bei jedem Overflow von Timer0 wird das register "timer0_zaehler" um eins erhöht. Wenn das register dann den Wert 15 erreicht hat wird der Status der LED's ermittelt und per UART an den PC übertragen. Das register "timer0_zaehler" wird wieder gleich null gesetzt und alles beginnt von vorne. Dies hat bei einem Takt von 8 Mhz die Folge das etwa zwei mal in der Sekunde der Status an den PC gesendet wird.
Das funktioniert auch.

Nun habe ich ja mit der Tasterentprellung angefangen bzw. auch fertigggestellt.
Dazu habe ich statt der primitiven Warteschleife vorher. Nach einem Tastendruck den Timer1 im CTC Modus gestartet. Bei dem Wert 39999 wird der CTC Interrupt ausgelöst. Bei jedem CTC Interrupt wird das register "timer1_zaehler" um eins erhöht.
Gleichzeitig befindet sich das Hauptprogramm in einer Zählschleife. Diese wird erst verlassen wenn das register "timer1_zaehler" den Wert 25 hat. Dies bedeutet das der µC nach jedem Tastendruck für ca. 1/8 Sekunde nicht auf Tastendrücke reagiert.
Erst nachdem diese Schleife verlassen wurde ist der µC wieder in der Lage auf Tastendrücke zu reagieren.

Nun zu meinem Problem. Vlt. hängt es auch mit dem vorrangegangenen Zusammen.
Wenn ich den CTC Modus beim Timer0 aktiviere. Dann reagiert der Timer0 nicht mehr auf seinen Overflow Interrupt. ICh weis aber nicht Wieso?!

Im Anhang ist nochmal der .asm Code als .gif also einfach die Dateiendung .gif gegen .asm tauschen!
Ach und danke für den Tip mit der Vektortabelle! Das hätte ich nicht rausbekommen Cheesy

EDIT:
Okay ich hab den Fehler gefunden. Es funktioniert.
Undzwar folgendes:
Meine "Timerdefintion":
Code:
;Timer0 Einstelungen -----------------------------------------------------
ldi     temp1, 0b00000101      ; CS00 setzen: Teiler 1024
        out     TCCR0, temp1
        ldi     temp1, 0b00000001      ; TOIE0: Interrupt bei Timer Overflow
        out     TIMSK, temp1

ldi timer0_zaehler, 0
;Timer0 Einstelungen -----------------------------------------------------
;Timer1 Einstelungen -----------------------------------------------------

ldi     temp1, high( 40000 - 1 )
           out     OCR1AH, temp1
           ldi     temp1, low( 40000 - 1 )
           out     OCR1AL, temp1
                                       ; CTC Modus einschalten
                                       ; Vorteiler auf 1
           ldi     temp1, ( 1 << WGM12 )
   out     TCCR1B, temp1

           ldi     temp1, 1 << OCIE1A  ; OCIE1A: Interrupt bei Timer Compare
           out     TIMSK, temp1

   ldi timer1_zaehler, 0

;Timer1 Einstelungen -----------------------------------------------------

Wie man sehen kann beschreibe ich zweimal das register "TIMSK".
Einmal im Teil des Timer0 undzwar setze ich es dort gleich"0b00000001".
Dies aktiviert den Timer Overflow von Timer0.

Dann bearbeite ich dies nochmal im Teil von Timer1.
Da aktiviere ich den CTC Modus. Dadurch wird das erste bzw. "nullte" Bit aber wieder deaktiviert. Wodurch der Timer0 nicht mehr auf einen Overflow reagiert. ICh hoffe ich hab es einigermaßen richtig erklärt Cheesy
Aufjedenfall war die Lösung halt das ich das Register "TIMSK" in einem durchlauf bearbeite.
Nun funktioniert alles!
Danke für die vielen Tips.
Als nächstes werde ich nun die Relais Platine zu Ende löten. Das ganze in das leere CD-ROM Laufwerksgehäuse einbauen und dann bekommt ihr ein Paar fotos. Ach so und parrallel werde ich mich daran machen Die Steuerungssoftware für den PC zu schreiben. Habt ihr(bzw. du PoWl) da auch Ahnung von? Sonst lass ich das Fragen stellen hier direkt! Cheesy
Aufjedenfall danke für die vielen Tips! Ohne eure Hilfe hätte ich das ncith hinbekommen!

* Relaiskarte.gif (13.02 KB - runtergeladen 2 Mal.)
« Letzte Änderung: November 28, 2007, 18:03:08 von Fabeulous » Gespeichert
Reisi
Lötkolbenfreak

*

Karma: +2/-0
Offline Offline
Beiträge: 190



Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #192 am: November 28, 2007, 20:31:40 »

Gleichzeitig befindet sich das Hauptprogramm in einer Zählschleife. Diese wird erst verlassen wenn das register "timer1_zaehler" den Wert 25 hat.
Huh Anscheinend hast du den eigentlichen Vorteil von Interrupts noch nicht begriffen. Normalerweise setzt man die ein, damit das Hauptprogramm eben nicht in einer Schleife hängt. So nutzt du den eigentlichen Vorteil der Interruptmethode gar nicht aus.

Unabhängig davon, warum hast du in den Timer ISRs noch zusätzliche Zähler drinn? Es bietet sich doch an, die Timer gleich entsprechend zu initialisieren. Die werden doch eh nur für diese eine Funktion genutzt.
Gespeichert
Fabeulous
Gast


E-Mail
Re: Taster als Schalter via AVR
« Antwort #193 am: November 28, 2007, 22:58:43 »

Gleichzeitig befindet sich das Hauptprogramm in einer Zählschleife. Diese wird erst verlassen wenn das register "timer1_zaehler" den Wert 25 hat.
Huh Anscheinend hast du den eigentlichen Vorteil von Interrupts noch nicht begriffen. Normalerweise setzt man die ein, damit das Hauptprogramm eben nicht in einer Schleife hängt. So nutzt du den eigentlichen Vorteil der Interruptmethode gar nicht aus.

Unabhängig davon, warum hast du in den Timer ISRs noch zusätzliche Zähler drinn? Es bietet sich doch an, die Timer gleich entsprechend zu initialisieren. Die werden doch eh nur für diese eine Funktion genutzt.

Aber gerade das ist doch der Sinn einer Warteschleife oder? Also zumindest brauchte ich jetzte eine Möglichkeit den Ablauf des Hauptprogramms zu verzögern. Und dies habe ich nun so realisiert.
Die anderen beiden Interrupts(UART Empfang und timer0 Overflow) habe ich ja so "Vorteilhaft" benutzt.

Diese zusätzlichen Zähler in den Timer Interrupts habe ich weil der Zahlenraum des normalen Timers nicht ausreicht bzw. alleine nicht genug Zeit verbrauchte. Ich habe den 16 Bit nun im CTC Modus so eingestellt das er bei 40000 einen Interrupt auslöst. Ich bräuchte aber eigentlich einen Timer der bei einem Stand von 100000 einen Interrupt auslöst. Da ich aber maximal etwas von 69000 einstellen kann muss ich das ganze mit einem zweiten Zaehler realisieren. Timer und Zaehler können dann zusammen bei einem Wert von 100000 Taktzyklen einen "Interrupt" auslösen.(40000*25=100000)
Ich hoffe ich habe das einigermaßen verständlich beschrieben Tongue

EDIT:
So ich habe gerade eben noch ein gimik hinzugefügt. Der Letzte Stand der LED's wird nun im EEPROM abgespeichert. Das heist auch anch einem NEu Start des µC's ist der aktuelle Stand noch da.
« Letzte Änderung: November 29, 2007, 00:18:19 von Fabeulous » Gespeichert
OlafSt
Global Moderator

*

Karma: +13/-0
Offline Offline
Geschlecht: Männlich
Beiträge: 2138


Master of STLCD and LISA III


Profil anzeigen
Re: Taster als Schalter via AVR
« Antwort #194 am: November 29, 2007, 08:07:01 »

Erstmal danke für das reparierte Layout  bestens Crawler@edit: Gern geschehen!  Wink

BTT: Warum so umständlich ?

- Timer so programmieren, das er nach 10.000 einen Interrupt auslöst
- in der ISR einen Zähler hochzählen (+1)
- Hat der Zähler "10" erreicht, sind 100.000 Ticks vergangen und du rufst einfach deine Routine auf (Ja, man darf aus einer ISR andere Routinen aufrufen Wink). Zähler zurückstellen nicht vergessen !

Das ist viel simpler als die genickbrechenden Verrenkungen, die du da machst Wink
« Letzte Änderung: November 29, 2007, 09:20:28 von Crawler » Gespeichert

Erstens: Lies was da steht. Zweitens: Denk drüber nach. Drittens: Dann erst fragen
Seiten: 1 ... 8 9 10 11 12 [13] 14 15 16 17 nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Einloggen mit Benutzername, Passwort und Sitzungslänge      

Powered by MySQL Powered by PHP
eXTReMe Tracker
Seite erstellt in 0.023 Sekunden mit 17 Zugriffen.
© 2001-2022 MODDING-FAQ FORUM | SMF
Alle Rechte vorbehalten.
Prüfe XHTML 1.0! Prüfe CSS!