|
|
  |
mega168 - скачет напряжение с АЦП |
|
|
|
Nov 8 2007, 10:24
|
Участник

Группа: Новичок
Сообщений: 58
Регистрация: 11-01-07
Пользователь №: 24 311

|
сделал так - уже лучше (да... креатифчик был  ) #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;
|
|
|
|
|
Nov 8 2007, 11:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8); лучше записать: ADCrez = ADCL | (ADCH << 8); или ADCrez = ADCL; ADCrez |= (ADCH << 8);
--------------------
|
|
|
|
|
Nov 8 2007, 12:33
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(kd_Rash @ Nov 8 2007, 14:24)  сделал так - уже лучше (да... креатифчик был  ) . . . Да уж, впердолить в прерывание три лишних пересылки в статическом массиве и до кучи деление на три - это сильный креатифчик.
|
|
|
|
|
Nov 10 2007, 11:53
|
Частый гость
 
Группа: Свой
Сообщений: 90
Регистрация: 26-10-07
Из: Одесса
Пользователь №: 31 768

|
Цитата(kd_Rash @ Nov 6 2007, 12:58)  Что может быть, подскажите на вход АЦП (через делитель) подаю напряжение, которое потом вывожу на индикаторы. использую ИОН - 1.1 V но при выводе на индикаторы напряжение скачет (перескакивает) 11,9-12,3-11,9-12,1... использую авто аккумулятор, т.ч сами понимаете такого быть не должно
что посоветуете С Уважением, Дмитрий. 1. Хорошим и быстрым вольтметром проверьте питание в процессе измерения. Из-за проводов питания/разводки напряжение может меняться от количества горящих сегментов индикатора. Вообще мерять питание через делитель можно, если питание ооочень стабильное. 2. Как управляются индикаторы? Портами Меги? Тогда - совсем плохо, по 5-10 мА в каждый сегмент, количество сегментов скачет, Мега дает ошибку. Если надо точно мерять - порты должны работать только на высокоомную нагрузку. Я использую для светодиодной индикации очередь сдвиговых регистров.
|
|
|
|
|
Nov 12 2007, 14:54
|
Участник

Группа: Новичок
Сообщений: 58
Регистрация: 11-01-07
Пользователь №: 24 311

|
сделал все таки - и не скачет, и почти мгновенно ... #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++; } } ... но тогда показания меняются совсем медленно, и не могу понять почему
|
|
|
|
|
Nov 13 2007, 05:45
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(kd_Rash @ Nov 12 2007, 17:54)  Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом.
|
|
|
|
|
Nov 13 2007, 09:32
|
Участник

Группа: Новичок
Сообщений: 58
Регистрация: 11-01-07
Пользователь №: 24 311

|
Цитата(kipmaster @ Nov 13 2007, 13:07)  И все-таки лечить аппаратные проблемы программными средствами не всегда гуд. По характеру скачков и по схеме очевидно, что напряжение меняется от количества включенных светодиодных сегментов. Посему, если хотите усреднять - усредняйте сколко угодно, только цикл усреднения должен захватывать несколько циклов индикации. А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую. естественно так и надо но переделывать лень для первого варианта, а подумать и программно исправить - интерес Цитата(alexander55 @ Nov 13 2007, 09:45)  Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом.  спасибо исправлюсь
|
|
|
|
|
Nov 13 2007, 18:46
|
Профессионал
    
Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364

|
Цитата А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую. Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП.... Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы... Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)...
|
|
|
|
|
Nov 13 2007, 19:11
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(ArtemKAD @ Nov 13 2007, 21:46)  Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП.... Наврятли это реальная причина... то есть влиять может конечно, в сумме.... просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как это нужно делать... Автор, похвально конечно Ваше желание разобраться самому, но зачем Вы тогда задаете вопросы здесь ? Сформулируйте точно что Вы хотите получить, ну и приложите код Вашего решения, ну а мы если что отредактируем...
|
|
|
|
|
Nov 14 2007, 07:24
|
Участник

Группа: Новичок
Сообщений: 58
Регистрация: 11-01-07
Пользователь №: 24 311

|
Цитата(singlskv @ Nov 13 2007, 23:11)  Наврятли это реальная причина... то есть влиять может конечно, в сумме.... просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как это нужно делать...
Автор, похвально конечно Ваше желание разобраться самому, но зачем Вы тогда задаете вопросы здесь ? Сформулируйте точно что Вы хотите получить, ну и приложите код Вашего решения, ну а мы если что отредактируем... мне кажется, что сформулировал более, чем достаточно если бы все здесь были такие как вы, то естественно, что я даже не стал регистрироваться на этом форуме а вопрос был в самом начале - стояла мега8. напряжение показывалось великолепно. выпаял и поставил мегу168 (кстати поменял их 2 греша на брак) - и начались перескакивания в напряжении укажите плз хотя бы одну причину Цитата(alexander55 @ Nov 13 2007, 09:45)  Несколько соображений. 1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей. 2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей. 3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет). 4. При 16 выборках и считайте так. ADCres=Sum>>4; Это видно невооруженным глазом.  Uadc у меня стояло сначала только перед выводом на дисплей. но когда я это поставил там где стоит - перескакивания исчезли полностью в купе с подсчетом среднего из 10-ти. пробовал брать 16, как Вы посоветовали - чуть стало похуже. беря последовательно среднее из от 2 до 20, лучшими стали из 10 и 11 спасибо
|
|
|
|
|
Nov 14 2007, 08:06
|
Частый гость
 
Группа: Свой
Сообщений: 90
Регистрация: 26-10-07
Из: Одесса
Пользователь №: 31 768

|
Цитата(ArtemKAD @ Nov 13 2007, 20:46)  Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом). Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП....
Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы...
Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)... Вот еще бредово-гениальная идея. Криатифф 2000%! Надо измерить влияние одного включенного сегмента на ошибку, и потом в каждом цикле индикации считать количество сегментов и делать поправку к отсчету АЦП.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|