led toogle mit mega88

Gast #811053
Lesenswert?

Hallo,

folgendes Programm mit einem ATmega88 läuft bei mir nicht:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#define F_CPU 8000000
5

6
volatile int counter = 0;
7

8

9
int main( void ) {
10

11
  DDRC = 0xFF;                    // PORTC als Ausgang, LEDS aus
12

13
  TCCR0B |= (1<<CS00) | (1<<CS02);          // Prescaler = 1024, Timer aktivieren
14
  TIMSK0 |= (1<<TOIE0);                // Interrupt für TimerOverflow aktivieren
15
  sei();                        // Interrupts global aktivieren
16

17
  PORTC = 0x00;                    // Alle LEDS an
18

19
  return(0);    
20
}
21

22

23
ISR( TIMER0_OVF_vect ) {                // Timer InterruptHandler, Ausführung 30.5 mal pro Sekunden
24
  
25
  counter++;  
26
    
27
  if( counter >= 5 ) {
28

29
    switch( PORTC ) {
30

31
    case 0x00:
32
      
33
      PORTC = 0xFF;
34

35
    case 0xFF:
36

37
      PORTC = 0x00;
38

39
    }
40
  
41
  counter = 0;
42

43
  }  
44
}


Ich habs jetzt schon so oft kontrolliert aber ich find den Fehler nicht. 
Die Leds bleiben einfach an, da tut sich nichts. Sollten eigentlich so 
ca. 6 mal pro Sekunde wechseln. Das CKDIV8 Fuse ist nicht gesetzt.

Thx
Gast #811084
Lesenswert?

da tut sich aber auch nichts wenn ich den counter zb auf 100 erhöhe, 
habs jetzt mal mit PortD versucht:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#define F_CPU 8000000
5

6
volatile int counter = 0;
7

8

9
int main( void ) {
10

11
  DDRD = 0xFF;                    // PORTC als Ausgang, LEDS aus
12

13
  TCCR0B |= (1<<CS00) | (1<<CS02);          // Prescaler = 1024, Timer aktivieren
14
  TIMSK0 |= (1<<TOIE0);                // Interrupt für TimerOverflow aktivieren
15
  sei();                        // Interrupts global aktivieren
16

17
  PORTD = 0x00;                    // Alle LEDS an
18

19
  while( 1 )
20

21
  return(0);    
22
}
23

24

25
ISR( TIMER0_OVF_vect ) {                // Timer InterruptHandler, Ausführung 30.5 mal pro Sekunden
26
  
27
  counter++;  
28
    
29
  if( counter >= 100 ) {
30

31
    switch( PORTD ) {
32

33
    case 0x00:
34
      
35
      PORTD = 0xFF;
36

37
    case 0xFF:
38

39
      PORTD = 0x00;
40

41
    }
42
  
43
  counter = 0;
44

45
  }  
46
}
#811092
Lesenswert?

Hallo Gast!
Du hast die Initialiesierungen alle man in der Main-Funktion drinne.
Die gehören davor, da diese eigentlich nur einmal aufgerufen werden 
sollen.
1
  DDRC = 0xFF;                    // PORTC als Ausgang, LEDS aus
2
  TCCR0B |= (1<<CS00) | (1<<CS02);      // Prescaler = 1024, Timer aktivieren
3
  TIMSK0 |= (1<<TOIE0);             // Interrupt für TimerOverflow aktivieren
4
  sei();                        // Interrupts global aktivieren
5
  PORTC = 0x00;                    // Alle LEDS an

Der ganze Kram muss VOR die Main-Funktion stehen.
Dann sollte es klappen ;-)
MFG K-Duke
Gast #811093
Lesenswert?

Ok abgeändert, weiterhin leuchten die LEDs nur:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#define F_CPU 8000000
5

6
volatile unsigned char counter;
7

8

9
int main( void ) {
10

11
  DDRD = 0xFF;                    // PORTC als Ausgang, LEDS aus
12

13
  TCCR0B |= (1<<CS00) | (1<<CS02);          // Prescaler = 1024, Timer aktivieren
14
  TIMSK0 |= (1<<TOIE0);                // Interrupt für TimerOverflow aktivieren
15
  sei();                        // Interrupts global aktivieren
16

17
  PORTD = 0x00;                    // Alle LEDS an
18

19
  while( 1 );
20

21
}
22

23

24
ISR( TIMER0_OVF_vect ) {                // Timer InterruptHandler, Ausführung 30.5 mal pro Sekunden
25
  
26
  counter++;  
27
    
28
  if( counter >= 100 ) {
29

30
    switch( PORTD ) {
31

32
    case 0x00:
33
      
34
      PORTD = 0xFF;
35

36
    case 0xFF:
37

38
      PORTD = 0x00;
39

40
    }
41
  
42
  counter = 0;
43

44
  }  
45
}
#811098
Lesenswert?

Karsten B. wrote:
> Hallo Gast!
> Du hast die Initialiesierungen alle man in der Main-Funktion drinne.
> Die gehören davor, da diese eigentlich nur einmal aufgerufen werden
> sollen.
>
1
  DDRC = 0xFF;                    // PORTC als Ausgang, LEDS aus
2
>   TCCR0B |= (1<<CS00) | (1<<CS02);      // Prescaler = 1024, Timer
3
> aktivieren
4
>   TIMSK0 |= (1<<TOIE0);             // Interrupt für TimerOverflow
5
> aktivieren
6
>   sei();                        // Interrupts global aktivieren
7
>   PORTC = 0x00;                    // Alle LEDS an
>
> Der ganze Kram muss VOR die Main-Funktion stehen.
> Dann sollte es klappen ;-)
> MFG K-Duke
Vor der main()-Funktion dürfen überhaupt keine Initialisierungen 
stehen! Lies Dir mal ein C-Buch durch, bevor Du hier so einen Unfug 
erzählst! In C darf Code nur innerhalb von Funktionen stehen.

Der ganze Kram steht da schon richtig.
#811102
Lesenswert?

@ Gast:
Karlheinz hat natürlich völlig recht: solange immer noch das unsinnige 
und so wie es da steht nicht funktionierende switch-case da steht, 
kann es nicht funktionieren! Nimm eine der beiden von mir weiter oben 
geposteten Versionen. Die funktionieren sicher!

EDIT: Sehe grad, dass Du auf PORTD gewechselt hast. Sollte dann zwar 
eigentlich funktionieren, aber ist trotzdem unsinnig.
#811118
Lesenswert?

Siehst Du jetzt, warum switch an so einer Stelle völliger Unsinn ist? 
Erstens ist es fehleranfällig, zweitens macht switch nur dann Sinn, 
wenn man deutlich mehr als zwei Fälle unterscheiden muss und drittens 
gibt es grad in diesem Fall mehrere Varianten, das ganze einzeilig zu 
schreiben.

Wenn man schon eine Verzweigung mit zwei Möglichkeiten machen will, dann 
in so einem Fall ein if-else
1
if(!PORTD)
2
    PORTD = 0xFF;
3
else
4
    PORTD = 0;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren