-
        

Ergebnis 1 bis 9 von 9

Thema: XMega ADC arbeitet nicht korrekt

  1. #1
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9

    XMega ADC arbeitet nicht korrekt

    Anzeige

    Hallo Forum,

    ich programmiere gerade etwas an einem XMega rum und will mit dem ADC eine Spannung messen und diese Spannung über den UART ausgeben.
    Der UART funktioniert problemlos, nur der ADC macht ein paar Probleme.
    Er gibt nicht das richtige Ergebnis raus. Als Spannungsquelle habe ich ein Labornetzteil genommen und der ADC sollte ja dann bei einer Spannung von 3,3V den maximalen Wert ausgeben, was er aber nicht tut. Stattdessen gibt er den Wert 3 raus.
    Den höchsten Wert (131) habe ich bei einer Spannung von 1,5V.
    Wo habe ich einen Fehler gemacht?
    Ich finde ihn nicht....

    Code:
    #define CPU_SPEED 32000000																			
    #define BAUDRATE    100000																				
    #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)														
    #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE) 
    
    
    // Lese- und Schreibadresse vom EEPROM
    #define EEPROM_W_Adresse 0xA0;
    #define EEPROM_R_Adresse 0xA1;
    
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <string.h>
    #include <stddef.h>		
    #include <avr/pgmspace.h>				
    #include <stdlib.h>
    												
    
    
    
    
    // Peripherie
    unsigned char ADCA_Conversion(char Channel);
    void DACB_Conversion(int Voltage);
    int LeseKalibrationsbyte(int Index);
    
    
    // Variablen
    volatile int ADC_Value = 0x00;
    volatile int Voltage = 0x00;
    volatile int Compare = 0x6000;
    volatile int ADC_Calibrationbyte;																			
    volatile int Zaehler = 1;
    char Text[50] = "Interrupt!";																					
    
    
    int main(void)
    {	
    	Clock_init();	
    	PLL_init();		
    	//RTC_init();			
    	//RTC_config();	
    	Int_init();			
    	DACB_Cal();			
    	DACB_init();		
    	ADCA_Cal();			
    	ADCA_init();		
    	TimerC0_init();		
    	TimerF0_init();		
    	Port_init();		
    	UART_init()				
    	DMA_init();																							TWIF_init();
    
        	while(1)
        	{
    	}	
    }
    
    
    int LeseKalibrationsbyte(int Index)
    {
        int result;
    
    
        NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;					
        result = pgm_read_byte(Index);								
        NVM_CMD = NVM_CMD_NO_OPERATION_gc;
        return(result); 
    }
    
    void ADCA_init()
    {
    	ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;	
    	ADCA.REFCTRL = ADC_REFSEL_AREFA_gc;		
    	ADCA.CTRLA = ADC_ENABLE_bm;		
    }
    
    void Clock_init(void)
    {	
    	OSC.CTRL |= OSC_RC32MEN_bm;			
    	while(!(OSC.STATUS & OSC_RC32MEN_bm));		
    	CCP = CCP_IOREG_gc;
    	CLK.CTRL = CLK_SCLKSEL_RC32M_gc;		
    }
    
    
    
    void UART_init(void)
    {
    	USARTC0.BAUDCTRLB = 0;		
    	USARTC0.BAUDCTRLA = 0x84;				
    	USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;		
    	USARTC0.CTRLB = USART_TXEN_bm | USART_RXEN_bm;
    	USARTC0.CTRLC = USART_CHSIZE_8BIT_gc; 			
    }
    
    void TimerC0_init()
    {
    	TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;	
    	TCC0.CTRLB = 0x00;						
    	TCC0.INTCTRLA = 0x03;					
    }
    
    void TimerC0_Freq(int TTW)
    {
    	TCC0.PER = TTW;								
    }
    
    
    void Send_UART(char data[])
    {
    	char Counter;
    	char lenght = 0x00;			
    	
    	lenght = strlen(data);
    	
    	while(Counter < lenght)
    	{
    		while (!(USARTC0.STATUS & USART_DREIF_bm));
    		USARTC0.DATA = data[Counter];	
    		Counter++;
    	}
    				
    	Counter = 0x00;	
    	while (!( USARTC0.STATUS & USART_DREIF_bm));
    	USARTC0.DATA = 0x0A;	
    	while (!( USARTC0.STATUS & USART_DREIF_bm));
    	USARTC0.DATA = 0x0D;	
    }
    
    unsigned char ADCA_Conversion(char Channel)
    {
    	ADCA_CH0_MUXCTRL = (Channel << 3);	
    	ADCA.CH0.CTRL = 0x81;										
    	return ADCA_CH0RES;																									
    }
    
    
    void ADCA_Cal(void)
    {
    	ADCA.CALL = LeseKalibrationsbyte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));	
    	ADCA.CALH = LeseKalibrationsbyte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));	
    }
    
    ISR(TCC0_OVF_vect)
    {
    	PORTR.OUT ^= 0x01;
    	Zaehler++;
    	Voltage = Voltage + 100;
    	Compare = Compare + 100;
    				
    	ADC_Value = ADCA_Conversion(0);
    	itoa(ADC_Value, Text, 10);
    	Send_UART(Text);		
    }
    Danke für die Hilfe!
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Hi,

    laut Datenblatt von meinem ATXMEGA64A3 (du hast ja nicht angegeben, welchen du verwendest) darf AREF höchstens mit VCC-0.6V beschaltet werden. Somit kannst du eine Spannung von 3.3V gar nicht messen?!
    Auch ist für mich nicht ersichtlich, welche Referenz du im Programm gewählt hast, da ich kein (zu wenig) C kann. Mach doch noch genauere Angaben (welcher µC, welche Referenz), damit man mehr sagen kann

    Gruß
    Chris

  3. #3
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Stimmt! Ganz vergessen.
    Also ich verwende einen XMega128A1 auf einem AVR XPlained 128A1 Board.
    Als Taktfrequenz verwende ich den 32MHz Oszillator den ich auf 41MHz gestellt habe (mittels PLL).
    Die Referenzspannung von 3,3V ist Boardbedingt schon an den passenden Pin angeschlossen.

    Edit......ich Idiot. Ich hab gerade gesehen das nur AVCC am Board angeschlossen ist aber nicht AREF. Von daher messe ich gerade ohne Referenzspannung.
    Ich glaube das Problem hat sich damit erledigt -.-
    Aber selbst für den XMega128 darf man nur eine max. Referenzspannung von Vcc - 0,6V nehmen.
    Danke für den Hinweis

    Noch ein Edit:
    Aber das komische Verhalten bleibt weiterhin bestehen.
    Ich habe an meinem Labornetzteil nun eine Spannung von 0,2V eingestellt und das Terminal gibt 125 aus.
    Geändert von Kampi (30.09.2012 um 14:31 Uhr)
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Was für eine Referenz hast du den nun?
    Ich bin mir grade nicht sicher, ob der ADC auch einen Offset bei Single-ended Inputs hat, aber dem würde ich auf jeden Fall mal nachgehen

    Gruß
    Chris

  5. #5
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Die interne 1V Referenz:

    ADCA.REFCTRL = ADC_REFSEL_INT1V_gc;

    Aber ein Offset würde das Ergebnis ja erhöhen. Ich hab ja den Fall das es teilweise niedriger wird wenn ich die Spannung hochdrehe.
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Hm, das hört sich komisch an ...
    GND ist verbunden?
    ADC ist auf Single-ended eingestellt?
    Die Spannung stimmt auch?
    Wie hoch ist den der Prescaler des ADC? Laut DB darf der mit maximal 2Msps laufen, bei deinen 41MHz muss der Prescaler >= 32 sein. Ich würde es aber erstmal zum testen sowieso mit 512 probieren, da es dadurch genauer wird. Den MUX Kanal hast du auch richtig einstellt?

    Sorry für meine doofe Fragerei, aber aufgrund meiner beschränkten C-Kenntnisse kann ich dir so besser helfen.

    Gruß
    Chris

  7. #7
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Ja GND ist verbunden und der ADC ist auf Singleended eingestellt.
    Die Versorgungsspannung ist mittels USB gegeben und wird auf 3,3V runtergeregelt.
    Den Prescaler hatte ich jetzt nicht drin, aber hab ihn mal mit einem Wert von 512 hinzugefügt.
    Ins MUXCTRL Register schreibe ich eine 0 rein, sprich es ist Kanal 0 ausgewählt da ich als Input Mode 0:1, also Singleended gewählt habe.
    In das ADC.CH0 Register schreibe ich eine 0x81 rein, sprich ich aktiviere Kanal 0 und stelle den Inputmode auf 01.
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Scheint ja alles richtig zu sein.. Dann kann ich dir momentan leider auch nicht weiterhelfen, aber wenn mir was einfällt, lasse ich es dich wissen

    Gruß
    Chris

  9. #9
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Ok nun funktioniert es endlich!
    Das "Problem" war einfach, dass ich den ADC auf 12Bit laufen lasse aber das Ergebnis der Wandlung in einen Char reinquetschen wollte der nur 8Bit groß ist.
    Die 140 oder so die immer angezeigt wurden waren im Endeffekt das Rauschen des ADCs + ein paar Fetzen des eigentlichen Ergebnisses. Ich habe den Rückgabewert nun als Int deklariert und schwups funktionierte es
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

Ähnliche Themen

  1. XMega UART funktioniert nicht
    Von Kampi im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 02.04.2012, 06:53
  2. AD-Wandler läuft nicht korrekt...
    Von DanielSan im Forum AVR Hardwarethemen
    Antworten: 16
    Letzter Beitrag: 05.01.2012, 13:48
  3. LCD-Ansteuerung nicht korrekt
    Von EagleStar im Forum AVR Hardwarethemen
    Antworten: 30
    Letzter Beitrag: 20.11.2007, 20:08
  4. Pic führtprogramm nicht korrekt aus
    Von cavorca im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 16.04.2007, 20:01
  5. Antworten: 9
    Letzter Beitrag: 11.02.2006, 02:50

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •