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)
Hallo, Habe den Quelltext überflogen - Ports werden über "PINx" eingelesen. Grüße Tommy
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
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?
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
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 ?
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.
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 ? ).
Hm ok wie müsste ich denn die Sache ändern damit das ein Interrupt benutzt.
(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 }
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
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.