Cześć,
mam problem z odczytem ADC w kontrolerze ATxmega32A4U-AU. Odczytuję dwie wartości, VCC oraz podpięte na zewnętrznym pinie napięcie z baterii litowo jonowej podzielone dzielnikiem napięcia przez 4.
ADC konfiguruję w ten sposób:
Wykorzystuję wewnętrzne napięcie odniesienia o wartości 1V. Do mierzenia wartości wykorzystuję następującą funkcję:
Pięć pomiarów (z pominięciem pierwszego), uśrednione.
Gdy mierzę napięcie zasilania procesora na kanale 1, przy 3.3V zasilania uzyskuję wynik 650-660.
Biorąc pod uwagę, że zakres pomiaru to 0-2047, oznacza to, że zmierzone napięcie wynosi 10*660/2047 (wewnętrznie podpięte od adc zasilanie jest podzielone dziesięciokrotnie), co daje mi wynik 3.22V Niezupełnie tak, jak być powinno, ale różnica wynosi 2,5%, mi to wystarczy.
Problem pojawia się, gdy mierzę zasilanie z zewnętrznego pinu, które zmierzyłem dla dwóch napięć - 1.01V oraz 0.93V. Napięcie zmierzone woltomierzem bezpośrednio na pinie pomiaru (PA0).
Dla wartości 1.01V otrzymuję wynik odczytu 1810, natomiast dla wartości 0,93V wynik to 1670. Już pierwszy wynik wydaje się być oczywistym błędem, bo przy pomiarze względem napięcia odniesienia 1V powinienem otrzymać wynik 2047. Dla 0,93 powinienem dostać wynik 1903.
Jak nietrudno zauważyć, 1810-1670 = 140, a 2047-1903 = 144. Czyli wygląda to tak, jakby "skala" pomiaru była właściwa, natomiast był on przesunięty o mniej więcej 0.1V Według datasheetu przy pomiarze signed, którego dokonuję, żadnego offsetu być nie powinno:
Co może być przyczyną tego stanu rzeczy?
mam problem z odczytem ADC w kontrolerze ATxmega32A4U-AU. Odczytuję dwie wartości, VCC oraz podpięte na zewnętrznym pinie napięcie z baterii litowo jonowej podzielone dzielnikiem napięcia przez 4.
ADC konfiguruję w ten sposób:
void battery_management_init()
{
// Setup battery input
PORTA.DIRCLR = PIN0_bm;
PORTA.PIN0CTRL = PORT_ISC_INPUT_DISABLE_gc;
// Setup general ADC characteristics
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc| ADC_BANDGAP_bm; // Internal 1V reference source
ADCA.CTRLB = ADC_CONMODE_bm; // Signed measurement to avoid offset
ADCA.PRESCALER=ADC_PRESCALER_DIV16_gc;
// Setup channel 0 to measure battery voltage
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc;
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
// Setup channel 1 to measure internal VCC/10
ADCA.CH1.CTRL = ADC_CH_INPUTMODE_INTERNAL_gc;
ADCA.CH1.MUXCTRL = ADC_CH_MUXINT_SCALEDVCC_gc;
ADCA.CALL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));
ADCA.CALH = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));
// Enable ADC
ADCA.CTRLA=ADC_ENABLE_bm;
}Wykorzystuję wewnętrzne napięcie odniesienia o wartości 1V. Do mierzenia wartości wykorzystuję następującą funkcję:
uint16_t adc_measure_channel(ADC_CH_t* channel)
{
uint16_t result = 0;
for (uint8_t i = 0; i < 6; i++)
{
channel->CTRL |= ADC_CH_START_bm;
while(!(channel->INTFLAGS & ADC_CH_CHIF_bm));
channel->INTFLAGS = ADC_CH_CHIF_bm;
if (i > 0) result += channel->RES;
}
return result/5;
}Pięć pomiarów (z pominięciem pierwszego), uśrednione.
Gdy mierzę napięcie zasilania procesora na kanale 1, przy 3.3V zasilania uzyskuję wynik 650-660.
Biorąc pod uwagę, że zakres pomiaru to 0-2047, oznacza to, że zmierzone napięcie wynosi 10*660/2047 (wewnętrznie podpięte od adc zasilanie jest podzielone dziesięciokrotnie), co daje mi wynik 3.22V Niezupełnie tak, jak być powinno, ale różnica wynosi 2,5%, mi to wystarczy.
Problem pojawia się, gdy mierzę zasilanie z zewnętrznego pinu, które zmierzyłem dla dwóch napięć - 1.01V oraz 0.93V. Napięcie zmierzone woltomierzem bezpośrednio na pinie pomiaru (PA0).
Dla wartości 1.01V otrzymuję wynik odczytu 1810, natomiast dla wartości 0,93V wynik to 1670. Już pierwszy wynik wydaje się być oczywistym błędem, bo przy pomiarze względem napięcia odniesienia 1V powinienem otrzymać wynik 2047. Dla 0,93 powinienem dostać wynik 1903.
Jak nietrudno zauważyć, 1810-1670 = 140, a 2047-1903 = 144. Czyli wygląda to tak, jakby "skala" pomiaru była właściwa, natomiast był on przesunięty o mniej więcej 0.1V Według datasheetu przy pomiarze signed, którego dokonuję, żadnego offsetu być nie powinno:
Co może być przyczyną tego stanu rzeczy?