Timer Interrupt wird nicht ausgelöst?

Gast #4387258
Lesenswert?
• ▲
▼
Hallo,

ich bin dabei mich mit dem timer des atmega 328p zu befassen. Ich will 
spätzer daraus eine Uhr bauen zu lernzwecken. Bin jetzt an einem Punkt, 
wo ich einfach mal Hilfe brauche.

Ich habe an meinem µController vier 7-Segmentanzeigen. Die ich wunderbar 
ansteuern kann. Jetzt möchste ich, dass die Ziffern der 7 Segmentanzeige 
wenn der Timer zum 50zigsten Mal seinen maximalwert erreicht hat 
umgeschaltet wird. Die Ziffern habe ich in einem Array. Jedoch bleiben 
meine 7-Segmentanzeigen dauerhaft auf 0 0 0 0, wenn ich das ganze mit 
dem Timer versuche. In der Hauptschleife wird die Bedingung 
if(extraTime>50) nie erfüllt bzw. der Interrupt wird gar nicht 
aufgerufen?

Jemand eine Idee?
1
/*
2
 * Uhr.c
3
 *
4
 * 
5
 *  Author: xxxx
6
 */ 
7
#ifndef F_CPU
8
#define F_CPU 8000000UL
9

10

11
  //Externer Quarztakt
12
#endif
13
#include <avr/io.h>
14
#include <util/delay.h>    //Warteschleifen
15
#include <avr/interrupt.h>  //Interruptheader
16
int extraTime=0;
17

18
//Konsanten
19
const char sieben_seg_ziffer[10] = {0b01000100,0b11001111,0b01010010,0b11000010,0b11001001,0b11100000,0b01100000,0b11001110,0b01000000,0b11000000};//Ziffern 0 bis 9 der 7-Seganzeige
20
  
21

22

23
ISR(TIMER0_COMPA_vect)
24
{
25
  extraTime++;
26
}
27

28
  
29

30
int main(void)
31
{
32

33
  
34
  TCCR0A |= (1<<WGM01);//CTC Mode aktivieren
35
  OCR0A = 156;//Max Wert bis Interrupt auslöst
36
  TIMSK0 |=  (1<<OCIE0A);
37
  sei();
38
  
39
  TCCR0A |= (1<<CS00)|(1<<CS02);//Setting Prescaler clk/1024
40
  
41
  
42
  
43
  DDRD   = 0b11111111;                      //Ausgang; Siebensegmentanzeige
44
  DDRC   = 0b11111111;            //Ausgang; Die vier Anoden der 7-Segmentanzeigen
45
  
46
  
47
  //vier 7-Segmentanzeigen aktivieren
48
  PORTC|=(1<<PC0);
49
  PORTC|=(1<<PC1);
50
  PORTC|=(1<<PC2);
51
  PORTC|=(1<<PC3);
52
  
53

54
  
55
  while(1)
56
    {
57
    
58
    int i=0;
59
  
60
    do 
61
    {
62
      PORTD=sieben_seg_ziffer[i];
63
    
64
      if(extraTime>50)
65
      {
66
        i++;
67
        extraTime=0;
68
      }
69
      } while (i<10);
70
    
71

72
  }
73
}
Gast #4387324
Lesenswert?
• ▲
▼
Danke für den Hinweis. Mit volatie int extraTimer habe ich jetzt 
ausgeschlossen, dass irgendwas wegoptimiert wurde. Trotzdem wird wie es 
aussieht die Bedinung if(extraTime>50) nicht erfüllt, da die Anzeige bei 
0 0 0 0 bleibt. hhhmm irgendwo ist noch ein bock...
Gast #4387712
Lesenswert?
• ▲
▼
Als erstes würde ich Dir vorschlagen, dass Du mal eine "Debug"-Funktion 
mittels einer LED in die ISR einbaust.
Suche Dir einen freien PORT mit passendem PIN
und daran schliesst Du eine LED an. Vergiss nicht den Port als Ausgang 
zu definieren.

Die ISR erweiterst Du wie folgt
1
ISR(TIMER0_COMPA_vect)
2
{
3
  PORTx ^= 0x80;      // Bspw. an PORTx (der freie Port) mit dem Bit7 wackeln
4
  extraTime++;
5
}
Dann siehst Du, ob Deine ISR überhaupt funktioniert.
D.h., die LED sollte flackern. Notfalls mal eine Scope anschliessen,
dann siehst Du auch die Taktrate Deines ISR. D.h., Du kannst am Scope 
sehen, wieviel Zeit vergeht bis der ISR wieder aufgerufen wird.

Als weiteres würde ich die Variable extraTime als char bzw. uint8_t 
definieren. Denn int ist 16-Bit. Damit gibt es immer Probleme, denn 
ein AVR ist ein 8-bittiger Prozessor. Auch wenn sie als volatile 
definiert ist.
Gewöhne Dir bitte an die Typdeklarationen zu benutzen die hier üblich 
sind.
Also: nicht char sonder als int8_t bzw. unsigned char als uint8_t zu 
deklarieren, usw.. Damit wird es Dir letzten Endes leicher und 
verständlicher gemacht. Weil Du genau weisst, wieviel Bits deine 
Variable definitiv hat.

Und als letzte Info: Nimm den #include <util/delay.h>  raus und setze 
die Optimierung auf -O0, sprich schalte sie aus.

Wenn alles läuft kannst Du später die Optimierung wieder aktivieren.
Gast #4387715
Lesenswert?
• ▲
▼
dude schrieb:
> sei();
>
>   TCCR0A |= (1<<CS00)|(1<<CS02);//Setting Prescaler clk/1024

Nachtrag:

Die Interrupts sollte man immer erst dann freigeben, wenn
alle Register vollständig initialisiert sind.
D.h., Dein sei() sollte nach dem setzen des Prescalers erfolgen.

Viel Erfolg!

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.