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!
Lesezeichen