Forum: Mikrocontroller und Digitale Elektronik PIN-Abfrage in ISR -> Unterschied zwischen if(PIN)-else anders als if(PIN)-else if(!PIN)


von Michael (Gast)


Lesenswert?

Hallo zusammen,

ich habe gerade mein DCF1-Modul von Pollin angeschlossen und wollte ein 
bisschen damit rumexperimentieren. Dazu habe ich einfach das Signal vom 
Modul (PA0) alle 0,01 s mit einem ATmega16 auf einen Pin (PD5) 
ausgegeben.
1
ISR (TIMER0_OVF_vect)
2
{
3
  // alle 0,01 Sekunden
4
  TCNT0 = (uint8_t)(-156);
5
  
6
  if (!(PINA & (1 << PINA0)))
7
  {
8
    PORTD |= (1 << PD5);
9
  }
10
  else if ((PINA & (1 << PINA0)))
11
  {
12
    PORTD &= ~(1 << PD5);
13
  }
14
}

Dabei blinkt die LED zwar ungefähr 1/s aber nach einigen Wiederholungen 
gab es dann eine mehrsekündige Pause. Ich dachte meine Beschaltung wäre 
nicht gut genug entstört, aber nachdem ich die else if-Bedingung durch 
ein einfaches else ersetzt habe klappt jetzt alles wunderbar.
1
ISR (TIMER0_OVF_vect)
2
{
3
  // alle 0,01 Sekunden
4
  TCNT0 = (uint8_t)(-156);
5
  
6
  if (!(PINA & (1 << PINA0)))
7
  {
8
    PORTD |= (1 << PD5);
9
  }
10
  else
11
  {
12
    PORTD &= ~(1 << PD5);
13
  }
14
}

Für mich ist es nachvollziehbar, dass zwischen den beiden if-Abfragen 
der Zustand des Pins wechselt, aber spätestens im nächsten Durchlauf 
müsste dann doch der gleiche Zustand anliegen und die LED wie gewohnt 
blinken (also ein maximaler Unterschied von 0,01 s). Natürlich kann ich 
hier die else Bedingung weglassen, aber ich verstehe nicht, wieso ich 
das muss.

Kann mir das einer erklären?

Danke und Gruß
Michael

von Nutzer (Gast)


Lesenswert?

andere Frage: warum castet man eine vorzeichenbehaftete Zahl die über 8 
Bit lang ist nach uint8_t?

von Michael (Gast)


Lesenswert?

Hallo,

damit man (im Kopf) einfacher rechnen kann.
Ich brauche mit meinem Quarz (16MHz) und dem Vorteiler (1024) 156 Takte 
für ~0,01s. Würde ich den Counter direkt mit positiven Integerwerten 
füttern so wäre die Rechnung/Überlegung:
Ich brauche 156 Takte, der Timer/Counter hat 8 bit -> 256 Takte, daher 
müsste ich TCNT0 auf 256 - 156 = 100 stellen.
Einfacher ist es jedoch, wenn ich mir durch den Cast einfach diesen Wert 
berechnen lasse -> (uint8_t)(-156) = 100
Ich könnte natürlich auch direkt TCNT0 = 100 setzen, aber so brauche ich 
keinen Zwischenschritt.

Gruß
Michael

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.