Ich versuche gerade dem Timer1 eine PWM im Mode 15 zu entlocken, aber so
langsam glaube ich, dass mein Controller spinnt.
1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | int main(void)
|
5 | {
|
6 | cli();
|
7 |
|
8 | DDRC = (1<<PC1); // OC1B auf Ausgang
|
9 |
|
10 | TCCR1B = 0x00; // stop
|
11 | TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10); // set OC1B on compare match
|
12 | TCCR1C = 0x00;
|
13 | OCR1A = 0x420;
|
14 | OCR1B = 0x10;
|
15 | TCCR1B = (1<<CS11) | (1<<WGM12) | (1<<WGM13); // mode = 15, fast-pwm, prescaler = 8 -> 2 MHz -> 500 ns / Tick
|
16 |
|
17 | sei();
|
18 |
|
19 | while(1)
|
20 | {
|
21 | //TODO:: Please write your application code
|
22 | }
|
23 | }
|
Wenn ich das nachrechne sollte ins Register TCCR1A der Wert 0x23
geschrieben werden und ins Register TCCR1B der Wert 0x1A.
Dem .lss File zu Folge ist das auch so.
Mein Controller läuft mit 16MHz Quarz, die Fuse-Bits sind richtig.
Das ist jetzt auch nur der auf das Problem reduzierte Ausschnitt, der
CAN lief ohne Probleme auf 500kBit.
Ich habe extra ein frisches Projekt aufgemacht.
Verschiedene Optimierungs-Stufen habe ich auch durch.
Wenn der Timer jetzt im Mode 15 wäre, dann müsste am Pin OC1B eine PWM
raus kommen mit:
0x420 = 1056 -> 1057 * 500ns = 528,5µs
0x10 = 16 -> 17 * 500ns = 8,5µs
Also etwa 1890 Hz und 1,5% Duty-Cycle.
Was ich allerdings messen kann sind 16,5µs Periode und 8,5µs Puls.
Mit OCR1A = 0x2ff erhalte ich 384,5µs Perioden-Dauer.
0x2ff = 767 -> 768 * 500ns = 384µs -> passt
Der Timer akzeptiert aus irgendeinem Grund nur Werte bis 0x3ff und hat
dann einen Überlauf.
Nur macht das überhaupt keinen Sinn, es gibt keinen Modus mit TOP =
OCR1A und TOP = 0x3ff.
Hier noch der relevante Ausschnitt aus der .lss Datei bei -Os:
1 | int main(void)
|
2 | {
|
3 | cli();
|
4 | 94: f8 94 cli
|
5 |
|
6 | DDRC = (1<<PC1); // OC1B auf Ausgang
|
7 | 96: 82 e0 ldi r24, 0x02 ; 2
|
8 | 98: 87 b9 out 0x07, r24 ; 7
|
9 |
|
10 | TCCR1B = 0x00; // stop
|
11 | 9a: 10 92 81 00 sts 0x0081, r1
|
12 | TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10); // set OC1B on compare match
|
13 | 9e: 83 e2 ldi r24, 0x23 ; 35
|
14 | a0: 80 93 80 00 sts 0x0080, r24
|
15 | TCCR1C = 0x00;
|
16 | a4: 10 92 82 00 sts 0x0082, r1
|
17 | OCR1A = 0x0420;
|
18 | a8: 80 e2 ldi r24, 0x20 ; 32
|
19 | aa: 94 e0 ldi r25, 0x04 ; 4
|
20 | ac: 90 93 89 00 sts 0x0089, r25
|
21 | b0: 80 93 88 00 sts 0x0088, r24
|
22 | OCR1B = 0x10;
|
23 | b4: 80 e1 ldi r24, 0x10 ; 16
|
24 | b6: 90 e0 ldi r25, 0x00 ; 0
|
25 | b8: 90 93 8b 00 sts 0x008B, r25
|
26 | bc: 80 93 8a 00 sts 0x008A, r24
|
27 | TCCR1B = (1<<CS11) | (1<<WGM12) | (1<<WGM13); // mode = 15, fast-pwm, prescaler = 8 -> 2 MHz -> 500 ns / Tick
|
28 | c0: 8a e1 ldi r24, 0x1A ; 26
|
29 | c2: 80 93 81 00 sts 0x0081, r24
|
30 |
|
31 | sei();
|
32 | c6: 78 94 sei
|
33 | c8: ff cf rjmp .-2 ; 0xc8 <main+0x34>
|
Sag mir doch mal bitte jemand, dass ich was falsch mache und was ich
falsch mache, ich würde den Controller gerne einsetzen.
Ach ja, eine zweite Platine aus einem anderen Projekt zeigt mit der
Test-Software das gleiche Verhalten.
Die Controller sind mit Date-Code 1330, das ist auf jeden Fall lange
nach der letzten Revision E des Datenblattes von 11/2012.
Errata sind keine für diesen Controller gelistet.