Hallo.
Ich weiß nicht woran es liegt, weil sich für mich an zu vielen Stellen
zu viele Fragen aufwerfen, aber vielleicht kann jemand mit mehr Ahnung
ja eher etwas damit anfangen.
_Ziel:_ 16Bit Timer 3 (4 oder 5) mittels CTC Mode 4 (oder 12) als
Interrupt mit modifizierter Auflösung nutzen.
_Idee:_ Da die Timer/Counter 4 und 5 keine Ausgangspins haben, würden
sie sich für interne Interrupts mit selbstgemachter Auflösung eignen
(Overflow Interrupt).
_Problem:_ Zitat Datenblatt ATmega1281, S.136: "Timer/Counter4 and
Timer/Counter5 only have full functionality in the ATmega640/1280/2560.
Input capture and output compare are not available in the
ATmega1281/2561..."
Mir ist durchaus bewusst, dass ich beim 1281'er für T/C4&5 für Mode 12
nichts erwarten darf, weils ja im Datenblat steht, aber schließt das
Zitat den Modus 4 (CTC mit OCRnA als TOP) für T/C 4&5 auch aus?
_Die Probleme betrifft in der Form aber vor allem AUCH Timer 3, und da
fängts für mich an._
/Ich benutzte Timer0 im Fast-PWM Modus und Pin 17 (PB7) als Ausgang für
die Anzeige über eine 2 farbige LED (OCR0A=0 -> grün, OCR0A=255 -> rot).
Wenn ich OCR0A mit diesen Werten beschreibe leuchtet es auch
entsprechend. Der Ausgang wird zusätzlich mit Oszi beobachtet.. ich kann
also sehen wie die PWM aussieht.
Die PowerReductionRegsiter-Bits für die Timer sind alle auf 0 -> Timer
also aktiv./
Problem 1: Modus 4 (CTC mit OCR3A) läuft nur mit "OCR3A = 0xFFFF",
sämtliche anderen Werte werden ignoriert.. das dürfte schon mal nicht
passieren.
1 | #include <inttypes.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 | int main (void)
|
6 | {
|
7 | PORTB |= (0<<PB7); // hier läuft der LED-PWM drauf
|
8 | DDRB |= (1<<DDB7);
|
9 | // Timer0 (8Bit): FastPWM-Mode(3), TOP = 0xFF, OCR0A als CompareMatch für PWM, Prescaler 1
|
10 | TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(1<<WGM00);
|
11 | TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
|
12 |
|
13 | sei(); // Interrupts global ein
|
14 | PRR1 |= (0<<PRTIM3); // Timer Modul ON
|
15 | TIMSK3 |= (1<<TOIE3); // Overflow Interrupt ein
|
16 | TCCR3B |= (0<<WGM33)|(1<<WGM32)|(1<<CS31); // Mode 4, Prescaler 1/8
|
17 |
|
18 | OCR3A = 0xFFFF; // OutputCompareRegister Vergleichswert setzen, andere Werte zB. 0xFFFE gehen nicht!
|
19 |
|
20 | TCNT3 = 0x0000; // Timer/Counter4 Zählregister Reset
|
21 | OCR0A = 10; // Alive-Signal: grün
|
22 | while (1) // Loop forever
|
23 | { }
|
24 | return (0);
|
25 | }
|
26 |
|
27 | ISR (TIMER3_OVF_vect)
|
28 | {
|
29 | OCR0A = 245; // Alive-Signal: rot
|
30 | }
|
Ich hab auch schon versucht OCR3A jeweils nur 8 Bit weise zu schreiben..
Erst OCR3AH mit 0xFF und dann OCR3AL mit 0xFF -> funktioniert, der
Interrupt kommt.
Nimmt man stattdessen andere Werte geht es nicht mehr, der Interrupt
bleibt aus.
Das gleiche gilt für Timer 4 und 5.
Problem 2: Modus 12 (CTC mit ICR) ISR-Funktion läuft nur mit
"_VECTOR(41)" anstatt "TIMER4_CAPT_vect".. wäre mit dem Zitat erklärbar.
Insofern überfahre ich sicher mit meinem _VECTOR(41) irgendwelche
Einstellungen in den Makros. Allerdings wär das nur die Notlösung, weil
ja Overflow-Interrupt nicht geht.. nur deshab führe ichs überhaupt auf.
1 | #include <inttypes.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 | int main (void)
|
6 | {
|
7 | PORTB |= (0<<PB7); // hier läuft der LED-PWM drauf
|
8 | DDRB |= (1<<DDB7);
|
9 | // Timer0 (8Bit): FastPWM-Mode(3), TOP = 0xFF, OCR0A als CompareMatch für PWM, Prescaler 1
|
10 | TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(1<<WGM00);
|
11 | TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
|
12 |
|
13 | sei(); // Interrupts global ein
|
14 | PRR1 |= (0<<PRTIM4); // Timer Modul ON
|
15 | TIMSK4 |= (1<<ICIE4); // InputCapture Interrupt ON
|
16 | TCCR4B |= (1<<WGM43)|(1<<WGM42)|(1<<CS41); // Mode 12, Prescaler 1/8
|
17 | ICR4H = 0xAF; // InputCaptureRegister Vergleichswert setzen
|
18 | ICR4L = 0x00;
|
19 | TCNT4 = 0x0000; // Timer/Counter4 Zählregister Reset
|
20 | OCR0A = 10; // Alive-Signal: grün
|
21 | while (1) // Loop forever
|
22 | { }
|
23 | return (0);
|
24 | }
|
25 |
|
26 | ISR (_VECTOR(41)) // wenn da "TIMER4_CAPT_vect" drin steht, gehts nicht..
|
27 | {
|
28 | OCR0A = 245; // Alive-Signal: rot
|
29 | }
|
Mit anderen Worten, schön das es mit _VECTOR(41) geht, aber darauf
verlassen sollte ich mich nicht, oder?
Mit Timer 3 funktioniert Mode 12 (CTC mit ICR) ohne diesen Trick, also
direkt mit "TIMER3_CAPT_vect".
Danke für eure Hilfe
Joan
[Edit, Overflow statt Output Compare solls ja sein]