Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATMEGA88PA работа АЦП
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
arttab
дано: atmega88pa. Внутренний генератор 8МГц. CKDIV=0. канал АЦП ADC0. aref 1,1В встроенный м внешним конденсатором 1000пкФ. питание 3.3В. IAR4
нужно: оцифровать переходной процесс засветки фотодиода светодиодом.
проблема: при коэф. делителя 2 от частоты мк 1МГц результат не очень хороший. младшие биты теряются. это нормально, но при делители в 128 получаю одни FF. хотя должно нормально работать. по оссцилу все красиво.

туплю что не так.
Прошу помочь найти ляп.

CODE
unsigned char dip_get_signal(void)
{
unsigned int U_min = 0;
unsigned char res_of_meg[_NUMB_OF_MEG]; // Измеренные значения каждого отчета //
__disable_interrupt();
WATCHDOG_ENABLE_LONG;
// ADC_init_prescaler_on_2_auto(); // Инициализация АЦП //
ADC_init_prescaler_on_16();
for (unsigned char z=0; z<3; z++){
w_mks(5000);}
// for (unsigned char z=0; z<6; z++){
// __delay_cycles(350000/8/10*F_MHZ); // срабатывает watchdog
// WATCHDOG_RESET;}
//задержку на выход ацп на режим ADC
CLRBIT(PORTB, 2); //
SETBIT(DDRB, 2); // VT
CLRBIT(PORTB, 6); // для дрыганья ношкой для отладки
CLRBIT(PORTB, 7); // для дрыганья ношкой для отладки
SETBIT(DDRB, 6); // для дрыганья ношкой для отладки
SETBIT(DDRB, 7); // для дрыганья ношкой для отладки


SETBIT (ADCSRA, _ADC_Start); //делаем пустое преобразование для нормальной работы АЦП
ADC_CONTROL_auto();
SETBIT(PORTB, 7); //от начало до конца измерений
// длительность измерений АЦП
WATCHDOG_RESET;
// SETBIT(DDRB, _Bright);
SETBIT(PORTB, _Bright); // Включить ИК СД //
__delay_cycles(50);//w_mks(50000);

// xx мкс //
for (char j = 0; j <_NUMB_OF_MEG; j++)
{res_of_meg[j] = ADC_CONTROL_auto();} // Массив измеренного значения калибровки //

CLRBIT (ADCSRA, _ADC_Start);
CLRBIT (PORTB, _Bright); // Выключить свет
ADCSRA = 0<<ADEN; // выключаем чтобы не потреблялся ток 0.120 mA //
CLRBIT(PORTB, 7);


/////////////Для отладки
dbg_msg("rm\r");
for (char j = 0; j <_NUMB_OF_MEG; j++)
{
unch_hex(res_of_meg[j]); //
}
dbg_msg("rn\r");
////////////////////////////////////////
WATCHDOG_ENABLE_LONG
while (1) {;}


Код
#define WATCHDOG_ENABLE_LONG {WDTCSR |=(1<<WDCE)|(1<<WDE); WDTCSR =(1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0);}//2sec


CODE
void ADC_init_prescaler_on_16(void)
{
ADMUX = (1<<REFS0)|(1<<REFS1)|(1<<ADLAR)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3);
ADCSRB = 0;//(0<<ACME)&(0<<ADTS2)&(0<<ADTS1)&(0<<ADTS0);
ADCSRA =(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
//16for1MHz 100 деление тактирующей частоты на 16;
ADCSRA |= (1<<ADATE);
}


CODE
#pragma optimize=none
unsigned char ADC_CONTROL_auto(void)
{
unsigned char t;
SETBIT(PORTB, 6); // Запуск АЦ преобразования;
while( !TSTBIT(ADCSRA, _ADC_Flag)); // Ожидание флага прерывания - окончания преобразования;
CLRBIT(PORTB, 6);
t= ADCL;
t= ADCH;
return t; // Чтение результата преобразования;
}


фото где полностью виден начальный импульс это с делителем 2.

желтый луч на осциле это от запуска ацп до завершения преобразования. (выводы дергаю).
_Pasha
А между фотодиодом и ацп операционник есть? А то ж входное сопротивление не более 2к...
arttab
ОУ есть. вопрос по сути то о работе ацп в режиме циклического преобразования. первое длится долше как и должно, но последующие почти не меняются от изменения делителя. а это странно
ILYAUL
Насколько я понял , Вы не используете аппартное прерывание ADC и просто определяете установлен ли флаг ADIF - установлен - считываете данные.
Толи всё таки не нашёл , толь этой команды нет. Флаг ADIF сбрасывается аппаратно при переходе в прерывание, или записью в него (1) Может по этому Вы считываете данные , когда их ещё нет.
Т.е. надо бы его сбросить и ждать следующей установки флага.
В Си не очень силен пока
arttab
прерывание не включал - так задумано. А вот насчет флага посмотрю. спасибо.

Вы правы Alternatively, ADIF is cleared by writing a logical one to the flag. Большое спасибо!

тогда можно объяснить почему последующие измерения почти не росли по времени.
чувствовал что какой то ляп сделал да глаза "намылились".

какой делитель минимальный допустим если мне хватит 8 бит.
по докам до 76.9КГц
• Up to 76.9kSPS (Up to 15kSPS at Maximum Resolution)
ILYAUL
Цитата(arttab @ Aug 4 2011, 17:47) *
прерывание не включал - так задумано. А вот насчет флага посмотрю. спасибо.

Вы правы Alternatively, ADIF is cleared by writing a logical one to the flag. Большое спасибо!

тогда можно объяснить почему последующие измерения почти не росли по времени.
чувствовал что какой то ляп сделал да глаза "намылились".

какой делитель минимальный допустим если мне хватит 8 бит.
по докам до 76.9КГц
• Up to 76.9kSPS (Up to 15kSPS at Maximum Resolution)

Выдержка из DS на эту mega
Цитата
If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.

Ближайший делитель - на 32 - 250 000 HZ - и тогда , раз у Вас ADLAR в 1 , то можно и не читать младший регистр данных , а только старший
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.