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]
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.
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 | }
|
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
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 :-).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.