mikrocontroller.net

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


Autor: Andreas Kramer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)

Autor: Tommy (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

Grüße
Tommy

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Kramer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/... Seite 26
müsste das doch ein externer Quarz sein ( macht das einen Unterschied
wenn das ein Quarzoszillator ist ? ).

Autor: Andreas Kramer (Gast)
Datum:

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

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
}

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Kramer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Kramer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.