Timer0 problem

Gast #3615559
Lesenswert?

Wie stellst du das fest?
Ich vermute mal, mit einer LED am Ausgang oder sowas in der Art.
Da wirst du aber nicht viel sehen. Mit einem Oszilloskop schon.
Der Impuls wird nur sehr kurz sein.


> while(1)
> {
>   PORTB |= (1<<PB0);
PB0 wird gesetzt
>   if(TCNT0 ==200)
wenn TCNT0 = 200 ist,
>      PORTB &= (1<<PB0);
wird PB0 rückgesetzt
> }
und im nächsten Schleifendurchlauf sofort wieder gesetzt.
#3616044
Lesenswert?

Daniel L. schrieb:
> Ich habe das jetzt mal außerhalb der while-Schleife versucht,aber die
> LED leuchtet durchgehend


Was erwartest du?

Natürlich leuchtet die durchgehend (für dich langsamen Menschen).
Aber wenn du mal eine LED daneben auf Dauer-Ein einschaltest, dann wirst 
du sehen, dass sie etwas dunkler leuchtet (wenn auch nicht viel).

Kann es sein, dass du du ganz krass die Geschwindigkeit unterschätzt? 
Rechne mal nach, wie schnell deine LED eigentlich blinkt!
#3616060
Lesenswert?

Und bitte: kompletten Code! Inklusive der Angabe der Taktfrequenz, mit 
der der µC läuft.
Ehe du Code in Prosa beschreibst, kopiere lieber den Code hier rein. Und 
zwar alles. Das ist für dich einfacher und für uns auch. Denn dann haben 
wir ein Bild davon, wie der Code wirklich aussieht und müssen nicht 
raten.
OP #3616074
Lesenswert?

Hier der Code:
1
#include <asf.h>
2
#define F_CPU 3686400UL
3
#include <avr/io.h>
4
#include <interrupt.h>
5
#include <util/delay.h>
6
#include <stdio.h>
7

8
#define taste_gedruckt       1 
9
#define taste_nicht_gedruckt 0
10

11
volatile int k = 0;
12

13
int main (void)
14
{
15
  
16
  sei();
17
  
18
  DDRB = 0xff;
19
  DDRD = 0x00;
20
  PORTD = 0xff;
21
  
22
  int i = 0;
23
  int taste_jetzt;
24
  int taste_vorher; 
25

26
  
27
  void blink1();
28
  void blink2();
29
  
30
  TCCR0  |= (1<<CS00) | (CS01);
31
  TIMSK  |= (1<<TOIE0);
32
  
33

34
  
35
  if (!(PIND & (1<<PD2)))
36
  {
37
    taste_vorher = taste_gedruckt;
38
  } 
39
  else
40
  {
41
    taste_vorher = taste_nicht_gedruckt;
42
  }
43
  
44
  
45
  
46
    
47
  while (1)
48
  {  
49
    if(!(PIND & (1<<PD2)))
50
    {
51
      taste_jetzt  = taste_gedruckt;  
52
    }
53
    else
54
    {
55
      taste_jetzt  = taste_nicht_gedruckt; 
56
    }      
57
  
58
    if(taste_vorher != taste_jetzt)
59
    {
60
      if (taste_jetzt == taste_gedruckt)
61
      {
62
        i++;
63
        //switch(i)
64
        //{
65
          blink1(i, k);
66
        
67
        //blink2(i);
68
        //}
69
      }
70
    } taste_jetzt = taste_vorher;
71
    
72
    _delay_ms(50);
73
  }
74
}
75

76
void blink1(int i , int k )
77
{
78
  while(1)
79
  {
80
    PORTB |= (1<<PD1);
81
    if (k  >= 440)
82
    {  
83
        PORTB |= (1<<PD2);
84
        PORTB &= ~ (1<<PD1);
85
    }
86
    if (k>= 440)
87
    {  
88
      PORTB &= ~ (1<<PD2);
89
      PORTB |= (1<<PD0);
90
    }
91
    if(k>=440)
92
      PORTB &= ~ (1<<PD0);    
93
  }
94
   
95
}
96
void blink2(int i)
97
{
98
  
99
}
100

101
ISR(TIMER0_OVF_vect)
102
{
103
  k++;
104
  if (k >= 440)
105
    k=0;
106
}

Hier ist das Programm

