kd_Rash 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба сделал так - уже лучше (да... креатифчик был :)) #pragma vector = ADC_vect __interrupt void MY_ADC (void) { static char t=0; static unsigned short x1=0,x2=0,x3=0; ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8); if (t <= 2) { x1=x2; x2=x3; x3=ADCrez; t++; } else { t=0; } ADCrez = (x1+x2+x3)/3; k=1; } ADMUX = Bit(REFS0) | Bit(REFS1); ADCSRA = Bit(ADEN) | Bit(ADIE) | Bit(ADPS2) | Bit(ADPS1) | Bit(ADPS0); ADCSRA |= Bit(ADSC);DIDR0 |= Bit(ADC0D); case 1: ADCSRA |= Bit(ADSC); while (k==0) {;} Uadc = (0.1947 * (float)ADCrez) + 9.5684; SetDataDisp (1,(unsigned short)Uadc); k=0; break; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба Совет. Берите выборку кратную 1, 2, 4, 8 и т.д (2 в степени 0, 1,2,3...). Не будете терять точность при вычислении среднего (обойдетесь простым сдвигом на соответствующее количество разрядов). Извините, чужие листинги читать лень (свои тоже временами). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8); лучше записать: ADCrez = ADCL | (ADCH << 8); или ADCrez = ADCL; ADCrez |= (ADCH << 8); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maik-vs 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба сделал так - уже лучше (да... креатифчик был :)) . . . Да уж, впердолить в прерывание три лишних пересылки в статическом массиве и до кучи деление на три - это сильный креатифчик. :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kipmaster 0 10 ноября, 2007 Опубликовано 10 ноября, 2007 · Жалоба Что может быть, подскажите на вход АЦП (через делитель) подаю напряжение, которое потом вывожу на индикаторы. использую ИОН - 1.1 V но при выводе на индикаторы напряжение скачет (перескакивает) 11,9-12,3-11,9-12,1... использую авто аккумулятор, т.ч сами понимаете такого быть не должно что посоветуете С Уважением, Дмитрий. 1. Хорошим и быстрым вольтметром проверьте питание в процессе измерения. Из-за проводов питания/разводки напряжение может меняться от количества горящих сегментов индикатора. Вообще мерять питание через делитель можно, если питание ооочень стабильное. 2. Как управляются индикаторы? Портами Меги? Тогда - совсем плохо, по 5-10 мА в каждый сегмент, количество сегментов скачет, Мега дает ошибку. Если надо точно мерять - порты должны работать только на высокоомную нагрузку. Я использую для светодиодной индикации очередь сдвиговых регистров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kd_Rash 0 12 ноября, 2007 Опубликовано 12 ноября, 2007 · Жалоба сделал все таки - и не скачет, и почти мгновенно ... #pragma vector = ADC_vect __interrupt void MY_ADC (void) { ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8); } ... ADMUX = Bit(REFS0) | Bit(REFS1); ADCSRA = Bit(ADEN) | Bit(ADIE) | Bit(ADPS2) | Bit(ADPS1) | Bit(ADPS0); ADCSRA |= Bit(ADSC); DIDR0 |= Bit(ADC0D); ... (main) ... for (;;) { if (ADCSRA & Bit(ADIF) != 0) { x1=x2; x2=x3; x3=x4; x4=x5; x5=x6; x6=x7; x7=x8; x8=x9; x9=x10; x10=ADCrez; ADCrez = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10)/10; Uadc = (0.1947 * (float)ADCrez) + 9.5684; ADCSRA |= Bit(ADSC); j++; } ... case 1: // вывод напряжения ADCSRA |= Bit(ADSC); j=0; SetDataDisp (1,(unsigned short)Uadc); break; ... правда, чтобы не загружать сильно процессор надо правильней наверно так: ... if (j<10) { if (ADCSRA & Bit(ADIF) != 0) { x1=x2; x2=x3; x3=x4; x4=x5; x5=x6; x6=x7; x7=x8; x8=x9; x9=x10; x10=ADCrez; ADCrez = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10)/10; Uadc = (0.1947 * (float)ADCrez) + 9.5684; ADCSRA |= Bit(ADSC); j++; } } ... но тогда показания меняются совсем медленно, и не могу понять почему :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kipmaster 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба И все-таки лечить аппаратные проблемы программными средствами не всегда гуд. По характеру скачков и по схеме очевидно, что напряжение меняется от количества включенных светодиодных сегментов. Посему, если хотите усреднять - усредняйте сколко угодно, только цикл усреднения должен захватывать несколько циклов индикации. А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kd_Rash 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба И все-таки лечить аппаратные проблемы программными средствами не всегда гуд. По характеру скачков и по схеме очевидно, что напряжение меняется от количества включенных светодиодных сегментов. Посему, если хотите усреднять - усредняйте сколко угодно, только цикл усреднения должен захватывать несколько циклов индикации. А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую. естественно так и надо но переделывать лень для первого варианта, а подумать и программно исправить - интерес Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом. спасибо исправлюсь :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 89 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую. Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП.... Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы... Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП.... Наврятли это реальная причина... то есть влиять может конечно, в сумме.... просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как это нужно делать... Автор, похвально конечно Ваше желание разобраться самому, но зачем Вы тогда задаете вопросы здесь ? Сформулируйте точно что Вы хотите получить, ну и приложите код Вашего решения, ну а мы если что отредактируем... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 14 ноября, 2007 Опубликовано 14 ноября, 2007 · Жалоба Уже предложена куча полезных советов, автору нужно только их осознать и все будет ХОРОШО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kd_Rash 0 14 ноября, 2007 Опубликовано 14 ноября, 2007 · Жалоба Наврятли это реальная причина... то есть влиять может конечно, в сумме.... просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как это нужно делать... Автор, похвально конечно Ваше желание разобраться самому, но зачем Вы тогда задаете вопросы здесь ? Сформулируйте точно что Вы хотите получить, ну и приложите код Вашего решения, ну а мы если что отредактируем... мне кажется, что сформулировал более, чем достаточно если бы все здесь были такие как вы, то естественно, что я даже не стал регистрироваться на этом форуме а вопрос был в самом начале - стояла мега8. напряжение показывалось великолепно. выпаял и поставил мегу168 (кстати поменял их 2 греша на брак) - и начались перескакивания в напряжении укажите плз хотя бы одну причину Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом. Uadc у меня стояло сначала только перед выводом на дисплей. но когда я это поставил там где стоит - перескакивания исчезли полностью в купе с подсчетом среднего из 10-ти. пробовал брать 16, как Вы посоветовали - чуть стало похуже. беря последовательно среднее из от 2 до 20, лучшими стали из 10 и 11 спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kipmaster 0 14 ноября, 2007 Опубликовано 14 ноября, 2007 · Жалоба Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП.... Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы... Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)... Вот еще бредово-гениальная идея. Криатифф 2000%! Надо измерить влияние одного включенного сегмента на ошибку, и потом в каждом цикле индикации считать количество сегментов и делать поправку к отсчету АЦП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 14 ноября, 2007 Опубликовано 14 ноября, 2007 · Жалоба пробовал брать 16, как Вы посоветовали - чуть стало похуже. беря последовательно среднее из от 2 до 20, лучшими стали из 10 и 11 Попробуйте 32. Сдвиг удобный >>5. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться