Forum: Compiler & IDEs Timer/Counter0 Overflow Interrupt kommt nicht


von Interessent (Gast)


Lesenswert?

Hallo allerseits! Ich habe eine Frage bzgl des Overflow Interrupts beim 
Timer/Counter0 des ATMega324A. Ich habe den unten aufgeführten Code. Ich 
hab diesen zunächst nur mit Hilfe des Datenblatts erstellt. Dieser 
scheint mir aber korrekt, da in den Threads, die ich hier im Forum 
gefunden hab, es genauso gemacht wurde. Nun mal zur genauen 
Problembeschreibung.

Ich will Timer0 im "Phase correct PWM mode" betreiben. Gemäß des 
Datenblatts wird jedes mal wenn der Timer wieder den BOTTOM-Wert 
erreicht hat das Timer/Counter Overflow Flag gesetzt, wodurch der 
Interrupt ausgelöst werden kann. In der ISR möchte ich dann den Wert des 
OCR von Timer2 ändern. Timer2 wird im CTC Mode betrieben.

Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den 
Initialisierten Werten. Folglich wird der Overflow Interrupt des Timer0 
nicht aufgerufen. Komischerweise funktioniert aber der Compare Match 
Interrupt, wenn ich ihn für Timer0 implementiere (also TIMSK0 = 
1<<OCIE0A mit entsprechender ISR). Im AVR-Studio habe ich auch darauf 
geachtet, dass das richtige Device ausgewählt ist.

Ich wäre euch sehr denkbar, wenn Ihr mich auf Fehler hinweisen könntet 
bzw wisst, woran es liegen könnte.
1
#ifndef F_CPU
2
#define F_CPU 16000000UL // or whatever may be your frequency
3
#endif
4
 
5
#include <asf.h>
6
#include <avr/io.h>          
7
#include <avr/interrupt.h>
8
#include <stdint.h>
9
10
int main (void) {            
11
  
12
  DDRA  = 0xFF;             
13
  PORTA = 0x00;
14
  DDRB = (1<<PB3) | (1<<PB4);
15
  DDRD = (1<<PD6) | (1<<PD7);
16
  DDRC = 0xFF;
17
  PORTC = 0x00;
18
  PORTC |= (1<<PC1);
19
20
21
        // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8
22
  TCCR0A =  (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<< COM0A0);
23
  TCCR0B = (0<<CS02) | (1<<CS01) | (0<<CS00);
24
25
  TCNT0 = 0;  //Anfangswert 0
26
27
  TIMSK0 |= 1<<TOIE0; // Enable Overflow Interrupt
28
  
29
  //Timer2: Enable CTC Mode, Toggle Compare Output at Compare Match, prescaler = 8
30
  TCCR2A =  (0<<WGM22) | (1<<WGM21) | (0<<WGM20) | (0<< COM2A1) | (1<< COM2A0);
31
  TCCR2B = (0<<CS22) | (1<<CS21) | (0<<CS20);  
32
  TIMSK2 = (1<<OCIE2A); //Enable Compare Match Interrupt
33
  
34
//Init OC-registers
35
  OCR0A = 155;
36
  OCR0B = 0;
37
  OCR2A = 79;
38
  OCR2B = 0;
39
  
40
  sei();
41
           
42
  while(1) 
43
        {  
44
45
  }                         
46
  
47
  return 0;                 
48
}
49
50
ISR (TIMER0_OVF_vect)
51
{
52
  OCR2A+=10;
53
  if(OCR2A >=254)
54
    OCR2A = 0;
55
}

von Mitlesa (Gast)


Lesenswert?

Du brauchst für jeden Timer Interrupt eine ISR.

Bei deinem Code sehe ich nur eine.

Du hast zwei Timer Interrupts scharf gemacht.

von Interessent (Gast)


Lesenswert?

Danke für den Hinweis. Jedoch bringt auch die Implementierung des 
zweiten Interrupts keine Besserung.

von Interessent (Gast)


Lesenswert?

Ich habe jetzt folgendes probiert:

Zur einfachen Signalgebung habe ich vor der while-Schleife einen Pin auf 
High gesetzt. In der Overflow ISR habe ich diesen dann auf Low gesetzt. 
Das funktionierte. Jedoch wird der Wert des OCR2A nicht geändert. Gibt 
es innerhalb des ATMega Zugriffsbeschränkungen, welche nicht erlauben, 
dass in einer ISR eines Timers Werte eines anderen Timers geändert 
werden können?

von Mitlesa (Gast)


Lesenswert?

Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.
Im Zweifelsfall auch ein Bild deines Aufbaus.

Kannst du denn mit Sicherheit erkennen dass dein Programm
überhaupt läuft, dass dein Prozessor einen (und den richtigen)
Clock hat?

Interessent schrieb:
> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den
> Initialisierten Werten.

Woran erkennst du das?

von Klaus (Gast)


Lesenswert?

Wenn ich mal raten soll, dann simuliert er den Code.

von Interessent (Gast)


Lesenswert?

Mitlesa schrieb:
> Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.
> Im Zweifelsfall auch ein Bild deines Aufbaus.
>
> Kannst du denn mit Sicherheit erkennen dass dein Programm
> überhaupt läuft, dass dein Prozessor einen (und den richtigen)
> Clock hat?
>
> Interessent schrieb:
>> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den
>> Initialisierten Werten.
>
> Woran erkennst du das?