Das Problem liegt hier in der Funktion blink1

Es sollte hier einfach die LED's umschalten
#3616081
Lesenswert?

Daniel L. schrieb:

> Es sollte hier einfach die LED's umschalten

Dann solltest du das auch machen.

ABer solange du den µC in der Funktion gefangen hältst
1
void blink1(int i , int k )
2
{
3
  while(1)
4
  {
5
    PORTB |= (1<<PD1);
6
    if (k  >= 440)
7
    {  
8
        PORTB |= (1<<PD2);
9
        PORTB &= ~ (1<<PD1);
10
    }
11
    if (k>= 440)
12
    {  
13
      PORTB &= ~ (1<<PD2);
14
      PORTB |= (1<<PD0);
15
    }
16
    if(k>=440)
17
      PORTB &= ~ (1<<PD0);    
18
  }
19
   
20
}

wird sich vom restlichen Programm da nichts mehr tun. Da ist eine 
Endlossschleife in der Funktion. Die Funktion wird nie mehr verlassen.
Ganz abgesehen davon, dass dein k auch mit ISR Hilfe nie größer/gleich 
440 werden kann.

Der ganze Ansatz ist Müll.
Mit der ISR hast du den perfekten Ort, um ein zeitliches Blinken zu 
realisieren.
#3616089
Lesenswert?

Karl Heinz schrieb:

> Der ganze Ansatz ist Müll.
> Mit der ISR hast du den perfekten Ort, um ein zeitliches Blinken zu
> realisieren.

STeck den kompletten Blink-Code in die ISR.
1
ISR(TIMER0_OVF_vect)
2
{
3
  if( isBlinking )
4
  {
5
    k++;
6
    if (k >= 440)
7
    {
8
      k=0;
9

10
      if( k > 200 ) {
11
        PORTB |= (1<<PD2);
12
        PORTB &= ~ (1<<PD1);
13
      }
14
      else {
15
        PORTB &= ~ (1<<PD2);
16
        PORTB |= (1<<PD0);      
17
      }
18
    }
19
  }
20
}

und im Hauptprogramm schaltest du bei Tastendruck einfach nur das 
Blinken ein/aus, indem du die Variable 'isBlinking' auf 0 bzw. 1 setzt.
1
volatile uint8_t isBlinking;
2

3
....
4

5

6
    if(taste_vorher != taste_jetzt)
