PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATXMega128 System Clock Auswahl funktioniert nicht.



Whassup
18.01.2012, 11:37
Hallo,

ich arbeite mit AVR Studio 5 und dem ATXMega128A1 auf dem STK600. Ich versuche die den System Clock auf internal 32 MHz einzustellen.

Beispielcode gibts dafür ja reichlich im Internet:
OSC.CTRL|=OSC_RC32MEN_bm;
while (!(OSC.STATUS & OSC_RC32MRDY_bm));
CCP=CCP_IOREG_gc;
CLK.CTRL=CLK_SCLKSEL_RC32M_gc;


Die Ausführung der ersten beiden Codezeilen kann ich im IO-View sehen. Bei den letzten beiden Codezeilen passiert gar nichts. Was könnte hierfür das Problem sein?

Danke.

Olle_Filzlaus
21.01.2012, 22:20
Hi,

habe an der selben Stelle auch gehangen. Ist aber recht einfach. Du musst die Compiler Optimierung auf -Os einstellen. Dann gehts auch.

cu Filzlaus

Whassup
23.01.2012, 08:01
Hallo,

danke für den Tip. So funktionierts. Ich habe dann aber den optimierten Assember Code direkt eingefügt, damit ich anschließend die Optimierung wieder fürs debuggen ausschalten kann. Ist schon komisch was der AVR Studio Compiler für einen umfangreichen Code bei ausgeschalteter Optimierung erzeugt.

Gruß Whassup

Olle_Filzlaus
23.01.2012, 08:49
Ich habe dann aber den optimierten Assember Code direkt eingefügt, damit ich anschließend die Optimierung wieder fürs debuggen ausschalten kann.

Da hätte ich jetzt wieder Interesse an einem Tip wie das geht :-) Wo kann man sich den compilierten Quelltext anschauen. Oder schaust du in einem Hex-Editor nach? Und wie füge ich das dann in mein Projekt ein.

Und weil ich dagerade hänge, hast du dich schonmal mit dem ADC auseinander gesetzt. Ist echt grauenhaft das Teil. Bekomme zwar Werte, aber die stehen in keinem Zusammenhang mit der Spannung die anliegt.

cu Arno

oberallgeier
23.01.2012, 10:59
Hi Arno.