Der Aufbau ist recht einfach. Ich habe die jeweiligen Pins, die ich 
benutze, an LEDs angeschlossen. Zusätzlich verwende ich ein Oszilloskop.

Dass die Werte sich nicht ändern erkenne ich am Oszilloskop. Wenn ich in 
den ISR nichts mache, bleiben die Werte ohnehin auf den initialisierten 
Werten, was ja auch so gewollt ist. Nehme ich nun in der ISR Änderungen 
der OCRx-Register vor, ändern sich die Werte weiterhin nicht. Das tritt 
allerdings nur bei der Overflow ISR auf! Ändere ich die Werte in der 
Compare Match ISR, treten die gewollten Änderungen auf.

von Klaus (Gast)


Lesenswert?

Falsch geraten.

von Mitlesa (Gast)


Lesenswert?

Interessent schrieb:
> Der Aufbau ist recht einfach.

Das ist ein aussagekräftiger Schaltplan.

Auch den Aufbau kann man gut erkennen.

Nach den Angaben müsste ja alles funktionieren.

von Interessent (Gast)


Angehängte Dateien:

Lesenswert?

Na denn. Hier der Schaltplan. Der wird allerdings nicht viel zum lösen 
des Problems beitragen.

von Paul B. (paul_baumann)


Lesenswert?

Interessent schrieb:
> Hier der Schaltplan.

Da fehlt ja die Betriebsspannung...
;-)
Schnell fort hier

MfG Paul

von Mitlesa (Gast)


Lesenswert?

Interessent schrieb:
> Der wird allerdings nicht viel zum lösen
> des Problems beitragen.

Ja, weil ein unvollständiger Schaltplan kein Schaltplan ist.

Und weil ein Aufbau so gestaltet sein kann dass eine
Schaltung nicht funktioniert.

Nach dem gezeigten Schaltplan kann jedenfalls nichts funktionieren.

Minimum ist eine ausreichende Stromversorgung, Abblock Kondensatoren,
und - nach deiner Frequenzinformation zu urteilen - eine Beschaltung
mit Quarz und Last-Kondensatoren.

Da man dir offensichtlich jeden Popel einzeln aus der Nase ziehen
muss bin ich draussen.

von Mitlesa (Gast)


Lesenswert?

Paul B. schrieb:
> Da fehlt ja die Betriebsspannung...

Scharf beobachtet, Paule.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Interessent schrieb:
> Jedoch wird der Wert des OCR2A nicht geändert.

Wodurch stellst du das fest?

Dein Timer 0 wird mit 2 MHz getaktet.  Als 8-Bit-Timer läuft er nach
128 µs über und ändert das OCR2A.  Das ist verdammt häufig.  Timer 2
läuft zu allem Überdruss mit konstant versetzter Phase zu Timer 0
über, denn er wird ebenfalls mit 2 MHz getaktet.  Damit ist bekommt er
möglicherweise sowieso nur jede zweite Änderung von OCR2A überhaupt
mit.  OCR2A wird in Zehnerschritten geändert, sodass es nach ca. 25
Änderungen wieder beim alten Wert ist, oder alle 3 Millisekunden.

Wenn du dir die LEDs mit dem Auge betrachtest, dürfte das Auge das
alles zu einer einzigen Helligkeit integrieren.  Ein Oszi wäre sicher
schnell genug, die sich ändernde Modulation zu erfassen …

Davon abgesehen:
1
  if(OCR2A >=254)
2
    OCR2A = 0;

Das wird kaum so funktionieren, wie du dir das vorstellst.  Du startest
mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei
249 bist.  Im nächsten Schritt werden wieder 10 addiert, dann bist du
bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253.  Diese
if-Bedingung greift nur sowas von selten, dass du sie genauso gut
komplett weglassen kannst.

: Bearbeitet durch Moderator
von Holger L. (max5v)


Lesenswert?

Interessent schrieb:
> // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8
>   TCCR0A =  (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<<
> COM0A0);

WGM02 befindet sich nicht in TCCR0A sondern in TCCR0B.
Bei dem zweiten Timer ist es genau so.

von Interessent (Gast)


Lesenswert?

Holger L. schrieb:
> Interessent schrieb:
>> // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8
>>   TCCR0A =  (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<<
>> COM0A0);
>
> WGM02 befindet sich nicht in TCCR0A sondern in TCCR0B.
> Bei dem zweiten Timer ist es genau so.

Vielen Dank für den Hinweis!

Jörg W. schrieb:
> Interessent schrieb:
> Davon abgesehen:
>
>
1
>   if(OCR2A >=254)
2
>     OCR2A = 0;
3
>
>
> Das wird kaum so funktionieren, wie du dir das vorstellst.  Du startest
> mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei
> 249 bist.  Im nächsten Schritt werden wieder 10 addiert, dann bist du
> bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253.  Diese
> if-Bedingung greift nur sowas von selten, dass du sie genauso gut
> komplett weglassen kannst.

Besten Dank. Das hat mich auf den richtigen Weg gebracht!

von Paul B. (paul_baumann)


Lesenswert?

Mitlesa schrieb:
> Scharf beobachtet, Paule.

Gell?!
..und vor Allem so schnell. Ich bin richtig stolz auf mich.

MfG Paul

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.