Forum: Mikrocontroller und Digitale Elektronik Atmel, Timer funktioniert nur mit Werten gößer als 0x0A


von Hans W. (hans_wurst)


Lesenswert?

Hallo,

ich verwende einen ATmega3290p bei 8 MHz. Durch nachfolgende 
Init-Funktion, stelle ich den Timer0 so ein, dass ich einen CTC-Timer 
habe. Den Systemtakt teile ich dafür durch 8.

Lasse ich den Timer nun auf Werte zwischen 0xFF und 0x0A zählen, toggelt 
mein Ausgang beim Eintritt des Interrupts. Ist der Wert jedoch kleiner 
als 0x0A, ist die Zeit bis zum Toggeln genauso kurz, wie wenn ich 0x0A 
in das Compare-Register schreibe jedoch den Systemtakt ungeteilt lasse. 
Ich hoffe ihr könnt mir sagen was ich falsch mache.
1
void init_timer(void)
2
{
3
    // Bit 6, 3 - WGM01:0: Waveform Generation Mode
4
    TCCR0A |=  (1<<WGM01);      // Clear Timer on Compare Match (CTC); Top=OCR0A;
5
    TCCR0A &= ~(1<<WGM00);      // Clear Timer on Compare Match (CTC); Top=OCR0A;
6
7
    // Bit 5:4 - COM0A1:0: Compare Match Output Mode
8
    TCCR0A &= ~(1<<COM0A1);     // Toggle OC0A on compare match
9
    TCCR0A |=  (1<<COM0A0);     // Toggle OC0A on compare match
10
11
    //Set Bit4 of PortB as output
12
    DDRB |= 0x10;
13
14
    // TIMSK0 - Timer/Counter 0 Interrupt Mask Register
15
    // Bit 1 - OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
16
    TIMSK0 |= (1<<OCIE0A);      // set interrupt enable
17
18
    TCNT0 = 0x00;
19
}
20
void start(void)
21
{
22
    OCR0A = 0x0A; // kleinst möglicher Wert
23
    TCCR0A |= 2;  // systemtakt/8
24
}
25
ISR(TIMER0_COMP_vect)
26
{   // Ausgang wird getoggelt
27
}

von Hans W. (hans_wurst)


Lesenswert?

Ich vermute gerade, mein Problem könnte vielleicht daran liegen, dass 
ich das mit dem Teiler des Systemtaktes falsch verstanden habe.

Ich bin davon ausgegangen, dass ich mit dem clk/8-Takt die Werte von 
0xFF (lange Zeit) bis 0x01 (kurze Zeit) einstellen kann. Und wenn ich 
den Teiler einfach auf eins setze, meine Timer-Zeit linear kürzer wird.

Kann es sein, dass ich hier falsch liege? Wenn ja, dann wäre es 
vielleicht auch logisch, dass der uC nicht das tut was ich möchte, da er 
in der Zeit nicht mehr schafft die Interrupts zu bearbeiten.

von Hans W. (hans_wurst)


Lesenswert?

Hat sich erledigt. Habe mir mal die Zeiten ausgerechnet und gegenüber 
gestellt. Bei Werten kleiner 0x0A schafft es der uC nicht mehr die 
Interrupts zu bearbeiten.

von Hannes Lux (Gast)


Lesenswert?

> Habe mir mal die Zeiten ausgerechnet und gegenüber gestellt.

Warum erst hinterher? Wenn man mit Timern arbeitet, rechnet man sich 
bereits im Vorfeld die nutzbaren Vorteiler und Arbeitsbereiche aus.

> ISR(TIMER0_COMP_vect)
> {   // Ausgang wird getoggelt
> }

Deine ISR enthält keinen Code. Wenn die ISR keine Arbeit erledigen muss, 
dann wird sie auch nicht gebraucht und kann entfallen. Das Toggeln des 
OC-Pins erfolgt ja durch Hardware (eingeschaltet per COM- und WGM-Bits) 
im Hintergund, also ohne ohne zyklisches Abarbeiten von Code durch den 
Prozessor.

Und mal so nebenbei:

> ...Bei Werten kleiner 0x0A schafft es der uC nicht ...

Warum betrachtest Du Zahlen, die Zählerstände darstellen (und in 1 Byte 
passen), nicht einfach dezimal? Ist doch viel übersichtlicher. Oder 
denkst Du hexadezimal?

Also ich sehe es so:
Zahlen, Zählerstände, Schleifenzähler, betrachtet man am besten dezimal.
Speicher-Adressen betrachtet man meist Hexadezimal.
ASCII-Werte schreibet man (wenn möglich) als lesbares Zeichen.
Bitmuster gibt man möglichst mit Bitnamen an, zumindest aber binär oder 
hex.

Nur so als Anregung.

...

von P. S. (Gast)


Lesenswert?

Hannes Lux wrote:

>> Habe mir mal die Zeiten ausgerechnet und gegenüber gestellt.
> Warum erst hinterher? Wenn man mit Timern arbeitet, rechnet man sich
> bereits im Vorfeld die nutzbaren Vorteiler und Arbeitsbereiche aus.

Er hat seinen Fehler selbst gefunden, er hat daraus gelernt und er hat 
Feedback gegeben, wo er seine Frage gestellt hat - wo siehst du jetzt 
einen Grund, nachtreten zu muessen?

von Hannes Lux (Gast)


Lesenswert?

> einen Grund, nachtreten zu muessen?

Sorry, das sehe ich nicht als Nachtreten, sondern als gut gemeinten 
Hinweis für die Zukunft. Außerdem enthält mein Text auch noch andere 
Hinweise, die vermutlich hilfreich sein könnten.

...

von Benedikt K. (benedikt)


Lesenswert?

Sehe ich auch so.
Keine Ahnung was Hans Wurst als Fehler gefunden hat, aber die Ursache 
ist es nicht, denn wie Hannes Lux schrieb: Das Pin toggeln geschieht in 
Hardware. Selbst wenn sich der µC komplett aufhängt toggelt der Pin noch 
weiter.
Davon abgesehen passen die Einstellungen aber. Es muss also an etwas 
anderes liegen.
0x0A und Prescaler 8 ergibt einen Teilerfaktor von 88. Das sollte der µC 
locker schaffen (ganz grob müsste ein leerer Interrupt etwa 10-20 Takte 
brauchen)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.