Forum: Mikrocontroller und Digitale Elektronik Interrupt Problem am Tiny13 dopelte Dauer ?


von Marcel B. (gigi)


Lesenswert?

Hallo,

habe hier ein kleines Programm für den Tiny geschrieben
und bemerke dass der Interrupt bzw die aufgerufene Funktion
10 anstatt 5 Sekunden dauert.

Also alarm() dauert 10 Sekundenm, ABER die funktion
blink() läuft so, wie sie soll.


Auch mit cli(); code sei(); in der if- Schleife ändert sich das 
Verhalten nicht.

1
#define F_CPU 128000UL
2
3
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <avr/sleep.h>
7
#include <avr/interrupt.h>
8
9
10
volatile uint8_t s;    
11
12
int alarm(void);  
13
int blink(void);  
14
15
ISR(INT0_vect)          // ISR - Put "switch" to 1
16
{
17
  s=1;
18
}
19
20
21
int main(void)
22
{
23
    DDRB = (1 << PB3);
24
  MCUCR = (1 << SE) | (1 << SM1) | (0 << SM0) | (0 << ISC00) | (0 << ISC01); // Sleep enabled - PwrDwn // LowLvlInt
25
  GIMSK = (1 << PCIE); // PCI Enable
26
  PCMSK = (1 << PCINT4); // PCI PB4
27
  
28
  int s = 0;
29
  
30
  sei();
31
  
32
  while(1)
33
    {
34
    
35
    if(s=1)
36
    {  cli();
37
      s=0;
38
      alarm();
39
      sei();
40
    }
41
    
42
    blink();
43
    sleep_mode();
44
  
45
    }
46
}
47
48
int alarm(void)
49
{
50
  
51
  s=0;
52
  PORTB =(0 << PB3);
53
  _delay_ms(5000);
54
  PORTB = (1 << PB3);
55
  
56
  
57
  return 0;
58
  
59
  
60
}
61
62
int blink (void)
63
{
64
  for(uint8_t i=0; i<3; i++)      //LED Signal, everything okay
65
  {
66
    PORTB = (0 << PB3);
67
    _delay_ms(1000);
68
    PORTB = (1 << PB3);
69
    _delay_ms(1000);
70
  }
71
  
72
  return 0;
73
}

von klapp (Gast)


Lesenswert?

Marcel B. schrieb:
> Auch mit cli(); code sei(); in der if- Schleife ändert sich das
> Verhalten nicht.

If Schleifen und delays in der ISR macht man nicht.

von Nico W. (nico_w)


Lesenswert?

Marcel B. schrieb:
> if(s=1)

Guck nochmal deinen Code an.

von Marcel B. (gigi)


Lesenswert?

Hab ich ja auch nicht.

Ich rede von der If-Schleife in der Funktion alarm().

Nico W. schrieb:
> Marcel B. schrieb:
>> if(s=1)
>
> Guck nochmal deinen Code an.

Was ist daran falsch ?

von Werner P. (Gast)


Lesenswert?

klapp schrieb:
> Marcel B. schrieb:
>> Auch mit cli(); code sei(); in der if- Schleife ändert sich das
>> Verhalten nicht.
>
> If Schleifen und delays in der ISR macht man nicht.

macht er doch nicht!

Denke es liegt eher an:
1
if(s=1)

von Nico W. (nico_w)


Lesenswert?

Marcel B. schrieb:
> Was ist daran falsch ?

Guck mal ganz genau hin!

von Route_66 H. (route_66)


Lesenswert?

klapp schrieb:
> If Schleifen und delays in der ISR macht man nicht.

If schleifen macht man grusätzlich nicht, weil es sowas nicht gibt.

Seine If-Abfrage macht er aber nicht im INT!
Heißt es nicht if(s==1)...?

von klapp (Gast)


Lesenswert?

Marcel B. schrieb:
> Ich rede von der If-Schleife in der Funktion alarm().

Es gibt keine If-Schleife! Das Ding heißt zB If Abfrage aber niemals 
Schleife :-)

von Marcel B. (gigi)


Lesenswert?

klapp schrieb:
> Marcel B. schrieb:
>> Ich rede von der If-Schleife in der Funktion alarm().
>
> Es gibt keine If-Schleife! Das Ding heißt zB If Abfrage aber niemals
> Schleife :-)

Stimmt!

Dieses == bricht mir noch den Hals! DANKE euch vielmals!

Allerdings blinkt es jetzt nur 1 Sekunde.

von Marcel B. (gigi)


Lesenswert?

Und trotz cli() und sei() kann ich das blinken ewig aufrecht erhalten.
1
 
2
int alarm(void)
3
{
4
  cli();
5
  s=0;
6
  PORTB =(0 << PB3);
7
  _delay_ms(5000);
8
  PORTB = (1 << PB3);
9
  sei();
10
  
11
  return 0;
12
  
13
  
14
}

von Werner P. (Gast)


Lesenswert?

Marcel B. schrieb:
> PORTB =(0 << PB3);
>   _delay_ms(5000);
>   PORTB = (1 << PB3);

Wundert mich eh dass da was blinkt ;-)

Bit setzen:
1
PORTB |= (1 << PB3);

Bit löschen:
1
PORTB &= ~(1 << PB3);

von Marcel B. (gigi)


Lesenswert?

Werner P. schrieb:
> Marcel B. schrieb:
>> PORTB =(0 << PB3);
>>   _delay_ms(5000);
>>   PORTB = (1 << PB3);
>
> Wundert mich eh dass da was blinkt ;-)
>
> Bit setzen:
> PORTB |= (1 << PB3);
> Bit löschen:
> PORTB &= ~(1 << PB3);


Gut, leuchten, nicht blinken, lach.
Es leuchtet aber keine 5000ms, vielleich 2000.

von HildeK (Gast)


Lesenswert?

Werner P. schrieb:
> Wundert mich eh dass da was blinkt ;-)

Doch, geht schon. Es hat eben die Wirkung wie
   PORTB = 0;
und
   PORTB = 8;

Es war zwar anders gemeint, wenn aber der PORTB sonst nicht verwendet 
wird, dann hat es an PB3 dieselbe Wirkung wie das was man üblicherweise 
macht und du auch geschrieben hast:

  PORTB &= ~(1 << PB3);
und
  PORTB |= (1 << PB3);

Beachte: er hatte nicht 'verodert', sondern nur zugewiesen!

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.