Forum: Mikrocontroller und Digitale Elektronik TIMER in C, AVR, Hilfe! danke!


von sutcer (Gast)


Lesenswert?

Hallo Leute!

Ich danke schonmal für die Hilfe, konnte auch schon ein wenig was damit
erreichen... steht steh ich aber vor meinem abschließendem problem,
allerdings nicht der timer selbst, hoff ich. vielleicht kann mir ja
nochma jemand helfen :-)

also, wenn das eingangssignal an port d eine längere zeit x (von mir aus
5 sekunden) fehlt, erst dann soll der ausgang port C0 (bei mir eine rote
LED) geschaltet werden und somit zeigen dass meine 'lichtschranke' zu
lang unterbrochen war.
zweites problem, ich hab einen taster an port B2 liegen, dieser soll
eine quittierung werden und ausgang port C0 (rote led) dauerhaft
ausschalten, bis die lichtschranke wieder zu lange unterbrochen wird.
derzeit geht sie nur aus, wenn der taster betätigt ist.

hier mal mein kleines programm, dass ich bis jetzt zusammen habe:

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL

ISR( TIMER0_OVF_vect )

{
  static uint8_t swTeiler = 0;

  swTeiler++;
  if ( swTeiler == 250)
  {
  swTeiler =1000000;
  PORTC |= (1<<0);
  }

}
int main ()
{
  DDRB=0x01;                       // B.0 = Ausgang
  DDRB &=~(1<<2);                  // PIN PB1 als Eingang
  PORTB |=(1<<2);                  // internen Pull-Up an PC1 aktivieren
  DDRC = 0x01;                     // B.0 = Ausgang

  ACSR &= ~(1<<7);                 // Comparator einschalten
  sei();                           // globale interrupts freigeben




  while (1)
  {

    if (bit_is_set (ACSR, 5))
    {
    PORTB &= ~(1<<0);             // LED = OFF
    TCCR0  = (1<<CS01);
    TIMSK |= (1<<TOIE0);
    }
    else
    {
    PORTB |= (1<<0);
    }
    if(bit_is_clear (PINB,2))
    {
    PORTC &=~(1<<0);
    }

  }

}

von Karl H. (kbuchegg)


Lesenswert?

Nehmen wir mal nur diesen Teil raus

    if (bit_is_set (ACSR, 5))
    {
    PORTB &= ~(1<<0);             // LED = OFF
    TCCR0  = (1<<CS01);
    TIMSK |= (1<<TOIE0);
    }


Der Comperator sagt dir: kein Eingangssignal.
Du schaltest die LED aus und startest den Timer.

Soweit so gut. Der Timer läuft jetzt.

Was macht deine Hauptschleife? Die läuft weiter und kommt natürlich 
wirgendwann wieder zu bewusster Abfrage. Noch immer meldet dir der 
Comperator, dass kein Eingangssignal vorhanden ist. Und wieder schaltest 
du die LED aus und startest den Timer. OK, der Timer ist schon gelaufen, 
von daher hat das keine Auswirkungen auf den Timer.

Weiter dreht deine Hauptschleife ihre Runden wobei sie jedesmal 
feststellt, dass kein Eingangssignal vorhanden ist und daher die LED 
auszuschalten und der Timer zu starten ist.

In der Zwischenzeit hat aber auch der Timer vor sich hingezählt und 
zählt und zählt.

<Sprung etwas in die Zukunft>

Der Timer ist wieder mal auf einen Overflow gelaufen und hat daher die 
ISR angestossen. In der ISR wurde in der Zwischenzeit weit genug 
hochgezählt und du schaltest die LED ein. Gut.
Aber wie gehts weiter? Nach Abarbeitung der ISR gehts an der Stelle im 
Hauptprogramm weiter, an der unterbrochen wurde. Und es kommt wie es 
kommen muss: die Hauptschleife kommt irgendwann zur bewussten Abfrage ob 
ein Signal vorhanden ist ... ist es nicht ... also wird in der 
Hauptschleife die LED abgeschaltet und der Timer gestartet.

D.h. deine ISR hat die LED eingeschaltet. Aber ein paar µ-Sekunden 
später wurde die LED in der Hauptschleife wieder abgeschaltet.

Da wirst du dir was anderes überlegen müssen. So gehts nicht.

Hinweis: du könntest dir zb in einer Variablen merken, ob der Timer 
schon eingeschaltet wurde oder nicht und diese Information zb bei der 
Abfrage ob ein Eingangssignal vorliegt benutzen.
Nur dann wenn
   kein Eingangssignal vorliegt
   UND der Timer noch nicht läuft
nur dann musst du
       die LED ausschalten
       den Timer starten
       und dir merken, dass der Timer jetzt läuft

Denn: wenn der Timer bereits läuft, brauchst du nichts mehr tun, wenn 
das Eingangssignal fehlt. Denn der Timer läuft ja bereits und wird nach 
der Zeitverzögerung die LED einschalten.

von Route_66 (Gast)


Lesenswert?

Hallo!
was mir als erstes auffällt: Du setzt in der Timer-ISR immer den 
swTeiler auf Null. Da kannst du den hinterher inkrementieren wie du 
willst, der wird am Ende nur bis Eins kommen...

von Karl H. (kbuchegg)


Lesenswert?

Route_66 schrieb:
> Hallo!
> was mir als erstes auffällt: Du setzt in der Timer-ISR immer den
> swTeiler auf Null. Da kannst du den hinterher inkrementieren wie du
> willst, der wird am Ende nur bis Eins kommen...

Das ist eine static Variable. Das passt schon.

von Route_66 (Gast)


Lesenswert?

O.K. übersehen.

von sutcer (Gast)


Lesenswert?

hey heinz!

vielen dank, als mal für die schnelle hilfe! hab in vielen anderen 
beiträgen nachgelesen, und schon gedacht, dass bei mir so ein fehler 
vorliegt, dass ich quasi mich die ganze zeit im kreis drehe.

ich werd mich jetzt mal mit den variablen beschäftigten und schauen, wie 
ich das im programm 'merken' kann. ist grad alles so ein riesen wald für 
mich!

aber merci nochmal!!!

werde berichten!

von sutcer (Gast)


Lesenswert?

achso, schnelle frage noch...

kann ich das eventuell mit 'toggle' lösen? bzw. welche variable könnt 
ich denn benutzen?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Route_66 schrieb:
>> Hallo!
>> was mir als erstes auffällt: Du setzt in der Timer-ISR immer den
>> swTeiler auf Null. Da kannst du den hinterher inkrementieren wie du
>> willst, der wird am Ende nur bis Eins kommen...
>
> Das ist eine static Variable. Das passt schon.

Die 1000000 passen aber nicht, jedenfalls nicht in einen uint8_t ;-)

von Karl H. (kbuchegg)


Lesenswert?

Frank M. schrieb:
> Karl Heinz Buchegger schrieb:
>> Route_66 schrieb:
>>> Hallo!
>>> was mir als erstes auffällt: Du setzt in der Timer-ISR immer den
>>> swTeiler auf Null. Da kannst du den hinterher inkrementieren wie du
>>> willst, der wird am Ende nur bis Eins kommen...
>>
>> Das ist eine static Variable. Das passt schon.
>
> Die 1000000 passen aber nicht, jedenfalls nicht in einen uint8_t ;-)

Die nicht.
Aber das wird ja auch nicht so bleiben :-)

eins nach dem anderen. Da gibt es noch mehr Probleme.

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.