Timer XMega128A1

Gast #994775
Lesenswert?

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.
#994790
Lesenswert?

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
(Firma: TravelRec.) Persönliche Seite #994791
Lesenswert?

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.
Gast #994793
Lesenswert?

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
Gast #994805
Lesenswert?

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
Gast #994827
Lesenswert?

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 ;)
Gast #994937
Lesenswert?

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?
Gast #994958
Lesenswert?

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
Gast #995135
Lesenswert?

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...
Gast #995154
Lesenswert?

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.
Gast #995159
Lesenswert?

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...
Gast #995191
Lesenswert?

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 :-(
Gast #995216
Lesenswert?

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?
Gast #995231
Lesenswert?

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!
Gast #995302
Lesenswert?

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.
Gast #995356
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren