Hi! Ich hab folgende Problem: Ich möchte das an Pin T0 (entspricht PD4) anliegende Rechtecksignal zählen. Nach 1000 Impulsen soll PortB "High" geschaltet werden. Dazu hab ich den Timer/Counter1 (16-bit) meines 2313 verwendet. Leider funktioniert es nicht, PortB bleibt immer auf "Low". Ich vermute das der Fehler irgendwo bei der Einrichtung des 16-bit Counters liegt. Hab aber bis jetzt noch nichts gefunden. Wäre total super wenn mir einer von euch weiterhelfen könnte. Schon mal im Voraus Danke! MfG Flo .include "2313def.inc" .def temp = r16 .equ start = 65536 - 1000 .equ highValue = high(start) .equ lowValue = low(start) rjmp reset ;Reset Handler reti ;IRQ0 Handler reti ;IRQ1 Handler reti ;Timer1 Capture Handler reti ;Timer1 Compare Handler rjmp counter1 ;Timer1 Overflow Handler reti ;Timer0 Overflow Handler reti ;SPI Transfer Complete Handler reti ;UART RX Complete Handler : RXCIE reti ;UDR Empty Handler reti ;UART TX Complete Handler reti ;ADC Conversion Complete Interrupt Handler reti ;EEPROM Ready Handler reti ;Analog Comparator Handler reset: ldi temp, low(RAMEND) ;set stackpointer out SPL, temp ldi temp, 0x00 out DDRD, temp ;PORTD input ldi temp, 0xFF out DDRB, temp ;PORTB output ldi temp, 1<<TOIE1 ;1000 0000 out TIMSK, temp ;timer1 interrupt on ldi temp, highValue ;Startwert des Counters Highbyte out TCNT1H, temp ldi temp, lowValue out TCNT1L, temp ;Startwert des Counters Lowbyte ldi temp, 0b00000111 out TCCR0, temp ;Counter +1 bei fallender Flanke an Pin T0 sei ;interrupts aktiv main: loop: rjmp loop ;-------------------------------------------------------------- counter1: ldi temp, 0xFF out PORTB, temp ldi r17, 0 ldi r18, 0 ldi r19, 35 delay: dec r17 brne delay dec r18 brne delay dec r19 brne delay ldi temp, 0x00 out PORTB, temp ldi temp, highValue ;Startwert des Counters Highbyte neu out TCNT1H, temp ldi temp, lowValue out TCNT1L, temp ;Startwert des Counters Lowbyte neu reti
Du wirfst Timer0 und Timer1 durcheinander. Wenn Du Dich für einen von beiden entscheidest, könnte es funktionieren ;-) Du zählst Impulse an T0, das ist der Eingang des Timer0. Allerdings die Interrupt-Routine ist für Timer1.
out TCCR0, temp ;Counter +1 bei fallender Flanke an Pin T0 da wird der Fehler liegen, sollte wohl heißen: out TCCR1B, temp Ansonsten kann ich nur sagen, das Programm ist ein Graus, verzeihen könnte ich dir das nur, wenn du Anfänger bist und dir noch keiner was beigebracht hat. folgende grobe Fehler: 1. das sreg sollte in einer ISR immer gesichert werden, das sollte in Fleisch und Blut übergehen 2. delays dieser Größenordnung haben in Unterruptprogrammen nichts zu suchen 3. Wenn du wirklich korrekt zählen willst, sollte das TCNT1-Register als erstes in der ISR nachgeladen werden. 4. Register sollten schon Namen bekommen, lange Fehlersuche ist sonst bei etwas komplexeren Programmen vorprogrammiert 5. wenn Register nicht ausdrücklich nur für eine ISR reserviert sind, auf dem Stack sichern. Programme wachsen im Lauf der Zeit, solche (erstmal funktionierenden) Nachlässigkeiten rächen sich später.
Guten Morgen! Danke für die Antworten! Werds dann gleich mal so ausprobieren. @ crazy horse ja ich bin leider noch ziemlicher Anfänger 1. das sreg sollte in einer ISR immer gesichert werden, das sollte in Fleisch und Blut übergehen ---> Danke für den Tip, wusste ich nicht 2. delays dieser Größenordnung haben in Unterruptprogrammen nichts zu suchen ---> Das war nur zum Test, sonst seh ich an meinen LED´s ja nichts 3. Wenn du wirklich korrekt zählen willst, sollte das TCNT1-Register als erstes in der ISR nachgeladen werden. ---> Nochmals Danke, ist ja eigentlich auch logisch 4. Register sollten schon Namen bekommen, lange Fehlersuche ist sonst bei etwas komplexeren Programmen vorprogrammiert ---> wie gesagt, die Delay war nur kurz zusammengeschustert 5. wenn Register nicht ausdrücklich nur für eine ISR reserviert sind, auf dem Stack sichern. Programme wachsen im Lauf der Zeit, solche (erstmal funktionierenden) Nachlässigkeiten rächen sich später. ---> Werds mir merken! MfG Flo
counter1: in sreg_bak, sreg push temp ldi temp, highValue ;Startwert des Counters Highbyte neu out TCNT1H, temp ldi temp, lowValue out TCNT1L, temp ;Startwert des Counters Lowbyte neu set ;T=1 bld flags, t1_ready pop temp out sreg, sreg_bak reti für das Register sreg_bak benutzt ich i.a. R1, wenn du keine Interrupts verschachtelst, kannst du das Register für verschiedene ISR benutzen .def sreg_bak R1 .def flags R2 .equ t1_ready=0 ;bit0 von R2 Im Hauptprogramm kannst du dann den Zustand von t1_rady abfragen, ist es gesetzt, werden die entsprechenden Aktionen ausgeführt (Port setzen, delay, Port rücksetzen. Es spielt zwar in deinem Programm keine Rolle, wird aber in komplexeren Programmen wichtig. also: - sreg sichern - alle benutzten Register sichern - ISR-Laufzeit kurz wie möglich halten Das ist natürlich kein unumstößliches Muss, wenn mans beherrscht oder besondere Umstände es erfordern, kann man davon abweichen, aber als Grundregel ist es nicht schlecht. Man kann das sreg auch auf dem Stack sichern: push temp in temp, sreg push temp . pop temp out sreg, temp pop temp reti Das empfiehlt sich bei verschachtelten ISRs (die fast immer vermeidbar sind)
Ich bin´s nochmal! Leider funktioniert das Programm immer noch nicht! Hab das "TCCRO, temp" gegen "TCCR1B, temp" ausgetauscht. Hat jemand vielleicht irgendein Beispielprogramm zum 16-Bit Timer / Counter? MfG Flo
Tja, und nun solltest du deine Impulse auch an den T1-EIngang legen (PD5), willst ja mit dem Timer1 zählen.
Ganz dumm bin ich auch nicht! :-) Das hab ich gemacht, funktioniert aber trotzdem nicht. :-(
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.