Hallo zusammen, ich würde fürs erste einfach mal gern ein Rechtecksignal am OCR1 Pin erzeugen. Das würde ich gerne mit einem 16-Bit Timer realisieren. Dazu verwende ich einen ATmega16 und einen Quarz mit 16Mhz. Meine Frage: Lege ich die ganzen Register vor der main() fest? Oder im main-Programm in einer while(1) Schleife? Ich verstehe nicht so ganz, wenn ein Interrupt ausgelöst wird, wo das Programm nach Ausführung des Interrupts weitermacht. Ich habe es so geschrieben: main(){ /*Soll bis 20ms zählen und einen Interrupt auslösen */ TCCR1A |= (1<<OC1A); //Toggle-Modus TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<CTC1); // 16MHz => T = 62.5 ns // Mit Vorteiler mit 16Mhz / 1024 // 62.5 ns 1024 312.5 = 20 ms => Vergleichsregister OCR1 auf 313 setzen! // CTC1 gesetzt, d.h. bei Übereinstimmung von TCNT1 und OCR1 wird TCNT1 wieder 0 gesetzt while(1) { TCNT1H = 0x00; TCNT1L = 0x00; //Zählregister auf 0 gesetzt OCR1AH = 0x01; OCR1AL = 0x39; // OCR1A Register wird auf (313)d = (0x139)hex gesetzt sei(); } }
Jürgen Hems wrote: > Lege ich die ganzen Register vor der main() fest? Du initialisiert die Peripherie am Anfang des Main. > Oder im main-Programm in einer while(1) Schleife? Das ist Quatsch mit Soße. Wenn Du den Timer in ner Schleife ständig rücksetzt, wie soll der dann zählen? > Ich verstehe nicht so ganz, wenn ein Interrupt ausgelöst wird, wo das > Programm nach Ausführung des Interrupts weitermacht. Genau an der gleichen Stelle, das ist ja der Sinn eines Interrupts. Das Hauptprogramm merkt den Interrupt nicht. Peter
Wie Du es geschrieben hast macht es Sinn. Nach dem Aufstrarten springt die CPU (per Aufstratcode) ins Main. Dann werden Dinge erledigt die nur einmal gemacht werden müssen wie Register und Variabeln initialisieren. In der while(1) Schleife ist dann das Hauptprogramm. Wurde eine Interruptserviceroutine abgearbeitet, macht der Controller dort weiter, wo er zuvor unterbrochen wurde. Es gehen also keine Operationen verloren.
>TCCR1A |= (1<<OC1A); //Toggle-Modus > >ich würde fürs erste einfach mal gern ein Rechtecksignal am OCR1 Pin >erzeugen. OK, aber wenn Du das über diesen Toggle-Modus realisierst, dann erledigt die Timerhardware die Signalerzeugung völlig autonom. Daran ist kein Interrupt beteiligt! Register setzen - leere Hauptschleife - am OCR-Pin Signal abgreifen. Ein Interrupt kommt nirgendwo in Deinem Programm vor. Sobald das funktioniert, kannst Du dann die "andere Methode" versuchen, nämlich das Signal über ein explizites, d. h. durch entsprechenden Programmcode bewirktes Pintogglen in einem Timerinterrupt ("Compare Match") zu erzeugen.
Ja, aber für alle bisher beschriebenen Möglichkeiten sollte die while(1)-Schleife leer sein. Und das ist sie nicht.
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.