Перейти к содержанию

Проблема с входами АЦП ATmega8


Рекомендуемые сообщения

Для исключения сбоев по питанию необходимо добавить пару конденсаторов емкостью 0,1 - 10 μF между выводами 7 - 8 и 20 - 22.

На Вашей схеме их нет, а без них возможны сбои как в цифровой, так и в аналоговой работе микросхемы Atmega8.

На схеме нет, но на плате впаял непосредственно к ногам контроллера на минимальных выводах.

Сейчас переписал функцию Volt_Input так, чтобы измерение происходило с обоих входов в одном полупериоде. Сбоить стало намного меньше. Включая выключая питание сейчас глюк появляеться раза с десятого.

Есть еще мысль уменьшить тактовую частоту контроллера с 12МГц до 8МГц. Наверное так и сделаю. :angry:

Ссылка на комментарий
Поделиться на другие сайты

...

Есть еще мысль уменьшить тактовую частоту контроллера с 12МГц до 8МГц. Наверное так и сделаю. :angry:

Ничего непоменялось. Точность измерения только стала меньше.

Насчет помех по питанию, кроме регистра ADMUX ведь ничего больше несбиваеться. Есть еще идеи?

 

Кстати напряжение счас мерию вот так

void Volt_Input(void){              
                                
unsigned char counter_1;                      // счетчик колличества сэмплов  
unsigned char counter_2;                      // счетчик колличества сэмплов
unsigned long int  buffer_A;                  // буффер для суммы сэмплов входа
unsigned long int  buffer_B;                  // буффер для суммы сэмплов выхода 
unsigned char flag_O = 1;         


 while(flag_O){                               // ждем переход через 0   
    if(CROSS_ZERO == 1) flag_O = 0;  
    };

 flag_A = 1;                                    //  флаг - начало измеряемого полупериода
 flag_T = 0;                                    //  флаг - конец измеряемого полупериода
 counter_1 = 0;                                 //  обнуляем счетчик колличества сэмплов 
 counter_2 = 0;                                 //  обнуляем счетчик колличества сэмплов 
 buffer_A = 0;                                  //  обнуляем буффер суммы всех сэмплов 
 buffer_B = 0;                                  //  обнуляем буффер суммы всех сэмплов   
 TCCR1B = 0x03;                                 //  включаем таймер, Clock value: 125,000 kHz
 TCNT1H = 0xFB;                                 //  начальное значение до переполнения 0xfb1d
 TCNT1L = 0x1D;
 while(flag_A){      
   
   ADC = ADC_result(0x00);                      //  запускаем преобразование      
   buffer_A = buffer_A + ADC;                   //  считаем сумму сэмплов
   counter_1++;                                 //  увеличиваем счетчик на 1
   
   ADC = ADC_result(0x01);                      //  запускаем преобразование      
   buffer_B = buffer_B + ADC;                   //  считаем сумму сэмплов
   counter_2++;                                 //  увеличиваем счетчик на 1
       
     if(flag_T == 1){                           //  если полупериод закончился - то
        flag_A = 0;                             //  конец измеряемого полупериода
        resultat = buffer_A / counter_1;        //  получаем среднее значение ADC вход
        result_out = buffer_B / counter_2;      //  получаем среднее значение ADC выход
        };
   }
   
            resultat = resultat * 0.695;        //  коеффициент 0,695 приводит значение 1023 = 660 вольт
            result_out = result_out * 0.695; 
                                                       
}

 

И вот каким то образом номер входа начинает меняться на кажом цикле в main.

Изменено пользователем химик
Ссылка на комментарий
Поделиться на другие сайты

unsigned char counter_1; // счетчик колличества сэмплов

unsigned char counter_2; // счетчик колличества сэмплов

надо попробовать заменить unsigned char на unsigned long int (хотя бы временно), так как количество сэмплов неизвестно, и возможно переполнение при подсчете или вычислениях.

Ссылка на комментарий
Поделиться на другие сайты

... Есть еще идеи?

Разве что попробовать ещё и вот так, чтобы и переменная для каждого АЦП была своя, чтобы исключить даже теоретическую возможность записи не из того канала.

   ADC_0 = ADC_result(0x00);                      //  запускаем преобразование      
   buffer_A = buffer_A + ADC_0;                   //  считаем сумму сэмплов
   counter_1++;                                 //  увеличиваем счетчик на 1
   
   ADC_1 = ADC_result(0x01);                      //  запускаем преобразование      
   buffer_B = buffer_B + ADC_1;                   //  считаем сумму сэмплов
   counter_2++;                                 //  увеличиваем счетчик на 1
       
...

И внимательно-внимательно смотреть, что возвращает ADC_result. Например, нет ли условий, когда она может вообще не писать в результат? Тогда это было бы объяснением - сейчас вы берёте результат от разных каналов из одной и той же переменной.

Изменено пользователем Lexter
Ссылка на комментарий
Поделиться на другие сайты

надо попробовать заменить unsigned char на unsigned long int (хотя бы временно), так как количество сэмплов неизвестно, и возможно переполнение при подсчете или вычислениях.

 

 

Разве что попробовать ещё и вот так, чтобы и переменная для каждого АЦП была своя, чтобы исключить даже теоретическую возможность записи не из того канала.

   ADC_0 = ADC_result(0x00);                      //  запускаем преобразование      
   buffer_A = buffer_A + ADC_0;                   //  считаем сумму сэмплов
   counter_1++;                                 //  увеличиваем счетчик на 1
   
   ADC_1 = ADC_result(0x01);                      //  запускаем преобразование      
   buffer_B = buffer_B + ADC_1;                   //  считаем сумму сэмплов
   counter_2++;                                 //  увеличиваем счетчик на 1
       
...

И внимательно-внимательно смотреть, что возвращает ADC_result. Например, нет ли условий, когда она может вообще не писать в результат? Тогда это было бы объяснением - сейчас вы берёте результат от разных каналов из одной и той же переменной.

 

Ничего неменяеться. Первое включение ве нормально, при продолжительной работе может какоето время поглючить после выравниваеться. Если сработала защита или выключили/включили питание, то глючит сразу. Еслю выключили и подождали какоето время, а после включили то все норм. Причем глюк ведет себя иногда как код грея :

Результат1 Результат2

Результат2 Результат2

Результат2 Результат1

Результат1 Результат2

Либо просто:

Результат1 Результат2

Результат2 Результат1

Результат1 Результат2

Результат2 Результат1

Бывает так:

Результат1 Результат2

Результат2 Результат2

Результат1 Результат2

Результат2 Результат2

Что-то здесь есть, вот никак непоймаю мысль.

Изменено пользователем химик
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...