Hallo, bin gerade dabei den Timer1 im CTC Modus zu betreiben. Also Vergleichswert ins Register schreiben. Irgendwie läuft der Timer viel zu schnell ab. Woran kann das liegen? Ich programmiere mit mikroC pro for AVR also keine includes. Der Timer soll den Pin B0 5760 mal pro Sekunde schalten also "Interruptfrequenz" von 11520Hz (wegen toggeln) Hier der Quelltext: int Timer1counter; void Timer1COMPA_ISR() org IVT_ADDR_TIMER1_COMPA { PORTB.B0 = ~PORTB.B0; //Nur zum Überprüfen Timer1counter++; if(Timer1counter>11000){ PORTB.B1 = ~PORTB.B1; Timer1counter=0; } } void main() { DDRB = 0xFF; // set PORTB as output PORTB = 0; // clear PORTB TIMSK1 = 0b00010010; //compare A Register Interrupt on y=1736; // write Compare Value in register OCR1AL = y; OCR1AH = (y>>8); //MCU Clock Frequency 20 MHz TCCR1A = 0b00000000; TCCR1B = 0b00001001; // 0b00000001 starte Timer1 mit Prescaler 1 s.D.-sheet 160 SREG_I_bit = 1; // Interrupt enable while (1) // Endless loop, port is changed inside Interrupt Service Routine (ISR) ; } Was könnte hier falsch sein? Danke für Eure Hilfe. Grüße Roland
der code sieht ein wenig verwirrend aus^^ btw ist das wirklich ein Atmel die register würden eher zum ARM passen. wäre gut wenn du sagst wenn du wichtige externe schaltteile wie zb einen oszillator verwendet hat. beim atmel musst du auch einen prescaler einstellen da er ansonsten mit der normalen cpu ferquenz läuft.....
1 | OCR1AL = y; |
2 | OCR1AH = (y>>8); |
Falsche Reihenfolge. PS: Und warum gibst du 2 Interrupts frei, wenn du nur eine ISR hast?
Jupp, ist ein ATmega 1284PU und läuft momentan mit internem Oszillator mit 20MHz. Die Register sollten schon passen. Hier das Datenblatt dazu: http://www.atmel.com/Images/doc8272.pdf 20MHz / 65536 = 305 Interrupts pro Sek. dann noch Prescaler von 8 -> 38 Interrupt pro Sek. wegen toggeln -> 38/2 = 19 mal blinkt LED. Also habe jetzt den ganzen Tag herumprobiert, aber irgendwie solls nicht sein xD
@Stefan:
Danke, Ich glaub das wars!
Nur zum Verständnis. Wieso zuerst das H-Register
H L
Y= 00000000 00000000
OCR1AL = y /// werden hier nicht die letzten 8bit in das Register
geschrieben
Dann 8mal shift nach rechts.
H L
y= xxxxxxxx 00000000
Jetzt ist das eigtl. Highbyte das Lowbyte also:
OCR1AH = (y>>8);
2 Interrupts? Gute Frage, zu oft rumprobiert? ;-)
Habs geändert:
TIMSK1 = 0b00000010; //compare A Register Interrupt on
stimmts so?
Danke für Eure Hilfe!
Hi >Jupp, ist ein ATmega 1284PU und läuft momentan mit internem Oszillator >mit 20MHz. Halte ich für ein Gerücht. MfG Spess
Roland K. schrieb: > Nur zum Verständnis. Wieso zuerst das H-Register > H L > Y= 00000000 00000000 > > OCR1AL = y /// werden hier nicht die letzten 8bit in das Register > geschrieben > > Dann 8mal shift nach rechts. > H L > y= xxxxxxxx 00000000 > > > Jetzt ist das eigtl. Highbyte das Lowbyte also: > > OCR1AH = (y>>8); Es geht nicht um die Aufteilung des 16-Bit Wertes in zwei 8-Bit Werte, es geht darum, in welcher Reihenfolge die beiden Register zu beschreiben sind. Ließ das im Datenblatt nach.
>Es geht nicht um die Aufteilung des 16-Bit Wertes in zwei 8-Bit Werte, >es geht darum, in welcher Reihenfolge die beiden Register zu beschreiben >sind. Ließ das im Datenblatt nach. OCR1A = y; Das macht der Compiler schon richtig.
@Stefan: Danke Dir! War wohl die Verlinkung, der ich nicht gefolgt bin. Für alle die den gleichen Fehler machen. Hier der Text aus dem Datenblatt: To do a 16-bit write, the high byte must be written before the low byte. For a 16-bit read, the low byte must be read before the high byte. @holger: Danke! Ja, sollte. Aber leider nicht bei MikroC :-/
Hi
>Ich lasse mich gerne belehren!
Der interne RC-Oszillator läuft normalerweise mit 8 MHz. Mit dem
OSCCAL-Register lässt er sich auf maximal 15MHz trimmen. Kannst ja
selbst im Datenblatt nachsehen.
MfG Spess
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.