Hallo zusammen, ich möchte auf einem ATmega32U2 den Compare A Interrupt von Timer1 verwenden. Dabei soll die Zeit zwischen zwei Compare Interrupt's immer konstant sein und der Timer darf nicht auf 0 zurück gesetzt werden. Nun meine Idee war einfach immer das Compare Register um den Wert zu erhöhe der mir die entsprechende Zeitdifferenz ergibt. Leider funktioniert es in der Praxis nicht ganz so gut wie in der Theorie, kann mir jemand helfen meinen Fehler zu finden oder gibt es vielleicht sogar eine "schönere" Lösung?
1 | //16Bit verwaltung
|
2 | #define low_byte(x) (x & 0xff)
|
3 | #define high_byte(x) ((x >> 8) & 0xff)
|
4 | |
5 | void init_USBTask (void) { |
6 | OCR0A = 0b00000000; //Kein Output Compare |
7 | |
8 | switch (Timer1_Prescaler) { //Frequenzteiler auswählen |
9 | case 0: TCCR1B = 0; |
10 | case 1: TCCR1B = 1; |
11 | case 8: TCCR1B = 2; |
12 | case 64: TCCR1B = 3; |
13 | case 256: TCCR1B = 4; |
14 | case 1024: TCCR1B = 5; |
15 | }
|
16 | |
17 | OCR1AL = low_byte (USB_USBTask_Frequenz); |
18 | OCR1AH = high_byte (USB_USBTask_Frequenz); |
19 | set_bit (TIMSK1,1); //Aktiviert Compare A |
20 | }
|
21 | |
22 | ISR (TIMER1_COMPA_vect) { |
23 | USB_USBTask_interrupt (); |
24 | }
|
25 | |
26 | void USB_USBTask_interrupt (void) { |
27 | USB_USBTask(); |
28 | uint16_t compare_a = OCR1AH; |
29 | compare_a << 8; |
30 | compare_a &= OCR1AL; |
31 | |
32 | uint16_t rest = 65536 - compare_a; |
33 | |
34 | if (rest < USB_USBTask_Frequenz) compare_a = USB_USBTask_Frequenz - rest; |
35 | else compare_a += USB_USBTask_Frequenz; |
36 | |
37 | OCR1AL = low_byte (compare_a); |
38 | OCR1AH = high_byte (compare_a); |
39 | }
|