Forum: Mikrocontroller und Digitale Elektronik Problem bei C code für 8-bit timer Atmega-8


von Andreas Kramer (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab ein Problem mit meinem Code in C für meinen Atmega-8. Eigendlich
soll der 8-bit timer aktiviert werden und das bei einer Clock von 16mhz.
Das Programm soll immer wenn der timer von 0-255-0 gezählt hat eine
16bit-Variable um 1 erhöhen und dann sollte eine LED die an PORTB pin
PB0 angeschlossen ist ausgeschaltet werden wenn die Variable 250*125
(pin auf hight).Das müsste nach meiner Rechnung ( takt/(256*2) ) genau
ne sec sein sein. Dann halt wieder das Gleiche von vorne nur dann am
Ende den pin für die LED wieder auf low. Momentan leuchtet die LED zwar
aber sie will den zustand nicht ändern. Also der Tackt geht da bin ich
sicher das hab ich getestet auch die LED geht nomalerweise also keine
Brücke oder so. Bin leider noch Anfänger aber den Code hab ich selbst
geschrieben.
Danke schon mal für die Hilfe ^^ (Code im Anhang)

von Tommy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Habe den Quelltext überflogen - Ports werden über "PINx" eingelesen.

Grüße
Tommy

von Andreas Kramer (Gast)


Lesenswert?

Eigendlich les ich die nicht ein oder meinst du das in der einen if
Bedingung sonnst setz ich die immer nur und das ging immer wenn ich das
so gemacht hab.

Gruß Andreas

von Tommy (Gast)


Lesenswert?

Hast du folgende Zeile:

if (PORTB==0x00) /* WENN PORT B LOW*/
{
  PORTB=0xff; /* SETZT PORT B AUF HIGHT*/
}

mal gegen:

if (PINB==0x00) PORTB=0xff;

geändert?

von Andreas Kramer (Gast)


Lesenswert?

Ok das hab ich behoben und ich weiß jetzt auch was du meinst ein kleiner
Fehler war noch in meiner Rechnung da war nur eine halbe sec um, aber
leider geht es immer noch nicht die LED leuchtet immer noch dauernd.

Gruß Andreas

von Andreas Kramer (Gast)


Angehängte Dateien:

Lesenswert?

Ok jetzt blinkt es mit dem Code aber irgendwie stimmt die Frequenz nicht
ich muss mich irgendwie vertan haben.

Momentan rechne ich Taktfrequenz/256 also den Counter Wert bis das
Register wieder 0 ist und das Ergebniss zähl ich dann in der 16bit
Variable, aber das blinkt nur etwa mit an 7 sec und aus auch 7 sec
könnten auch 8 sein.

Wo liegt mein Fehler in der Rechnung ?

von Karl H. (kbuchegg)


Lesenswert?

So wird das nichts.
Du fragst in der Schleife ab, ob der Timer den Wert 0 hat.
Nur blöderweise ändert der Timer mit jedem Taktzyklus seinen
Wert um 1. Was ist wenn der Timer genau dann 0 erreicht, wenn
du gerade überprüfst, ob teiler seinen magischen Wert erreicht hat?
Dann kriegst du nicht mit, dass der Timer gerade 0 ist.
Auf Deutsch: Der Timer kriegt den Wert 0, aber dein Programm schaut
zufällig gerade jetzt nicht hin, weil es anderweitig beschäftigt
ist.

Für sowas gibt es Interrupts. Da kriegst du dann auf jeden Fall
mit, dass der Timer einen Overflow von 255 nach 0 hat.

von Andreas Kramer (Gast)


Lesenswert?

Mist 3x Post sry deswegen aber könnte das an meinen Fusebits liegen die
sind momentan auf CKSEL3-0 auf 0 also laut Datenblatt
http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf Seite 26
müsste das doch ein externer Quarz sein ( macht das einen Unterschied
wenn das ein Quarzoszillator ist ? ).

von Andreas Kramer (Gast)


Lesenswert?

Hm ok wie müsste ich denn die Sache ändern damit das ein Interrupt
benutzt.

von Tommy (Gast)


Lesenswert?

(1) Initialisierung

//TIMER2 mit Prescaler=128
//Überlauf alle 1ms
 TCCR2 = 0x00; //Timer stoppen
 TCNT2 = 0x83; //Zählregister mit T=1ms setzen
 TCCR2 = 0x05; //Timer mit Überlauf-Int starten

//Timer-Interrupt freigeben
 TIMSK = 0x40; //timer interrupt sources

//globaler Interrupt freigeben
 sei();

(2) Hauptprogramme
while(1)
{
  Ausertung des Teiler
}

(3)T2-ISR
ISR(TIMER2_OVF_vect)
{
  TCNT2 = 0x83; //Zählregister reloaden
  teiler ++;  //ggf. einen long integer (32Bit) nehmen
}

von Andreas Kramer (Gast)


Lesenswert?

Also danke erstmal ich werde mir das mal länger morgen ansehen ich
versteh das noch nicht ganz wie das mit den krummen Zahlen geht und wie
das zusammenhängt aber ich muss leider jetzt weg ( blöde Schule morgen
^^ )

Nochmal vielen Dank für die Gute und reichliche Hilfe. So ein Forum mit
so schnellen Antworten hab ich echt noch nei gesehen.

Gruß Andreas

von Tommy (Gast)


Lesenswert?

Krumme Zahlen??? Gute und schnelle Hilfe für den Einstief findest im
GCC-Tutorial -dort werden viele Grundlagen besprochen.

In meinen Quelltext-Fragmenten habe ich dir ein long-integer
vorgschlagen, da ich auf die Schnelle nur einen Timer2-Überlauf von 1ms
errechnet habe. Musst einfach mal schauen, wie groß deine Werte sind. Ab
65535 brauchst du einen größeren Wert als unsigned integer.

Gute Nacht und viele Grüße
Tommy

von Andreas Kramer (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab mich mal erfolglos an dem Interrrupt versucht (Code im Anhang), 
aber das geht einfach nicht es wär echt super wenn das irgendjemand mal 
nachsehen könnte und sagen könnte wo der Fehler ist. Ich bin langsam am 
verzweifeln...

Gruß Andreas

von Andreas Kramer (Gast)


Angehängte Dateien:

Lesenswert?

Hat sich gerade erledigt musste nur vor die Variablendeff. ein volatile 
voranstellen ^^
Das könnte man vieleicht irgendwann im avr-gcc tut als Hinweis 
reinschreiben, da ich glaub das der Fehler viele Anfänger heimsucht. Im 
Anhang noch die verbesserte File weil ich mich immer bei Beiträgen ärger 
wo n Fehler den ich auch hab plötzlich erledigt ist ohne zu zeigen wie.

Gruß Andreas

von mr.chip (Gast)


Lesenswert?

Hallo

Das ist klar, dass da nix geht. Da fehlt noch einiges in dieser Zeile:

TCCR2 |= (1<<CS20);

Du stellst lediglich einen Prescaler ein, sagst dem Timer aber nicht, in 
welchem Modus er laufen soll. Das solltest du im Datenblatt eigentlich 
finden.

Gruss

Michael

von Andreas Kramer (Gast)


Lesenswert?

Leider weiß ich grad nicht was du meinst weil momentan läuft das Ding so 
wie es soll und das was ich da hab ist aus dem Datenblatt und aus dem 
AVR-GCC Tutorial zusammengestellt.

Momentan und meines Wissens nach aktiviere ich zuerst den Timeroverflow 
Interrupt dann aktiviere ich die Interrupts allgemein mit sei() und dann 
schalt ich den Timer ohne Prescaler ein. Was habe ich denn da vergessen 
?

Gruß Andreas

von Karl heinz B. (kbucheg)


Lesenswert?

Wahrscheinlich hat Mr. Chip das Setzen des Overflow
Interrupts und den sei() ganz am Anfang übersehen.

Ist auch etwas unüblich. Normalerweise konfiguriert man
zuerst und schaltet erst dann dann die Interrupts ein.

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.