Гость химик Опубликовано 18 Ноября, 2013 в 08:24 Жалоба Поделиться Опубликовано 18 Ноября, 2013 в 08:24 Для исключения сбоев по питанию необходимо добавить пару конденсаторов емкостью 0,1 - 10 μF между выводами 7 - 8 и 20 - 22. На Вашей схеме их нет, а без них возможны сбои как в цифровой, так и в аналоговой работе микросхемы Atmega8. На схеме нет, но на плате впаял непосредственно к ногам контроллера на минимальных выводах. Сейчас переписал функцию Volt_Input так, чтобы измерение происходило с обоих входов в одном полупериоде. Сбоить стало намного меньше. Включая выключая питание сейчас глюк появляеться раза с десятого. Есть еще мысль уменьшить тактовую частоту контроллера с 12МГц до 8МГц. Наверное так и сделаю. :angry: Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 19 Ноября, 2013 в 14:19 Жалоба Поделиться Опубликовано 19 Ноября, 2013 в 14:19 (изменено) ...Есть еще мысль уменьшить тактовую частоту контроллера с 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. Изменено 19 Ноября, 2013 в 14:46 пользователем химик Ссылка на комментарий Поделиться на другие сайты Поделиться
if33 Опубликовано 19 Ноября, 2013 в 17:00 Жалоба Поделиться Опубликовано 19 Ноября, 2013 в 17:00 unsigned char counter_1; // счетчик колличества сэмплов unsigned char counter_2; // счетчик колличества сэмплов надо попробовать заменить unsigned char на unsigned long int (хотя бы временно), так как количество сэмплов неизвестно, и возможно переполнение при подсчете или вычислениях. Ссылка на комментарий Поделиться на другие сайты Поделиться
Lexter Опубликовано 19 Ноября, 2013 в 18:06 Жалоба Поделиться Опубликовано 19 Ноября, 2013 в 18:06 (изменено) ... Есть еще идеи? Разве что попробовать ещё и вот так, чтобы и переменная для каждого АЦП была своя, чтобы исключить даже теоретическую возможность записи не из того канала. 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. Например, нет ли условий, когда она может вообще не писать в результат? Тогда это было бы объяснением - сейчас вы берёте результат от разных каналов из одной и той же переменной. Изменено 19 Ноября, 2013 в 18:08 пользователем Lexter Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 21 Ноября, 2013 в 06:54 Жалоба Поделиться Опубликовано 21 Ноября, 2013 в 06:54 (изменено) надо попробовать заменить 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 Что-то здесь есть, вот никак непоймаю мысль. Изменено 21 Ноября, 2013 в 07:02 пользователем химик Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти