Forum: Mikrocontroller und Digitale Elektronik Timer ATXMega initialisieren


von Jan-Henrik B. (vedaykin)


Lesenswert?

Hallo Forum,

in diversen Beiträgen konnte ich Hilfe zu diesem Thema finden, jedoch 
wurde am Schluss empfohlen einen neuen Beitrag zu öffnen, da diese älter 
als 6 Monate sind. Ich fange gerade an mit der uPc-Programmierung und 
habe die folgende Lösung unten zusammenkopiert und versucht alle 
Einzelteile nachzuvollziehen.

Prinzipiell funktioniert diese Code schonmal auf dem ATXMega256 in 
Verbindung mit dem STK600. Ich würde ganz gerne am Schluss ein 
Zeitsignal mit 20kHz abtasten und weiterverarbeiten. Als ersten Schritt 
dachte ich wäre es sinnvoll eine ISR mit 20kHz auszulösen. Der an einem 
Port erfasste Wert kann dann an das Hauptprogramm gegeben werden, 
abgespeichert und eventuell in einer Integration weiterverarbeitet 
werden. Soviel zur Problemstellung ;).

Meine Frage nun lautet, ob der unten gezeigte Code grobe strukturelle 
Fehler aufweist. Da ich neu bin hier muss ich zugeben, dass es mir schon 
nach ganz schön viel Code aussieht, dafür das ich nur einen Port mit 
20kHz toggle. Habe ich hier ein wenig zu kompliziert gedacht und ein 
alter C-Hase kann mir das auf 1-3 Zeilen zusammenstreichen?

Ich habe versucht den Code kurz zu dokumentieren. Besonders Probleme 
macht mir die Zeile CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc 
); Wurde die Clock nicht schon selektiert und gestartet? Wenn ich die 
Zeile rausnehme funzt es nicht mehr, daher scheint hier was wichtiges zu 
passieren ;). Ich bin für jeden hilfreichen Tipp dankbar.

[c]
#include <avr/io.h>
#include <avr/interrupt.h>
#include <clksys_driver.h>

int main( void )
{
  //Port D als Ausgang definieren
  PORTD.DIR = 0xff;

  //32MHz Oszillator laden
  OSC.CTRL = OSC_RC32MEN_bm;
  //Vorteiler definieren
  CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
  //Warten bis Oszillator eingeschwungen ist
  do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
  //Muss hier nochmal der Oszillator selektiert werden???
  CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );

  //Counter zählt bis 25
  TCC0.PER = 25;
  //Jeder 64te Takt wird gezahlt.
  TCC0.CTRLA = TC_CLKSEL_DIV64_gc;
  //Irgendwie wird hier der Overflow Flag der ISR intitialisiert
  TCC0.INTCTRLA = (TCC0.INTCTRLA & ~TC0_OVFINTLVL_gm)| 
TC_OVFINTLVL_MED_gc;

  //Priorität des Interrupts festlegen
  PMIC.CTRL |= PMIC_MEDLVLEN_bm;
  //Interrupts global zulassen.
  sei();

  while(1){
  }
}

ISR(TCC0_OVF_vect)
{
  //Togglefrequenz = 32000000/(25*64) = 20000kHz
  PORTD.OUTTGL = 0xff;
}
[\c]

von Jan-Henrik B. (vedaykin)


Lesenswert?

Achso, hier noch der Link wo es die Bibliothek clksys_driver.h gibt:

http://www.atmel.com/products/microcontrollers/avr/AVR_XMEGA.aspx?tab=documents

