Hallo,
ich bin absoluter MikroController-Einsteiger und möchte nun meine erste
kleine Steuerungsaufgabe lösen:
PB0 soll für ca. 1 Stunde auf "logisch 1" sein, dann für ca. 15 Sekunden
auf "logisch 0" sein, dann wieder für ca. 1 Stunde auf "logisch 1" und
sofort (periodisch fortgesetzt). Dazu brauche ich irgendwie einen Timer
für 1 Stunde und für 15 Sekunden, alles +- 20%, also nur ungefähr.
Als Quarz nehme ich den internen mit 1MHz.
Kann mir jemand einen Assembler Code-Schnipsel mit
- Timer Initialisierung
- Schleifen für die zwei Zeiten
kurz schreiben? Im AVR Tutorial und im Netz hab ich mich schon
erkundigt, jedoch nichts brauchbares für dieses (ich denke) einfache
Problem gefunden.
Ich wäre wirklich riesig erfreut, wenn jemand einen
Assembler-Code-Schnipsel (ohne drum herum) schreiben könnte, oder mir
einen Link sagen könnte.
Vielen Dank schon einmal für unterstützende Hilfen.
Gruß
Jan Purrucker
(aus dem Schwaben-Ländle)
ldi r16, 0b00000101 ;clk/1024 -> 1,024mSec Periode
3
out TCCR0, r16
4
ldi r16, 0b00000010 ; enable overflow irq
5
out TIMSK, r16
6
clr r16 ; reset counter
7
out TCNT0, r16
Damit kommt der Overflow Irq alle 0.262144 Sec.
Dann must du im IRQ nur noch feststellen welcher der beiden
Zeiten laufen soll und dementsprechend von
0 bis 3600Sec/0.262144 Sec = 13733 oder
0 bis 15Sec/0.262144 Sec = 57 zählen.
Wenn der zähler seinen wert erreicht hat zurücksetzen, port
umschalten und in einem Register speichern das jetzt der andere
Zähler dran ist.
als Hauptprogramm braucht du dann nur noch eine endlosschleife, ggf
mit einem sleep befehl drin
btw: die internen Taktgeneratoren der AVRs sind keine Quarze sondern
RC-glieder! Du solltest dir also mal die sache mit dem OSCCAL ansehen...
Danke für die Hilfe!
Du hast Recht, es ist ein RC Glied der interne Takt. Der ist relative
ungenau. Aber ich brauche die Zeiten wie gesagt nur ungefähr so genau,
daher brauche ich auch kein OSCCAL, sondern muß nur die Fuse-Bits
entsprechend auf den internen Oszillator einstellen.
Die Entscheidung, ob ich bis 57 oder 13733 zähle mache ich dann, indem
ich den Status des PB0 abfrage.
Ich versuch mich mal demnächst, und frage hier wieder, sollte was nicht
funktionieren.
Vielen Dank nochmals für die Hilfe.
Gruß
Jan
Das ist sehr einfach zu machen. Du brauchst nur zwei ineinander
verschachtelte Software-Teiler. Der eine teilt durch 57 (von 0.262144 s
auf 14.9422 s), der zweite von 14.9422 s auf ca. 1 h). Nach dem
Zählerstand des zweiten schaltest Du den Portpin: "High" wenn
Zählerstand = 0, "Low" wenn Zählerstand = 1, 2, 3 ... 239. Das ist
alles.
1
TOOverflowInterrupt:
2
3
// wird alle 0.262144 s durchlaufen
4
5
inck
6
IF(k=57)
7
{
8
// wird alle 57*0.262144 s = 14.9422 s durchlaufen
Hallo AVRFan,
vielen Dank für die nette Erklärung. Nur möchte ich jetzt erst einmal
Assembler lernen. Könntest du (oder irgendwer hier) mir deshalb bitte
diese Schleife in Assembler kurz schreiben. Kann nämlich mit C nicht
viel anfangen. Hab auch schon überlegt wie ich es in Assembler mache,
aber bin nicht drauf gekommen. Also wenn mir hier jemand weiterhelfen
könnte wäre ich wirklich riesig dankbar.
Gruß
Jan Purrucker