Servus Controller Freaks, Ich will den ADC des ATxmega-Controllers benutzen und verwende den ImageCraft C-Compiler, den ich seit Jahren benutze. Der ADC muß kalibriert werden, es muß dabei irgendwie ein Offset-Wert aus dem Flash ausgelesen werden und in bestimmte ADC-Register geschriebne werden. In meinemm Compiler Handbuch kann ich nichts darüber finden, auch im Internet kein Erfolg. Ich hab auch schon die Demo-Version des Compilers CodeVisionAVR installiert, dieser kann Initialisierungs-Code generieren, leider bei der EVAL-Version den Code für ADC-Kalibrierung des ATxmega. Kann mir jemand bei diesem Problem helfen ?
Wie es mir CodeVisionAVR geht weiß ich jetzt nicht, mit GCC geht es auf jeden Fall so:
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | #include <stddef.h> |
4 | #include <avr/pgmspace.h> |
5 | |
6 | uint8_t ReadCalibrationByte( uint8_t index ){ |
7 | uint8_t result; |
8 | |
9 | /* Load the NVM Command register to read the calibration row. */
|
10 | NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; |
11 | result = pgm_read_byte(index); |
12 | |
13 | /* Clean up NVM Command register. */
|
14 | NVM_CMD = NVM_CMD_NO_OPERATION_gc; |
15 | |
16 | return( result ); |
17 | }
|
18 | |
19 | void ADC_init(){ |
20 | |
21 | //Read factory calibration bytes
|
22 | ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) ); |
23 | ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) ); |
24 | |
25 | // more init
|
26 | //...
|
27 | }
|
:
Bearbeitet durch User
Kann mir einer sagen, wie der Aufruf hierfür aussehen würde? Ich möchte den ADC am xmega16D4 kalibrieren
Peet schrieb: > Kann mir einer sagen, wie der Aufruf hierfür aussehen würde? Ich möchte > den ADC am xmega16D4 kalibrieren Wie oben beschrieben ;)
Du hast recht! :) Sorry habe es übersehen. Allerdings erhalte ich den Fehler: Error expected expression before 'NVM_PROD_SIGNATURES_t' Was stimmt hier nicht??
OK, habe die includes vergessen. Das wäre also geklärt. Dennoch habe ich ein Offset-Problem. Durch die Kalibrierung oben erhalte ich keine Besserung. Bei Ref VCC/1,6 habe ich bis zu 200mV Offset. Woran kann das liegen? Als Grundlage dient mir der ADC-Code (nicht die Kalibrierung weiter unten): https://www.kampis-elektroecke.de/?page_id=1644 ... Allerdings mit 8Bit Auflösung
Arbeitest du beim ADC single ended? Wenn ja dann musst du einen Offset von AREF * 0.05 laut Datenblatt einplanen. Im XMEGA AU Manual auf Seite 353 unter der Rubrik "ADc Singel-Ended Measurement" kannst du das nachlesen.
Wenn du es genauer als den typtischen im Datenblatt angegebenen Offset haben willst musst du es händisch machen, so wie hier beschrieben: http://ww1.microchip.com/downloads/en/AppNotes/00002535A.pdf http://ww1.microchip.com/downloads/en/appnotes/atmel-2559-characterization-and-calibration-of-the-adc-on-an-avr_applicationnote_avr120.pdf
du kannst doch im Messbereich eine Kennlinie aufnehmen für jeden ADC Wert gibt es eine Spannung, normalerweise sollte da die Geradengleichung passen, also passende Wertpaare aussuchen. dann Steigung und Offset ermitteln und als Konstante in den flash mit PROGMEM oder __flash
Joachim B. schrieb: > du kannst doch im Messbereich eine Kennlinie aufnehmen > > für jeden ADC Wert gibt es eine Spannung, normalerweise sollte da die > Geradengleichung passen, also passende Wertpaare aussuchen. > > dann Steigung und Offset ermitteln und als Konstante in den flash mit > PROGMEM oder __flash Warum? Die, während der Produktion des Xmegas festgestellten und einprogrammierten, Kalibrierwerte zu verwenden ist jetzt zu leicht oder zu einfach?
M. K. schrieb: > Warum? Die, während der Produktion des Xmegas festgestellten und > einprogrammierten, Kalibrierwerte zu verwenden ist jetzt zu leicht oder > zu einfach? kann machen wer mag, ich mache das lieber mit meiner Schaltung und angeschlossenen Bauteile, Spannungsteiler o.ä. Mich interessiert aber meist nur ein kleiner Ausschnitt, z.B. VCC oder Ibat in einem kleinen Wertebereich. Es ist ziemlich selten das nichts weiter am ADC Eingang hängt und eine komplette Fehlerrechnung aller Toleranzen mag ich auch nicht.
:
Bearbeitet durch User
Wie gesagt, ich lese immer die Kalibrationsbytes aus bei den Atxmegas. Die Werte stecken da ja schon drin ;)
1 | void ADCA_Cal(void) |
2 | {
|
3 | ADCA.CALL = |
4 | LeseKalibrationsbyte(offsetof(NVM_PROD_SIGNATURES_t, |
5 | ADCACAL0)); |
6 | ADCA.CALH = |
7 | LeseKalibrationsbyte(offsetof(NVM_PROD_SIGNATURES_t, |
8 | ADCACAL1)); |
9 | }
|
10 | |
11 | int LeseKalibrationsbyte(int Index) |
12 | {
|
13 | int result; |
14 | |
15 | NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; |
16 | result = pgm_read_byte(Index); |
17 | NVM_CMD = NVM_CMD_NO_OPERATION_gc; |
18 | return(result); |
19 | }
|
Geht schneller, ist einfacher und genauso genau wie ein manuelles Kalibrieren.
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.