... schonmal mit dem ADC auseinander gesetzt. Ist echt grauenhaft das Teil ...Das kann ich so wirklich nicht stehen lassen. Ich habe den ADC z.B. in der Familie m168/m328 genutzt und es geht so prächtig, dass ich meinen Zweirädrer sogar ziemlich simpel balancieren lassen kann (klick zur Demo). (https://www.roboternetz.de/community/threads/43015-Balance-halten?p=411231#post411231)

Vielleicht kannst Du mit dem Code für meine Controller etwas anfangen (nen ~128~ hatte ich noch nie) ? Der Code dient zum Auslesen eines Sharp-Entfernungssensors. Dann schau mal hier:

// ================================================== ============================ =
// === HAUPTProgramm ================================================== ========= =
// Initialisierungen, LED1 kurzblinken als Signal für Programmstart,
// Ausgabe des Identifizierungsstrings per USART
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int main(void)
{ //
....
//
// Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
// A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
....
DDRC = 0b01110000; // PC3 ist ADC3, PC0 .. 6 , kein PC7-Pin bei m168
PORTC = 0b00000111; // Beachte für ADC: PC3 ist ADC-Eingang ##>> OHNE Pullup !!
....
// Dadurch Initialisierung der Anschlüsse für miniD0 auf mega328: - - - - - - - -
// /RESET,PC6 1 A A 28 PC5,(SCL), gLED
// RxD,PD0 2 EU A 27 PC4,(SDA), rLED
// TxD,PD1___3 EU E 26___PC3, ADC0=GP2D120
// SigMot1/ExtINT0,PD2 4 EU EU 25 PC2, SFH 5110, IN irDME 4 Rechts
// SigMot2/ExtINT1,PD3 5 EU EU 24 PC1, SFH 5110, IN irDME 3 Links
// _|-- 3,4 Guz, PD4___6 A EU 23___PC0, SFH 5110, IN irDME 1-2 Mitte
// - - - - - - Belegung Pinne - - - - - - - - -
// XTAL1 PB6___9 EU 20___VCC
// XTAL2 PB7 10 EU EU 19 PB5, SCK, Taster2
// PWM 1,2 uz+Guz,PD5 11 A A 18 PB4, MISO, _|-- 3,4 uz, (Taster1)
// PWM 3,4 uz+Guz,PD6__12 A A 17___PB3, MOSI, Reserve 2
// _|-- 1,2 uz,PD7 13 A A 16 PB2, Servo
// _|-- 1,2 Guz,PB0 14 A A 15 PB1, OC1A = SFH 415, OUT (irDME)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== ============================ =
// ================================================== ============================ =
.....


Es folgen die Module für die ADC-Initialisierung und -Auswertung
/* ================================================== ============================ */
/* === Initialisierung fuer ADC mega168 MIT Interrupt ========================
ADC3/PC3 auf 10 Bit, Wandlung #####>>>>> Interrupt ausgelöst */
void ADC3_10_init_irupt(void) //
{
ADMUX |= (1<<MUX1)|(1<<MUX0); // Wandlung mit ADC3
ADMUX |= (1<<REFS0); // Referenzspannung ist Vcc doc S 256
// sowie https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=287602#287602
ADCSRA |= (1<<ADATE); // Auto Triggering Enable doc S 247 + 257
ADCSRB |= (1<<ADTS1)|(1<<ADTS0); // Triggersource = TC0 CmpA doc S 260
// es wird also mit 1/1220 getriggert ca. 0,82 ms
ADCSRA |= (1<<ADIE); // ADC Interrupt Enable doc S 258
ADCSRA |= (1<<ADEN); // AD Enable
ADCSRA |= (1<<ADSC); // starte gleich die erste Wandlung

adc3_cnt = 0; // ADC-Wert wird x-fach aufaddiert
adc3_tmp = 0; // ADC-x-fach-Speicher
}
/* ================================================== ============================ */

/* ================================================== ============================ */
/* === Nicht unterbrechbare ISR für ADC3 auf Pin 26/PC3/mega168 =============== */
/* Routine übernimmt ADC-Wert und quittiert mit 170 ins Statusbyte. */
ISR(ADC_vect) // _VECTOR(21)
{
adc3_tmp = ADC; // Hole Wert
adc3_sum = adc3_sum + adc3_tmp; // ADC-Werte aufsummieren
adc3_cnt = adc3_cnt + 1; // Hochzählen Counter für ISR-Aufruf

if (adc3_cnt == 4) // Jeden vierten (zwölften!) ISR-Aufruf regeln
rgl_mo_12(); // Aufruf Regeln für mo_12

if (adc3_cnt == 8)
rgl_mo_34(); // Aufruf Regeln für mo_34

if (adc3_cnt >= 12) // Wenn Counter >= x, dann Messwert ausrechnen
{ // Wenn adc3_counter < x, dann keine Aktion
adc3_dat = adc3_sum / 12; // Gemittelten ADC-Wert ausrechnen
adc3_sum = 0; // adc3_sum und Counter rücksetzen
adc3_cnt = 1;
PORTC ^= (1<<PC4); // Zeitmessung: Port PC4 toggeln
// ADCSRA |= (1<<ADSC); // starte die nächste Wandlung
}
}
/* ================================================== ============================ */

/* ================================================== ============================ */
/*### ADCwert für GP2D120 auf ADC3/PC3/Pin26 des ATMega168 z.B. auf m168D-Platine
================================================== ============================== */
// === Abholen des ADC-Wertes (keine Ausgabe, wenn ein neuer da ist?) ==============
// Codeschnippsel, ähnlich 22dzms168-regel-x13.c, eingefügt am 26mai2008 1126
// ##>> DAZU unbedingt notwendig: Internen Pullup auf PC3 ausgeschaltet!! >> main
int GPDist (void) // Auswerten des aktuellen Messwertes mit dem Sharp
{
uint16_t GPDmm = 0, gpdtmp = 0; // Messwert Distanz in mm, temporärer Wert
//
// Verbesserung, siehe hierzu auch Umrechnung im µC-Tabelle-Tool. Der Umrechnungs-
// bezugswert "25600" gilt für eine Vesorgungsspannung von 5,00 V
cli(); // Datenübernahme Interruptgefährdet - 2 Byte
gpdtmp = adc3_dat; // Übernimm Daten
sei(); // Gefahr vorbei
GPDmm = 25600 / gpdtmp;
if (GPDmm > 999)
GPDmm = 999;
if (GPDmm < 0 )
GPDmm = 0;

return GPDmm;
}
// === Ende Abholen des ADC-Wertes und Ausgabe ===================================
/* ================================================== ============================ */

Olle_Filzlaus
23.01.2012, 12:03
oberallgeier: ... den ADC z.B. in der Familie m168/m328 genutzt ...

Hallo oberallgeier,

jetzt stehe ich gerade auf dem Schlauch :-) Bei Atmel haben ich keine Xmega 168 bzw. 328 gesehen. Falls du dich auf Atmega 168 bzw 328 beziehst, gebe ich dir Recht. Die gehen prima. Ich nutze selbst einen Atmega328P (3,3V).

Aber wenn man z.B bei den größeren Suchmaschinene wegen "ADC & Xmega" sucht, bekommt man meisten solche Antworten wie: Geht nicht, geht scheiße, ...
So wie ich das mitbekommen habe, gabs auch in den ersten Versionen dieses Chips ein Hardwarefehler im ADC. Habe aber ne Version wo es schon gehen sollte. Aber das geht trotzdem nicht.

Und da habe ich noch nichtmal die ganzen Korrektursachen drin. Ich will erstmal nur ein einfachen Wert einlesen. Weil man ja jetzt auch den Fabrikkalibrierfaktor auslesen kann und das muss man dann noch abziehen. Ausserdem misst der ja jetzt bis -0,2V. also liegt der 0V ADC-Wert bei ca. 200. Ich bekomme Werte die so um die 0-255 liegen. Messe auch erstmal nur 8bit Werte. 12Bit Werte kommen später wenns geht. Weil der Fehler laut Inet nur im 12Bit Teil vorkommt.

cu Arno

Whassup
23.01.2012, 15:59
Hallo Arno,

den Assembler Code habe ich mir aus der Disassembly-Anzeige kopiert. Aus dem C-Code "CLK.CTRL = CLK_SCLKSEL_XOSC_gc;" wird dann in der optimierten Form
asm ("LDI R24, 0x03" ::);
asm ("STS 0x0040, R24" ::);
Dauert also nur 2 Taktzyklen und das Register ist ja 4 Taktzyklen geöffnet. (Bei deaktivierte Optimierung stehen dort 5 Assembler-Befehle und das war einer zu viel :-( und darum gehts nicht)

Wobei asm(" "::); die Methodik ist, den Assembler-Code in den C-Code zu integrieren.

Den ADC habe ich noch nicht ausprobiert...will ich aber bald mal tun. Ich meld mich nochmal.

Gruß
Whassup