Autor
|
Thema: Taster als Schalter via AVR (Gelesen 152110 mal)
|
PoWl
Dremelfreund

Karma: +0/-0
Offline
Beiträge: 140
Atmel AVR Mikrocontroller
|
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
|
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 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 
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! dafür funktioniert der Empfang schonmal provisorisch...
|
|
« Letzte Änderung: November 22, 2007, 23:39:54 von Fabeulous »
|
Gespeichert
|
|
|
|
|
PoWl
Dremelfreund

Karma: +0/-0
Offline
Beiträge: 140
Atmel AVR Mikrocontroller
|
sicher dass mit den fusebits alles in ordnung is?
|
|
|
Gespeichert
|
|
|
|
Fabeulous
Gast
|
Hey ihr seit gut! 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... 
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:
.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
<\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...  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
|
Also ich habe heute nochmal geschaut. Selbst wenn ich den Code drastisch dezimiere bliebt das Problem. Ich hab nun den folgenden Code ausprobiert:
.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
Beiträge: 140
Atmel AVR Mikrocontroller
|
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
|
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! 
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! 
.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
|
So ich hab ein problem(mal wieder)  Google war auch nciht sehr aussagekräftig bzw. unverständlich. Ich habe hier sonne Interrupr Vektortabelle:
.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:
.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
Beiträge: 140
Atmel AVR Mikrocontroller
|
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
|
|
|
|
|
Fabeulous
Gast
|
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 
EDIT: Okay ich hab den Fehler gefunden. Es funktioniert. Undzwar folgendes: Meine "Timerdefintion":
;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  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!  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
|
|
|
|
|
Fabeulous
Gast
|
Gleichzeitig befindet sich das Hauptprogramm in einer Zählschleife. Diese wird erst verlassen wenn das register "timer1_zaehler" den Wert 25 hat.
 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 
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
|
|
|
|
|
|