Только что закончил небольшшой заказ в 10 устройств на ATtiny461. В каждом устройстве необходимо было мерить как униполярные, так
и дифф сигналы. Так как прослеживалась тенденция к повторным заказам, решил приложить определенные усилия к написанию программы
калибровки внутреннего ADC. Попытки сделать это чуть не сорвали сроки проекта - оказалось, что ADC ATtiny461 имеют существенные
разбросы по параметрам от экз к экз и др. тонкости:
1. Обычное униполярное измерение в 4 экземплярах из 10 показало ошибку в 20 LSB при напряжениях на входе около 2.2 вольт при
опоре 2.56 вольт. Вроде требования даташита выполнены - для униполярных сигналов все напряжения в доп пределах. Измерения низких
напряжений (в районе 100 mV) были практически идеальны. Насколько я понимаю, ADC в этих 4 экз. имеют слишком большой INL. Как с
этим бороться просто не представляю. А если бы устройств было не 10, а 100? Что, делать стенд для отбраковки кристаллов?
2. ADC в AVR по скорости работы и так аутсайдер, но определенные тонкости выявились и при переключениях каналов. Особенно когда
есть и униполярные и дифф. (у меня было по 2 сигнала каждого типа). Засада в том, что униполярные мерялись стабильно, но дифф
колбасило конкретно, сэмплы отличались почти в два раза. Сначала подумал, что PCB неправильно разведена, но вроде не первый раз
развожу, решил искать причину дальше. По-моему, из AVR аппликух была в свое время выдрана некая функция AdcStable():
Код
void AdcStable(void){
signed int Vmax,Vmin,V[4];
unsigned char i;
//Loop until the ADC value is stable. (Vmax <= (Vmin+1))
for (Vmax=10,Vmin=0;Vmax > (Vmin+1);){
V[3] = V[2];V[2] = V[1];V[1] = V[0];// сдвиг в буфере
SETBIT(ADCSRA,ADSC);while(CHKBIT(ADCSRA,ADSC));// получить результат
V[0] = ADC;
Vmin = V[0]; // Vmin is the lower VOLTAGE
Vmax = V[0]; // Vmax is the higher VOLTAGE
for (i=0;i<=3;i++){//Save the max and min voltage
if (V[i] > Vmax) Vmax=V[i];
if (V[i] < Vmin) Vmin=V[i];
}
}
}
C ней дифф сигналы стали измеряться нормально, но косяк проявился в том, что компилятор IAR v5.50 при оптимизации по скорости
сделал так, что цикл в этой функции становился вечным и я не смог разобраться в чем дело. При оптимизации по коду все работало
нормально. Однако это наблюдение покоя так и не дало, поэтому данную функцию пришлось выкинуть. В даташите на ATmega324 написано,
что при измер дифф сигналов схеме нужно время чтобы прошли переходные процессы переключения и это время указано - 125us. Как
только поставил паузу 200us после смены мультиплексора (измерения шли группой, но single conversions) - сразу все начало измеряться нормально. Но горький осадок остался: ADC и так не быстр, скорость выборок падает с увеличением кол-ва сигналов, дак еще и переходные задерживают... Что же делать? Кто как выкручивается?
Мне особенно интересно, как все это хозяйство калибруется в серию? Это же все серьезный риск получить приключений на собственное то самое место...