Ich habe mich am Beispielcode: AVR1003 orientiert. Am Schluss habe ich 
was von 20000kHz geschrieben... ich meinte 20kHz natürlich.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Was für ein XMega256 ist denn das? Es gibt einige, die so heissen 
(A1,A3,D1,usw.).
Hier ist mal eine 32 Mhz Initialisierung für die A1 und A3 ohne Library 
Benutzung:
1
// Configure XMega Clock 
2
// clock system @ 32Mhz , PERCLK is 16 Mhz
3
void ConfigClockSystem( void )
4
{
5
  /* Start internal 32MHz RC oscillator. */
6
  OSC.CTRL = OSC_RC32MEN_bm;
7
  do {
8
    /* Wait while oscillator stabilizes. */
9
  } while ( ( OSC.STATUS & OSC_RC32MRDY_bm ) == 0 );
10
  /* Enable prescaler A div by 1 and B and C to div by 2 */
11
  CCP = CCP_IOREG_gc;
12
  CLK.PSCTRL = (CLK_PSADIV_1_gc | CLK_PSBCDIV_1_2_gc);
13
14
  /* Select 32 MHz as master clock. */
15
  CCP = CCP_IOREG_gc;
16
  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
17
}

von Jan-Henrik B. (vedaykin)


Lesenswert?

Guten Morgen Mathias,

danke für die Antwort und sorry für die späte Rückmeldung, ich war übers 
WE nicht im Labor. Zuerst, Dein Code funktioniert und sieht auch 
wesentlich strukturierter aus, wie Du wahrscheinlich schon vorher 
wusstest ;). Ich habe ihn auf einen ATXMega256A3 hochgeladen.

Jetzt kommt eher eine grundsätzliche Frage zum Programmieren des 
ATXMegas. Du verwendest einfach den Befehl: CCP = CCP_IOREG_gc; Ich habe 
solche Zeilen schon öfter gesehen und frage mich, woher weisst Du, dass 
der Befehl "CCP_IOREG_gc" heißt? Beziehungsweise laut Doku-Tabele auf 
Seite 15 Abschnitt "CCP – Configuration Change Protection register" kann 
ich sehen, dass im Register CCP "IOREG = 0xD8 = Protected IO Register" 
bedeutet. Woher kommt das "CCP_" und abschließende "_gc" in Deiner 
Befehlszeile?

Nachträglich kann ich rausfinden, dass in der iox256a3.h die Signaturen 
so definiert sind. Muss ich für jedes Register die vordefinierten 
Signaturen rausfinden/suchen, oder steht das irgendwo in der Doku und 
ich habe es nur noch nicht gefunden?

Grüße,

Jan

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Die '_gc' Muster sind eigentlich nur Vereinfachungen, um sich nicht 
jedesmal die 'Group Configuration' Bits merken zu müssen und diese sind 
deswegen in den iox___.h Includes so definiert. Die Bitmuster 
entsprechen dann denen aus dem Datenblatt. Im Datenblatt bist du 
bestimmt auch schon auf 'Group Configuration' gestossen.
Du wirst auch öfter auf '__bm' Muster stossen, das sind Bitmasken.

CCP ist, wie du schon herausgefunden hast, das Configuration Change 
Protection Register und dieses muss 'entriegelt' werden, bevor man an 
solch vitalen Sachen wie dem Master Clock oder den Vorteilern 
rumfummelt. In C ist es deswegen auch wichtig, die Optimierung 
einzuschalten, da die 'Entriegelung' nur für einige Clockzyklen wirkt.
In AVR Studio 4 stellst du also am besten in den 'Projekt->Configuration 
Options' die Optimierung auf '-Os'

Jan-Henrik Bathelt schrieb:
> Muss ich für jedes Register die vordefinierten
> Signaturen rausfinden/suchen, oder steht das irgendwo in der Doku und
> ich habe es nur noch nicht gefunden?

Wenn ich ein neues Register programmieren muss, habe ich immer die für 
den Prozessor passende iox__.h in einem Texteditor offen und schau dort, 
was definiert ist. Ich lerne am besten durch vorhandene Beispiele, und 
fummel mir dann die Sachen raus, für die es keine gibt :-).

von Jan-Henrik B. (vedaykin)


Lesenswert?

Tja, was soll ich sagen, ich glaube der Thread ist damit abgeschlossen. 
Vielen Dank Mathias für die zügige Unterstützung, ich bin nun definitiv 
schlauer als vor 5 Minuten.

Grüße,

Jan

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
Noch kein Account? Hier anmelden.