Hallo,
benutze seit kurzem einen AT90CAN128 und habe davor einen ATmega128
verwendet. Mir ist aufgefallen dass es beim Timer2 kleine unterschiede
gibt, und zwar werden beim AT90CAN128 bei allen Registern des Timers 2
ein A hinten angehängt. (Bsp.: TCCR2A) Es ist zwar auch in den
Datenblättern so, kann mir jemand den Grund sagen.
Und jetzt zu meinem eigentlichen Problem, ich habe folgenden Code:
1 | #include <stdint.h>
|
2 | #include <stdlib.h>
|
3 | #include <stdio.h>
|
4 |
|
5 | #include <avr/io.h>
|
6 | #include <avr/interrupt.h>
|
7 | #include <avr/eeprom.h>
|
8 |
|
9 | static uint32_t eeTimer3Frequency EEMEM = 230; // in Hz
|
10 | static uint8_t eeTimer3DutyCycleA EEMEM = 33; // in %
|
11 | static uint8_t eeTimer3ComOutMode EEMEM = 0x80;
|
12 |
|
13 |
|
14 | void pwm_init_timer3(void)
|
15 | {
|
16 | uint32_t temp_clk_div = 0;
|
17 | uint16_t temp_ICR3 = 0;
|
18 | uint8_t temp_TCCR3A = 0;
|
19 | uint8_t temp_TCCR3B = 0;
|
20 |
|
21 | uint32_t Timer3Frequency;
|
22 | uint8_t Timer3DutyCycleA;
|
23 |
|
24 | // Stop & reset timer
|
25 | TCCR3B = 0;
|
26 | TCNT3 = 0;
|
27 |
|
28 | // read from EEPROM
|
29 | eeprom_read_block(&Timer3Frequency ,&eeTimer3Frequency,4);
|
30 | Timer3DutyCycleA = eeprom_read_byte(&eeTimer3DutyCycleA);
|
31 | temp_TCCR3A = eeprom_read_byte(&eeTimer3ComOutMode);
|
32 |
|
33 | if(Timer3Frequency > F_CPU)
|
34 | {
|
35 | // Not possible
|
36 | return;
|
37 | }
|
38 | else
|
39 | {
|
40 | temp_clk_div = F_CPU / Timer3Frequency;
|
41 |
|
42 | if (temp_clk_div < 0xFFFF)
|
43 | {
|
44 | temp_ICR3 = temp_clk_div;
|
45 | temp_TCCR3B |= ( _BV(CS30) );
|
46 | }
|
47 | else if (temp_clk_div < 0x7FFFF)
|
48 | {
|
49 | temp_ICR3 = temp_clk_div / 8;
|
50 | temp_TCCR3B |= ( _BV(CS31) );
|
51 | }
|
52 | else if (temp_clk_div < 0x3FFFFF)
|
53 | {
|
54 | temp_ICR3 = temp_clk_div / 64;
|
55 | temp_TCCR3B |= ( _BV(CS31) | _BV(CS30) );
|
56 | }
|
57 | else if (temp_clk_div < 0xFFFFFF)
|
58 | {
|
59 | temp_ICR3 = temp_clk_div / 256;
|
60 | temp_TCCR3B |= ( _BV(CS32) );
|
61 | }
|
62 | else if (temp_clk_div < 0x3FFFFFF)
|
63 | {
|
64 | temp_ICR3 = temp_clk_div / 1024;
|
65 | temp_TCCR3B |= ( _BV(CS32) | _BV(CS30) );
|
66 | }
|
67 | else
|
68 | {
|
69 | return;
|
70 | }
|
71 | }
|
72 |
|
73 | temp_TCCR3A |= ( _BV(WGM31) );
|
74 | temp_TCCR3B |= ( _BV(WGM33) | _BV(WGM32) );
|
75 |
|
76 | OCR3A = (uint16_t)(temp_ICR3 * Timer3DutyCycleA / 100);
|
77 | ICR3 = temp_ICR3;
|
78 | TCCR3B = temp_TCCR3B;
|
79 | TCCR3A = temp_TCCR3A;
|
80 | }
|
Ich habe dass ganze im Simulator laufen lassen und festgestellt, dass
OCR3AH nie beschrieben wird.
Wo liegt ein Fehler, ich vermute in der Berechnung des Registers.
Ich setze WinAVR 20060421 ein.
Gilles