PrimussTh
PrimussTh
Админ сломал ногу! realy.

Повышение разрешения АЦП с помощью оверсемплинга

0 Пользователей и 1 Гость просматривают эту тему.

slav0n

  • Администратор
  • .
  • *****
    • Сообщений: 5328
    • Карма: +7/-0
В природе существует апноут AVR121 и его перевод.
Я попробовал запустить этот метод на симуляторе и вот что получилось:
на картинке показания "железного" 12-бит АЦП MCP3201, "софтового" разогнанного АЦП ATmega8, осциллограмма добавленного шума



while(1||!1);
зберігай спокій


slav0n

  • Администратор
  • .
  • *****
    • Сообщений: 5328
    • Карма: +7/-0
формула расчета повышенного разрешения
n - количество дополнительных бит разрешения
k - коэффициент усреднения средним арифметическим
while(1||!1);
зберігай спокій


slav0n

  • Администратор
  • .
  • *****
    • Сообщений: 5328
    • Карма: +7/-0
отладка в железе показала хорошие результаты.
Можно легко измерять два канала в диапазоне 0-5 вольт с разрешением 1мВ
while(1||!1);
зберігай спокій


slav0n

  • Администратор
  • .
  • *****
    • Сообщений: 5328
    • Карма: +7/-0
Код
Код
#define OVERBIT 5
#define ROUNDS (1024 * 1)

u32 adc0sum, adc1sum;
u16 cnt;

ISR(ADC_vect)
{
if (cnt < ROUNDS * 2){ //2 channels
if(cnt & 1){
adc1sum += ADCW;
ADMUX &=~1;//channel 0
}else{
adc0sum += ADCW;
ADMUX |= 1;//channel 1
}
cnt++;
}
}


int __attribute__((naked)) main(void)
{
// ******* ADC initialization ***************** /
ADMUX = (0<<REFS1)|(1<<REFS0); //ref AVcc,
#define VREF 4560UL //mV

#define calcvoltage(x) ((x >> OVERBIT) * VREF / 1024 / (ROUNDS >> OVERBIT))

// непрерывное измерение, частота 8MHz/32
//101 - 32 250kHz
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADFR)|(1<<ADIE) |(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);

u16 res0, res1; //results
sei();

while(1){
if(cnt >= ROUNDS * 2){ //2 channels
ADCSRA &=~(1<<ADIE);//Interrupt off
//экспоненциальный фильтр
res0 += (calcvoltage(adc0sum) - res0) >> 1;
res1 += (calcvoltage(adc1sum) - res1) >> 2;

adc0sum = adc1sum = cnt = 0;
ADCSRA |= (1<<ADIE);//Interrupt on
}
}
}
« Последнее редактирование: 13 Сентябрь 2021, 10:22:11 от slav0n »
while(1||!1);
зберігай спокій