Hallo, ich bin Neuling auf dem Gebiet der AVR-Programmierung und möchte mich jetzt ein wenig mit Timern beschäftigen (XMega128A1, STK600, C). Ich hab aber leider keine Ahnung wie ich die Dinger ans laufen kriege. Ich weis nur soviel: 1. Timer initialisieren 2. Prescaler festlegen 3. irgendwie die Interrupts festlegen und freigeben Aber wie lauten die entsprechenden Befehle bzw. wo kann man die nachlesen. Aus den Atmel unterlagen werde ich leider nicht schlau. Gruß Alex B.
Ich kenn mich zwar mit den xmega noch nicht aus, aber schau doch mal auf Seit 134 im Datenblatt. http://www.atmel.com/dyn/resources/prod_documents/doc8077.pdf
Alex B. wrote: > Aber wie lauten die entsprechenden Befehle bzw. wo kann man die > nachlesen. Der Befehl lautet "=", also
1 | Register_x = Wert_y; |
Was wo zugewiesen werden muß, steht im Datenblatt.
> Aus den Atmel unterlagen werde ich leider nicht schlau.
Wenn man sich in Datenblättern nicht zurecht findet, dann ist es äußerst
unklug, nen brandneuen Chip zu nehmen, den so gut wie keiner benutzt.
Wo kriegt man den denn überhaupt zu kaufen, außer auf dem STK600-Board?
Ich benutze grundsätzlich Chips immer erst, wenn sie auch gut verfügbar
sind (mehrere Anbieter und Lagerware).
Als Anfänger hätte ich zuerst mal geguckt, welche Chips in den
entsprechenden Foren gerne genommen werden.
Hier z.B. werden der ATmega8 oder ATmega168 häufig benutzt.
Peter
Kann denn Dein Compiler überhaupt schon mit dem XMega umgehen? Desweiteren mußt Du dem XMega erstmal einen gültigen Takt zuweisen, da er sonst intern mit 2Mhz läuft. Diese Zuweisung muß per Software erfolgen und ist mittels bestimmter Timings und Befehlsabfolgen gesichert. Wie man das macht, steht im Datenblatt und im Manual. Du brauchst zwingend beide Dokumente.
Leider konnte ich mir den Controller nicht selbst aussuchen, sondern ich hab die Hardware zur Verfügung gestellt bekommen. Und richtig, ich glaub den Chip gibts bisher nur mit dem STK600 zu kaufen, welches auch hier neben meiner Tastatur liegt. Zum Programmieren benutze ich AVR Studio 4, und der dort enthaltene Compiler kennt auch schon den XMega128A1. Hab auch schon ein kleines Programm zum laufen bekommen, mit welchem man die LEDS mittels der Taster einschalten kann. Taktfrequenz ist auch eingestellt (32MHz). Ich weis dass meine Frage hier leider sehr unkonkret ist, aber da ich leider recht wenig Ahnung von AVRs habe, ist es schwierig bessere Fragen zu stellen. Trotzdem aber herzlichen Danke für eure Mühe und eure Hilfe. Gruß Alex
1 | void InitCounter() |
2 | {
|
3 | TCC0_CTRLA = 0x05; //Vorteiler auf 64 stellen |
4 | TCC0_INTCTRLA = 0x03; //Interrupt Level High |
5 | TCC0_PER = 0x09C4; //2500 -> bei 16MHZ 10ms //TOP-Value auf 2500 -> Überlauf alle 10ms |
6 | }
|
Das wars schon... und es ist wohl alles im Datenblatt enthalten schau dir einfach die Registerbeschreibung im Timer Kapitel an und du wirst alles finden was du für diene Zwecke abändern musst Die Interruptroutine musst du natürlich auch noch schreiben
heinz wrote:
>
1 | > TCC0_PER = 0x09C4; //2500 |
2 | >
|
Und warum schreibste nicht gleich
1 | TCC0_PER = 2500; |
Dann sparste nämlich den Kommentar. Ich vermute allerdings, daß
1 | TCC0_PER = 2500-1; |
richtig ist. Peter
ja das liegt wohl daran dass ich mir in der assembler programmierung irgendwie angewöhnt hatte alles mit hexwerten zu machen obwohl es auch anders geht und ich das irgendwie jetz noch drin hab... jep 2500-1 ist richtig das war irgendwas schnell zusammenprogramiertes um den xmega zu testen als ich mit seiner programmierung begonnen hab da gings nicht um jede µs ;)
OK, danke dafür. Wenn ich das jetzt richtig verstehe, wird jetzt immer bei Timerüberlauf das OVFIF (Bit0) in Register INTFLAGS gesetzt. Mittels dieses Flags müsste man dann jetzt also eine Interrupt-Routine starten, in der man dann was nettes macht, oder?
dann wärs keine Interrupt Routine ;) Dann mal grundlegend: 1. Du musst die Interrupts freigeben(z.B. alle Levels geht mit dem Register PMIC.CTRL=0x07) 2. Globale Interrupts freigeben geht beim IAR-Compiter mit __enable_interrupt() weiß ja net welchen du benutzt musst du ggf nachschauen 3. Interrupt Routine schreiben geht beim IAR so: #pragma vector=USARTC0_RXC_vect __interrupt void RXC0interrupt(void) { **Was du machen willst** } wie das bei andern Compilern geht weiß ich net hab leider noch nichts andres verwendet als den IAR aber sollte irgendwo beschrieben sein
kann ich leider nichts zu sagen an deiner stelle würde ich ins tutorial dieser seite schauen da steht bestimmt was über interrupts...
Also ich hab jetzt folgendes: #include <avr/interrupt.h> uint8_t temp; void InitCounter( void ); int main(void) { sei(); PMIC.CTRL=0x07; InitCounter(); while(1) { } } void InitCounter() { TCC0_CTRLA = 0x05; TCC0_INTCTRLA = 0x03; TCC0_PER = 0x09C4; } ISR (Timer0_OVF_vect) { temp++; } Aber irgendwie wird die Variable temp nicht hochgezählte...
wie testest du das? außerdem: dein xmega läuft standardmäßig mit 2Mhz internem Takt, d.h. du hast alle 80ms den Überlauf
Aktuell teste ich mit dem AVR Simulator2 aus AVR Studio 4. Ob der Prozessor mit 2MHz oder irgendwie anders läuft ist mir vorerst mal egal, trotzdem danke für den Hinweis. Mich würde es halt schon freuen, wenn die ISR ausgeführt würde.
lass doch einfach mal in deiner Interrupt routine eine Led auf dem Board angehen und beim nächsten aufruf wieder ausmachen usw vll ists ja was mit dem simulator ich teste sowas lieber direkt auf der hardware mit z.B. leds blinken lassen...
Ich hab das dann jetzt wie folgt geändert: #include <avr/io.h> #include <avr/interrupt.h> uint8_t temp; void InitCounter( void ); int main(void) { sei(); PMIC.CTRL=0x07; InitCounter(); PORTA.DIR = 0xFF; PORTA.OUT = 0xFF; while(1) { } } void InitCounter() { TCC0_CTRLA = 0x05; TCC0_INTCTRLA = 0x03; TCC0_PER = 0x09C4; } ISR (Timer0_OVF_vect) { PORTA.OUT = ~PORTA.OUT; } Aber da tut sich nicht viel :-(
Ich verstehe aber auch noch nicht so wirklich was es mit: sei() und PMIC.CTRL=0x07 so auf sich hat. Beides ist doch für das freischalten der Interrupts zuständig, ist dann nicht eins von beidem überflüssig?
Ich werd wahnsinnig, es geht, es geht... Und ich hatte das eben auch schon mal so geändert gehabt, aber da lief es nicht und dachte deshalb das doch Timer0_OVF_vect richtig wäre, aber da lags wahrscheinlich an dem AVR Simulator. Danke euch allen für eure schnelle Hilfe!
nein es ist keines überflüssig mit sei() aktivierst du global interrupts zusätzlich muss bei den xmegas aber auch noch jeder interrupt level "freigeschalten" werden mit 0x07 werden alle 3 level freigeschalten.
es lag nicht an dem Simulator, sondern in deiner Vorgängerversion hat der Compiler dir einfach die Variable temp wegoptimiert, weil sie unnütz war (und nicht volatile deklariert!)
Also kann ich mit volatile eine Variable vor Weg-Optimierung schützen. Hat dieses Schlüsselwort sonst noch eine Bedeutung? Sollte man daher Variablen in ISRs immer als volatile deklarieren, sowas hab ich glaube ich vor kurzem mal hier in irgendnem Thread gelesen.
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.