Ich habe bis jetzt meine AVR´s immer mit Bascomavr Programmiert. Nun möchte ich auch C lernen. Da ich programmir Anfänger bin. Möchte ich erstmal so einfache Sachen machen wie z.B.: eine LED Blinken lassen. Nun stand ich vor dem Problem das es in C den Befehl wait 5 --> also 5 Sekunden warten nicht gibt. Erst habe ich versucht das ganze mit _delay_ms(5000)zu lösen. Dies funktioniert natürlich nicht. (maximal mögliche Delay-Zeit: 262,14ms/F_CPU in MHz z.B.: Bei 8Mhz = 32,77ms--Bei ´4Mhz ca. 65) Also habe ich eine Funktion geschrieben (wait) , welche als Parameter die Wartezeit übernimmt und dann in einer Schleife, solange _delay_ms ausführt bis die gwünschte Pausenzeit erreicht ist. Ich Poste dies , weil ich im Forum nicht vergleichbares gefunden habe. Nur Kluge Ratschläge, man macht so etwas mit Timern. Das mag wol richtig sein, aber gerade für Anfänger(wie ich), sind Timer recht schwer zu verstehen. Auserdem, braucht man bei einer Schaltung wo zum Beispiel ein Relais blinken soll, keine anderen Sachen gleichzeitig ausführen. Ich find für alle Anfänger ist dies ein guter Einstieg.
Michael, das ist die korrekte Methode um laaaange delays in C zu basteln. Der Grund, warum die glibc nur so 'kurze' delays ermoeglichst, ist die Tatsache, dass in fast allen Faellen ein solches delay die schlechteste aller moeglichen Loesungen darstellt weil nur sinnlos processor power verbraten wird.
Die Timer sind so schwer zu verstehen, weil sie (bei den neueren AVRs) so viele Features haben und daher das Kapitel "Timer" im Datenblatt etwas langatmig geschrieben ist. Um die Grundfunktionen zu verstehen, lohnt es sich, mal das Datenblatt vom AT90S2313 oder AT90S8515 vorzukramen und sich den Aufbau des Timers anzusehen. Auch eine Simulation in AVR-Studio kann zeigen, wie der Timer funktioniert. Dazu benötigt man zwar etwas Assembler, das ist aber viel einfacher als allgemein angenommen. Mit Datenblatt, Instruction-Set und Onlinehilfe des AVR-Studios kommt man schnell zu einem sichtbaren Ergebnis. Das Verwenden langer Delay-Schleifen blockiert den MC für andere Arbeiten. Sowas macht man nicht, solche Programme lassen sich nicht erweitern, sie haben keine Rechenzeitreserven. Mein Tip: Versuche Assembler zu lernen und richte dich nach dem Datenblatt. Dort sind alle I/O-Register und die Funktionen ihrer Bits genau erklärt. Für kleinere Programme direkt an der Hardware ist ASM sogar einfacher als eine Hochsprache. ...
Hab mich inzwischen ein bischen mit den Timern befast. Hatte das Problem das ich mit den obrigen Progamm meine Uhr nicht nebenbei Laufen lassen kann, wärend das Programm z.B.: die DCF Zeit ausliest.Inzwischen habe ich begriffen das Programme mit Pausen schlecht sind. Wärend der Pause kann man einfach nichts anders mehr machen. Aber wie gesagt, für die allerersten Schritte ist das obrige Programm ein guter Einstieg. Hier die elegantere Methote: Das ganze hab ich auf einem AT 90S8515 getestet. Müste aber im Prinzip auf jeden Typ laufen. (Timer anpassen) int main(void) { TCCR1B = (1<<CS10) | (1<<CS11); //setzt den Prescaler 64 OCR1A = 62500; //setzt den Vergleichswert TCNT1 = 0; //startewert des Counters TIMSK = 1<<OCIE1A; //Compare-Int aktivieren sei(); //globale Ints aktivieren } SIGNAL (SIG_OUTPUT_COMPARE1A) { //wird ausgeführt wenn der Counterwert mit dem Vergleichswert übereinstimmt // Uhrenroutine s++; // s jede Sekunde um 1 erhöhen TCNT1 = 0; //timer 1 auf null for (;;) {Programm} } OCR1A = 62500; errechnet mit der Formel: OutpurCompare = Fosc/prescaler * Tsoll z.B.: OCR1A = 4000000Mhz/64 * 1 = 62500
Ein Timer kann mehrere Dinge zugleich erledigen... Z.B. für die Uhr: Timer-Interrupt alle 10ms (Hundertstel Sekunden) In der ISR: - Hundertstel Sekunde hochzählen, bei Erreichen von 100 wieder löschen und ein Flag für das Hauptprogramm setzen, dass eine neue Sekunde begonnen hat, worauf das Hauptprogramm bei nächster Gelegenheit die Sekunde und ggf. Minute, Stunde, Wochentag, Tag, Monat, Jahr, Jahrhundert... aktualisiert. - Bei aktivem DCF-Empfang den DCF-Eingang pollen, also abfragen und die Impuls-Zeiten (in Hundertstel Sekunden) registrieren, um das DCF-Signal zu decodieren. - Die Bedienungstasten der Uhr abfragen und entprellen, hier bietet sich sogar an, das DCF-Signal mit zu entprellen und die Auswertung im Hauptprogramm zu machen. - Die LCD-Ausgabe (via Ringbuffer) zu synchronisieren, für eine einfache Uhr genügen 100 Zeichen pro Sekunde, so schnell kann eh niemand lesen. - Beim Hundertstelsekundenstand von 50 ein Flag setzen, damit das Hauptprogramm den Doppelpunkt der Zeitanzeige wieder mit einem Leerzeichen überschreibt, damit das wie Blinken aussieht. - Im Weckbetrieb den Piepser toren, da ein periodischer Piepser viel besser weckt als ein Dauerpiep. Und das alles in einem einzigen Timer-Interrupt alle 10000 Takte, falls der AVR mit 1MHz läuft... Deinen C-Code habe ich mir nicht angesehen, ich schreibe in ASM. ...
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.