Hallo, ich hab ein kleines Problem mit dem Conuter eines ATmega 168A-PU. Die Clocksource des Timer0 wurde auf Extern und fallende Flanke eingestellt. Damit sollen die von einem Encoder produzierten Flanken detektiert werden. Timer2 stellt den Zeitbezug her um auf eine Drehzahl schließen zu können. Prinziepiell funktioniert das auch. Allerdings nur solange der Motor nicht mit "Vollgas" fährt. Sobal die Encoderpulsfrequenz einen Grenzwert (ca 41kHz) überschreitet verweigert der Counter vollständig seinen Dienst. Die über die Serielleschnittstelle eingelesenen Variablen bleiben 0. Unterhalb der genannten Frequenz liefert der Counter zwar Werte, allerdings sehen diese eher nach einer Alias-Frequenz aus. Das heisst bei geringerer Geschwindigkeit zählt der Counter mehr Pulse als bei höheren. Soweit ich das im Datenblatt nachlesen konnte sollte die Grenzfrequenz bei dem 1/2,5 fachen des CPU-Taktes liegen. Da die CPU über einen externen Quarz mit 20MHz läuft, kann ich da kein Problem erkennen. Und auch bei 8MHz wären 42kHz auch noch unter dem geforderten Wert. Deshalb verstehe ich nicht wirklich wo das Problem liegt. Hat jemand dazu eine Idee? Quelltext(Auszug):
1 | #define EXTCLK_FALING_EDGE 0x06
|
2 | #define TIMER0_OVINT_ENABLED TIMSK0 |= (1<<TOIE0)
|
3 | #define TIMER2_OVINT_ENABLED TIMSK2 |= (1<<TOIE2)
|
4 | #define START_TIMER0 TCCR0B = EXTCLK_FALING_EDGE
|
5 | #define START_TIMER2 TCCR2B = 0x07
|
6 | |
7 | int main(void) |
8 | {
|
9 | setup(); //ruft unter Anderem timer() und counter() auf. |
10 | OVERFLOW=0; |
11 | OVERFLOW2=0; |
12 | |
13 | while(1) |
14 | {
|
15 | sei(); |
16 | }
|
17 | }
|
18 | |
19 | void timer() |
20 | {
|
21 | START_TIMER2; |
22 | TIMER2_OVINT_ENABLED; |
23 | }
|
24 | |
25 | void counter() |
26 | {
|
27 | START_TIMER0; |
28 | TIMER0_OVINT_ENABLED; |
29 | }
|
30 | |
31 | |
32 | ISR(TIMER0_OVF_vect) |
33 | {
|
34 | cli(); |
35 | overflow_flag++; |
36 | if (overflow_flag==255) |
37 | {
|
38 | overflow2_flag=1; |
39 | overflow_flag=0; |
40 | }
|
41 | }
|
42 | |
43 | ISR(TIMER2_OVF_vect) |
44 | {
|
45 | cli(); |
46 | TICK_COUNT=TCNT0; |
47 | tick_sum=tick_sum+TICK_COUNT; |
48 | OVERFLOW=overflow_flag; |
49 | OVERFLOW2=overflow2_flag; |
50 | overflow_flag=0; |
51 | overflow2_flag=0; |
52 | }
|
Der gesamte Quelltext ist etwas zu umfangreich um ihn hier einzustellen. (380 Zeilen + Header) Daher nur ein Auszug. Um feinheiten, wie exakte Werte durch stoppen und wieder starten der Timer und den genauen Prescaler des Timer2 habe ich mich noch nicht gekümmert. Ich wollte erst einmal einen prinziepiell funktionierenden Code.