7
    {
8
      if (taste_jetzt == taste_gedruckt)
9
      {
10
        isBlinking = 1 - isBlinking;
11
      }
12
      ...
13

14
...
#3616103
Lesenswert?

Karl Heinz schrieb:

> Hast du deine Tastenauswertung für sich alleine gestestet oder hast du
> das nicht?
> Funktioniert die?


Ehe da jetzt der nächste Schritt drauf gesetzt wird, sollte der Punkt 
erst mal geklärt sein. Nicht dass du/wir da jetzt einem Timer-Phantom 
nachjagen und das 'Problem' ganz woanders liegt.

1
+#include <asf.h>
2
#define F_CPU 3686400UL
3
#include <avr/io.h>
4
#include <interrupt.h>
5
#include <util/delay.h>
6
#include <stdio.h>
7

8
#define taste_gedruckt       1 
9
#define taste_nicht_gedruckt 0
10

11
volatile int k = 0;
12

13
int main (void)
14
{
15
  DDRB = 0xff;
16
  DDRD = 0x00;
17
  PORTD = 0xff;
18
  
19
  int i = 0;
20
  int taste_jetzt;
21
  int taste_vorher; 
22

23
  taste_vorher =  (PIND & (1<<PD2) ? taste_nicht_gedruckt : taste_gedruckt;
24

25
  while (1)
26
  {  
27
    taste_jetzt  = (PIND & (1<<PD2) ? taste_nicht_gedruckt : taste_gedruckt;  
28
  
29
    if(taste_vorher != taste_jetzt)
30
    {
31
      if (taste_jetzt == taste_gedruckt)
32
      {
33
        PORTB ^= ( 1 << PB2 );
34
      }
35
    } taste_jetzt = taste_vorher;
36
    
37
    _delay_ms(50);
38
  }
39
}

die LED an PB2 muss mit jedem Tastendruck umschalten.
klappt?
klappt nicht?
#3616106
Lesenswert?

Karl Heinz schrieb:
> PS:
> Allerdings müssen dazu auch die Interrupts mitels sei() freigegeben
> worden sein.

Seh gerade, du hast das am Anfang von main() gemacht.
Keine gute Idee.

Erst mal wird alles initialisiert, die Hardware eingestellt, Variablen 
auf ihre Anfangswerte begracht.
Und erst dann, wenn alles soweit fertig und grundsätzlich lauffähig ist, 
erst dann kommt das 'Feuer frei' für die Interrupts. Als letzte Aktion 
vor der Hauptschleife.
Denn was du nicht willst: Das die Interrupts sofort zu feuern beginnen, 
wenn du in einzelnen Komponenten einen spezifischen Interrupt während 
der Konfiguration frei gibst. Du kannst nicht alles parallel und zur 
gleichen Zeit konfigurieren. Du willst aber in komplexeren Programmen 
haben, dass das Interrupt-Konzert in geordneten Bahnen läuft. Und das 
tut es im Regelfall erst dann, wenn ALLE Komponenten initialisiert sind.
OP #3616118
Lesenswert?

1
if (!(PIND & (1<<PD2))) // wenn Taste gedrückt
2
  {
3
    taste_vorher = taste_gedruckt;
4
  } 
5
  else
6
  {
7
    taste_vorher = taste_nicht_gedruckt;
8
  }
9
  
10
  sei();  
11
  while (1)
12
  {  
13
    if(!(PIND & (1<<PD2))) // Wenn Taste gedrückt
14
    {
15
      taste_jetzt  = taste_gedruckt;  
16
    }
17
    else
18
    {
19
      taste_jetzt  = taste_nicht_gedruckt; 
20
    }      
21
  
22
    if(taste_vorher != taste_jetzt)
23
    {
24
      if (taste_jetzt == taste_gedruckt)
25
      {
26
        
27
          PORTB ^= (1<<PB0); // Wird umgeshcalten
28
        
29
        
30
      }
31
    } taste_jetzt = taste_vorher;
32
    
33
    _delay_ms(50);
34
  }
35
}
OP #3616207
Lesenswert?

1
#include <asf.h>
2
#define F_CPU 3686400UL
3
#include <avr/io.h>
4
#include <interrupt.h>
5
#include <util/delay.h>
6
#include <stdio.h>
7

8
#define taste_gedruckt       1 
9
#define taste_nicht_gedruckt 0
10

11
volatile int k = 0;
12
volatile bool isblinking = false;
13

14
int main (void)
15
{
16
        
17
  DDRB = 0xff;
18
  DDRD = 0x00;
19
  PORTD = 0xff;
20
  
21
  int i = 0;
22
  int taste_jetzt;
23
  int taste_vorher; 
24

25
  
26
  void blink1();
27
  void blink2();
28
  
29
  TCCR0  |= (1<<CS00) | (CS01);
30
  TIMSK  |= (1<<TOIE0);
31
  
32

33
  
34
  if (!(PIND & (1<<PD2)))
35
  {
36
    taste_vorher = taste_gedruckt;
37
  } 
38
  else
39
  {
40
    taste_vorher = taste_nicht_gedruckt;
41
  }
42
    
43
  sei();  
44
  while (1)
45
  {  
46
    if(!(PIND & (1<<PD2)))
47
    {
48
      taste_jetzt  = taste_gedruckt;  
49
    }
50
    else
51
    {
52
      taste_jetzt  = taste_nicht_gedruckt; 
53
    }      
54
  
55
    if(taste_vorher != taste_jetzt)
56
    {
57
      if (taste_jetzt == taste_gedruckt)
58
      {
59
        
60
          PORTB ^= (1<<PB0);
61
        
62
      }
63
    } taste_vorher = taste_jetzt;
64
    
65
    _delay_ms(30);
66
  }
67
}
OP #3616255
Lesenswert?

Hier noch die ISR
1
ISR(TIMER0_OVF_vect)
2
{
3
  
4
  
5
  if (isblinking == true)
6
  {
7
    k++;
8
    if (k >= 440)
9
    k=0;
10
    
11
    PORTB |= (1<<PD1);
12
    if (k == 440)
13
    {
14
      PORTB |= (1<<PD2);
15
      PORTB &= ~(1<<PD1);
16
    }
17
    if (k>= 440)
18
    {
19
      PORTB &= ~(1<<PD2);
20
      PORTB |= (1<<PD0);
21
    }
22
    if(k>=440)
23
    PORTB &= ~(1<<PD0);
24
  }
25
  
26
}
OP #3616278
Lesenswert?

Oke tut mir leid hier ist der ganze Code:
1
#include <asf.h>
2
#define F_CPU 3686400UL
3
#include <avr/io.h>
4
#include <interrupt.h>
5
#include <util/delay.h>
6
#include <stdio.h>
7

8
#define taste_gedruckt       1
9
#define taste_nicht_gedruckt 0
10

11
volatile int k = 0;
12
volatile bool isblinking = false;
13

14
int main (void)
15
{
16
  
17
  DDRB = 0xff;
18
  DDRD = 0x00;
19
  PORTD = 0xff;
20
  
21
  int i = 0;
22
  int taste_jetzt;
23
  int taste_vorher;
24

25
  
26
  void blink1();
27
  void blink2();
28
  
29
  TCCR0  |= (1<<CS00) | (CS01);
30
  TIMSK  |= (1<<TOIE0);
31
  
32

33
  
34
  if (!(PIND & (1<<PD2)))
35
  {
36
    taste_vorher = taste_gedruckt;
37
  }
38
  else
39
  {
40
    taste_vorher = taste_nicht_gedruckt;
41
  }
42
  
43
  
44
  
45
  
46
  sei();
47
  while (1)
48
  {
49
    if(!(PIND & (1<<PD2)))
50
    {
51
      taste_jetzt  = taste_gedruckt;
52
    }
53
    else
54
    {
55
      taste_jetzt  = taste_nicht_gedruckt;
56
    }
57
    
58
    if(taste_vorher != taste_jetzt)
59
    {
60
      if (taste_jetzt == taste_gedruckt)
61
      {
62
      
63
             isblinking = true;
64
        
65
        
66
      }
67
    } taste_vorher = taste_jetzt;
68
    
69
    _delay_ms(30);
70
  }
71
}
72
ISR(TIMER0_OVF_vect)
73
{
74
  
75
  
76
  if (isblinking == true)
77
  {
78
    k++;
79
    if (k >= 440)
80
    k=0;
81
    
82
    PORTB |= (1<<PD1);
83
    if (k == 440)
84
    {
85
      PORTB |= (1<<PD2);
86
      PORTB &= ~(1<<PD1);
87
    }
88
    if (k>= 440)
89
    {
90
      PORTB &= ~(1<<PD2);
91
      PORTB |= (1<<PD0);
92
    }
93
    if(k>=440)
94
    PORTB &= ~(1<<PD0);
95
  }
96
  
97
}
Gast #3667701
Lesenswert?

Hallo,

Kann mir jemand sagen warum die Led bei diesem Code nicht leuchtet ?

//---------------------CODE 1-----------------------------
#include <avr/io.h>
#include <avr/interrupt.h>

long cnt;
int main(void)
{
    TCCR0 = (1<<CS01);
    TIMSK |= (1<<TOIE0);
    DDRD = 0b11110111;
    sei();
    while(1)
    {
    if(cnt > 3900)
    {
      PORTD = 0x01;
      cnt = 0;
    }

    }
}
ISR (TIMER0_OVF_vect)
{
      cnt++;
}


Bei diesem Code leuchtet die Led jedoch!!!!!!!!!!!
//---------------------CODE 2-----------------------------
#include <avr/io.h>
#include <avr/interrupt.h>

long cnt;

int main(void)
{
    TCCR0 = (1<<CS01);
    TIMSK |= (1<<TOIE0);
    DDRD = 0b11110111;
    sei();

    while(1)
    {


    }
}

ISR (TIMER0_OVF_vect)
{
      cnt++;
      if(cnt > 3900)
      {
        PORTD = 0x01;
        cnt = 0;
      }
}


Im Grunde ist es das gleiche Programm aber es funktioniert nur der Code 
2.
Wenn ich das Programm im Atmel Studio 6 Simuliere sieht es aus als würde 
nur 1 mal die while schleife augeführt werden und danach nicht mehr, was 
auch erklären würden wieso die Led nicht leuchtet. Aber Wieso? Kann mir 
jemand weiter helfen!?

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