|
нестабильность показаний АЦП, нестабильность показаний АЦП |
|
|
|
Sep 24 2012, 21:56
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
Вообщем нужно изменять некое напряжение (для примера я взял 5в). АЦП меряет, значение преобразуется для отображения на четырехразрядном семисегментрике и выводится на него. Но два последних разряда АЦП постоянно дают разные значения (крайние правые разряды индикатора постоянно показывают разные значения, при этом частота АЦП = 15 кГц). После этого, я добавил в схему повторитель на ОУ (т.к. думал что его малое выходное значение и большое входное положительно отобразится на стабильности измерений, но не помогло - значения по прежнему скачают). Подскажите что может исправить положения дел, что бы различные помехи наводки почти не влияли на результат измерений. Видео, упрощенная схема и код прилагаются. И, кстати, до нуля вход на АЦП тоже не доходит - там где минимум 1.2в, я думаю это из-за особенностей ОУ - так как он не rail-to-rail. Демонстрация работы CODE #include <avr/io.h> #include <avr/interrupt.h>
#define F_CPU 1000000UL #include <util/delay.h>
int ADC_data; unsigned char i; unsigned char d0,d1,d2,d3;
unsigned char kod_simvola[10]= //коды цифр для семисегментного индикатора { 0b00111111, //0 0b00000110, //1 0b01011011, //2 0b01001111, //3 0b01100110, //4 0b01101101, //5 0b01111101, //6 0b00000111, //7 0b01111111, //8 0b01101111 //9 };
//=====================ВЫВОД 4-ех ЦИФР НА СЕМИСЕГМЕНТНЫЙ ИНДИКАТОР===================== void vivod_led(unsigned char digit0,unsigned char digit1,unsigned char digit2,unsigned char digit3) { cli(); unsigned char razr, digit; DDRC=0b11111111; //PORTC0:7 подключаем к сегментам индикатора DDRB=0b00001111; //PORTB0:3 подключаем к разрядам индикатора for(razr=0;razr<4;razr++) { switch (razr) { case 0: digit=digit0; break; case 1: digit=digit1; break; case 2: digit=digit2; break; case 3: digit=digit3; break; } switch (digit) { case 0: PORTC=kod_simvola[0]; //выводим в порт нужную цифру break; case 1: PORTC=kod_simvola[1]; break; case 2: PORTC=kod_simvola[2]; break; case 3: PORTC=kod_simvola[3]; break; case 4: PORTC=kod_simvola[4]; break; case 5: PORTC=kod_simvola[5]; break; case 6: PORTC=kod_simvola[6]; break; case 7: PORTC=kod_simvola[7]; break; case 8: PORTC=kod_simvola[8]; break; case 9: PORTC=kod_simvola[9]; break; default: //если задан некорректный символ - выводится "_" PORTC=0b0001000; break; } if (razr==0) PORTC |=0b10000000; //зажигаем точку после первого рязряда PORTB=1<<razr; //зажигаем нужный разряд индикатора _delay_us(500); //менее 200 мкс - падает яркость, более 5 мс - заметно мерцание PORTB=0<<razr; //гасим разряд индикатора } sei(); }
int main(void) { DDRA=0b00000000; int temp; //для хранения результата преобразования АЦП //====================ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА T0=================================== TCCR0=(1<<CS00) | (1<<CS01); /*Timer/Counter Control Register устанавливаем коэффициент делителя таймера 64*/ OCR0=156; /*Output Compare Register число тактов котое будет сравниватся с числом тактов таймера*/ /*TIMSK=(1<<OCIE0); / *Timer/Counter Interrupt Mask Register разрешаем прерывания по совпадению значения таймера T0 и OCR0=156* /*/ TIMSK=(1<<TOIE0); /*Timer/Counter Interrupt Mask Register разрешаем прерывания по переполнению таймера T0*/ //======================ИНИЦИАЛИЗАЦИЯ АЦП======================================= ADMUX=(1<<REFS0) | (1<<ADLAR); /*ADC Multiplexer Selection Register REFS1:0=01 - за ИОН берем Vcc контроллера (AVcc) MUX4:0=0000 - выбераем канал для АЦП - PORTA.0 ADLAR=1 - выравнивание результата преобразования АЦП по левому краю байтов результата*/ ADCSRA=(1<<ADEN) | (1<<ADSC) | (1<<ADPS1) | (1<<ADPS2) | (1<<ADATE);// | (1<<ADIE); /*ADC Control and Status Register A ADEN=1 - включаем АЦП ADSC=1 - запускаем первое преобразование АЦП, дальше само идет автоматически ADPS2:0=110 - делитель тактовой частоты для АЦП 1 Мгц/64 = 15.625 кГц ADATE=1 - запускаем АЦП в режиме непрерывных последовательных преобразовний одно за другим ADIE=0 - запрещаем прерывания по окончанию преобразования АЦП*/ SFIOR &=~(1<<ADTS0) | (1<<ADTS1) | (1<<ADTS2); /*Special FunctionIO Register ADTS2:0=000 - преобразование идет в непрерывном режиме с момента запуска*/ sei(); //разрешаем глобальные прерывания while(1) { //ADC_data=(ADCL>>6) | (ADCH<<2); //байт ADCH всегда должен читатся последним temp=ADC_data*0.004858*1000; //0.0049 - значение напряжение на одну ступень 4.97/1023 d3=temp%10; temp /=10; d2=temp%10; temp /=10; d1=temp%10; temp /=10; d0=temp%10; vivod_led(d0,d1,d2,d3); } }
ISR(TIMER0_OVF_vect) //обработчик прерывания по переполнению T0 { if(i==5) { ADC_data=(ADCL>>6) | (ADCH<<2); //байт ADCH всегда должен читатся последним i=0; } else i++; }
Сообщение отредактировал IgorKossak - Sep 25 2012, 06:45
Причина редактирования: [codebox] для длинного кода!!!
|
|
|
|
Сообщений в этой теме
endasm нестабильность показаний АЦП Sep 24 2012, 21:56 Snaky Цитата(endasm @ Sep 25 2012, 07:56) АЦП м... Sep 24 2012, 22:30 _Артём_ Цитата(endasm @ Sep 25 2012, 00:56) Вообщ... Sep 24 2012, 22:49 endasm Пробовал в другом порядке считывать - после первог... Sep 25 2012, 04:31 kovigor Цитата(endasm @ Sep 25 2012, 07:31) И нуж... Sep 25 2012, 07:33 MTh Даже в идеальном случае - младший 1-2 разряда буду... Sep 25 2012, 16:35 uriy Вот тут описан простой фильтр http://we.easyelectr... Sep 25 2012, 16:45 ReAl Цитата(uriy @ Sep 25 2012, 19:45) Вот тут... Sep 27 2012, 07:53  ViKo Цитата(ReAl @ Sep 27 2012, 10:53) «Ну кто... Sep 27 2012, 08:28   ReAl Цитата(ViKo @ Sep 27 2012, 11:28) Можно п... Sep 27 2012, 08:47    ViKo Цитата(ReAl @ Sep 27 2012, 11:47) Ну так ... Sep 27 2012, 08:57  drvlas Цитата(ReAl @ Sep 27 2012, 10:53) «Ну кто... Sep 27 2012, 09:39   ReAl Цитата(drvlas @ Sep 27 2012, 12:39) В обс... Sep 27 2012, 17:09    drvlas Цитата(ReAl @ Sep 27 2012, 20:09) Да вот ... Sep 27 2012, 18:04   ViKo Цитата(drvlas @ Sep 27 2012, 12:39) Так ч... Sep 28 2012, 05:13    drvlas Цитата(ViKo @ Sep 28 2012, 08:13) То есть... Sep 28 2012, 06:14     ViKo Цитата(drvlas @ Sep 28 2012, 09:14) Вы не... Sep 28 2012, 06:20 TSerg >Вот тут описан простой фильтр...
Откровения о... Sep 25 2012, 17:08 Integral Стабильность показаний АЦП зависит в первую очеред... Sep 26 2012, 10:47 endasm А как добится полного нуля на выходе ОУ, ведь у ме... Sep 27 2012, 03:27 Tanya Цитата(endasm @ Sep 27 2012, 07:27) А как... Sep 27 2012, 05:34 RabidRabbit Ну в качестве придирки цитата из даташита:
"B... Sep 27 2012, 05:44 xemul Даже с сохранением неделённого результата так
Кодr... Sep 27 2012, 09:59 drvlas Да, конечно, симметричное округление. Это правильн... Sep 27 2012, 10:20  xemul Цитата(drvlas @ Sep 27 2012, 14:20) Что с... Sep 27 2012, 10:32   Tanya Цитата(xemul @ Sep 27 2012, 14:32) Скажу.... Sep 27 2012, 10:48    ViKo Цитата(Tanya @ Sep 27 2012, 13:48) вблизи... Sep 27 2012, 11:19    drvlas Цитата(Tanya @ Sep 27 2012, 13:48) Если и... Sep 27 2012, 11:29 ViKo Можно и аналогию из аналоговой схемотехники привес... Sep 27 2012, 11:54 endasm А применение rail to rail ОУ даст мне на 10 битном... Sep 27 2012, 13:44 muravei Цитата(endasm @ Sep 27 2012, 16:44) А при... Sep 28 2012, 08:21 endasm Я тогда попробую поставить такой rail-to-rail ОУ ч... Sep 28 2012, 09:41 Tanya Цитата(endasm @ Sep 28 2012, 13:41) Я тог... Sep 28 2012, 10:59  AndreyVN Пользую с Мегами ОУ AD8602 (Rail-to-Rail), никаких... Sep 29 2012, 17:02   Myron Цитата(AndreyVN @ Sep 29 2012, 12:02) У R... Sep 29 2012, 20:45    drvlas Несколько старнно то, что автор не хочет пойти про... Sep 29 2012, 20:58 rx3apf Вольтодобавка в ОУ - это больше похоже на кошмарны... Sep 29 2012, 19:00 endasm Хорошая идея, но MAX232 довольно дорогая, если бы ... Oct 1 2012, 05:23 drvlas Цитата(endasm @ Oct 1 2012, 08:23) Хороша... Oct 1 2012, 05:46
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|