Forum: Compiler & IDEs Timer-Problem Atmega16 und Code::Blocks


von Laurenz K. (gimmebottles)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein Problem, ich möchte den Timer0 eines Atmega16 mit 
Overflow-Interrupt nutzen. Der Code steht unten, es wird aber nie in die 
ISR-gesprungen.

Ich verwende avr-gcc 4.5.3 und COde::Blocks 10.05. Erkennt jemand den 
Fehler?

Im Anhang ist der komplette Projektordner, vielleicht stimmen ja auch 
meine Einstellungen in Code::Blocks nicht.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
#include "main.h"
6
7
8
uint8_t step, column, frame[100];
9
10
int main(void)
11
{
12
   uint8_t buf[100], i, ii;
13
14
15
   init();
16
17
//   PORTA = 0b11111111;
18
//   PORTC = 0b11111111;
19
//   PORTD = 0b11111111;
20
21
   for(i=0; i<100; i++) {
22
      frame[i] = 50;
23
   }
24
25
   while(0) {  //Hauptschleife
26
27
      while(!(SPSR & (1<<SPIF)))
28
         ;
29
      buf[i] = SPDR;
30
      if(buf[i] == 255) {
31
         switch(buf[0]) {
32
            case 0:  //Einzelne Lampe setzen
33
               frame[buf[1]] = buf[2];
34
            break;
35
            case 1:  //Alle Lampen gleich setzen
36
               for(ii = 0; ii < 97; ii++)
37
                  frame[ii] = buf[1];
38
            break;
39
            case 2:  //Ganzes Bild setzen
40
               for(ii = 0; ii < 97; ii++)
41
                  frame[ii] = buf[ii+1];
42
            break;
43
            case 3:  //Ganze Spalte setzen
44
               for(ii = 0; ii < 6; ii++)
45
                  frame[(buf[1]*7)+ii] = buf[2];
46
            break;
47
            case 4:  //Ganze Reihe setzen
48
               for(ii = 0; ii < 13; ii++)
49
                  frame[buf[1]+(ii*7)] = buf[2];
50
            break;
51
         }
52
         i = 0;
53
      }
54
      else
55
         i++;
56
   }
57
58
    return 0;
59
}
60
61
void init(void)
62
{
63
   DDRA = 0b11111111;   //Ports als Ausgänge schalten
64
   DDRC = 0b11111111;
65
   DDRD = 0b11111111;
66
   DDRB = 0b00001111;
67
68
   PORTA = 0b00000000;  //Alle Pins low, alle LEDs aus
69
   PORTC = 0b00000000;
70
   PORTD = 0b00000000;
71
   PORTB = 0b00000000;
72
73
   column = 0;
74
   step = 0;
75
76
   DDRB = (1<<PORTB6); //MISO als Ausgang
77
   SPCR = (1<<SPE);  //SPI aktivieren
78
79
   TCCR0 = (1<<CS01);   //timer0 konfigurieren,
80
   TIMSK |= (1<<TOIE0); //starten,
81
   TCNT0  = 141;        //und vorladen
82
   sei();
83
}
84
85
ISR(TIMER0_OVF_vect)
86
{
87
   uint8_t i;
88
89
   PORTB = 0b00001111;  //WIRD NIE AUSGEFÜHRT
90
91
92
   TCNT0  = 141;
93
94
   PORTA = 0b00000000;  //RESET ROWS A
95
   PORTC = 0b00000000;  //RESET ROWS B
96
   PORTC = 1 << column; //SET COLUMN column
97
98
   for(i = 0; i < 7; i++) {
99
      if(frame[(column*7)+i] <= step) {
100
         PORTA = 1 << i;   //SET ROW i IN A
101
      }
102
103
      if(frame[(column*7)+i+49] <= step) {
104
         PORTC = 1 << i;   //SET ROW i IN B
105
      }
106
   }
107
108
   column++;
109
   if(column > 6) {
110
      column = 0;
111
      step++;
112
      if(step > 50)
113
         step = 0;
114
   }
115
}

von Karl H. (kbuchegg)


Lesenswert?

>    DDRB = (1<<PORTB6); //MISO als Ausgang

Du hast dir soeben die unteren 4 BIts am Port B, die in der ISR als 
Nachweis benutzt werden und die du vorher als Ausgang konfiguriert hast, 
wieder auf Eingang zurückkonfiguriert.

von Laurenz K. (gimmebottles)


Lesenswert?

so, ich habe jetzt mal alles überflüssige entfernt, trotzdem springt er 
nicht in die ISR, PORTD0 bleibt high.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
#include "main.h"
6
7
#define F_CPU 16000000UL
8
9
10
int main(void)
11
{
12
13
14
15
   init();
16
17
   PORTD |= (1<<PD0);
18
19
20
21
   while(0) {  //Hauptschleife
22
23
24
   }
25
26
    return 0;
27
}
28
29
void init(void)
30
{
31
   DDRA = 0b11111111;   //Ports als Ausgänge schalten
32
   DDRC = 0b11111111;
33
   DDRD = 0b11111111;
34
   DDRB = 0b00001111;
35
36
   PORTA = 0b00000000;  //Alle Pins low, alle LEDs aus
37
   PORTC = 0b00000000;
38
   PORTD = 0b00000000;
39
   PORTB = 0b00000000;
40
41
   TCCR0 = (1<<CS01);   //timer0 konfigurieren,
42
   TIMSK |= (1<<TOIE0); //starten,
43
   TCNT0  = 141;        //und vorladen
44
   sei();
45
}
46
47
ISR(TIMER0_OVF_vect)
48
{
49
   uint8_t i;
50
51
52
   PORTD = 0b00000000;
53
54
   TCNT0  = 141;
55
56
57
58
}

von Stefan E. (sternst)


Lesenswert?

Laurenz K. schrieb:
> trotzdem springt er
> nicht in die ISR

Weil du main() verlässt. Nach main() kommt eine Endlosschleife mit 
ausgeschalteten Interrupts.

von Peter D. (peda)


Lesenswert?

Laurenz K. schrieb:
> while(0) {  //Hauptschleife

Alles darin ist toter Code.


Schreib besser:
1
  for(;;){
2
    ...
3
  }

Das funktioniert immer.
Und jeder weiß sofort, was damit gemeint ist.


Peter

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.