|
ADC Mega168. Измерение напряжения "наоборот". |
|
|
|
Jun 29 2009, 10:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Есть устройство с автономным питанием. Для того ,Чтоб не использовать ключей, делителей и прочей обвязки - измеряю напряжение на аккумуляторе по сл. алгоритму:
AREF = AVCC = Vbat Данные АЦП: N = 1024*Vop/Vbat т.е. Vbat = Vop*1024/N
вот инициализация ADC: void adc_init(void) { ADMUX = (1<<REFS0)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1); ADCSRB = 0x00; ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); }
Вот прерывание: #pragma vector= ADC_vect __interrupt void ADC_vect_isr (void) { //conversion complete, read value (int) using... value_ADC=ADCL; //Read 8 low bits first (important) value_ADC|=(int)ADCH << 8; //read 2 high bits and shift into top byte }
В тексте программы: ... __disable_interrupt();adc_init();ADCSRA |= (1<<ADEN); __enable_interrupt(); DelayMs(5); f_bat=(1.22*1024/value_ADC); V_BAT=(f_bat*100); __disable_interrupt();ADCSRA &= ~(1<<ADEN); __enable_interrupt(); ...
не могу понять, почему иногда считает ADC неверно!? Где ошибка? Я не использую никакой обвязки. То есть, на ногах проца имеющих отношение к преобразованию ничего не "висит". Может быть в этом проблема? AVСС тоже в воздухе. Если измерять напряжение на этом выводе, то там меньше, чем на питании проца. Сори за очередные глупые вопросы, но оч. нужна помощь. Спасибо.
Сообщение отредактировал Буратино - Jun 29 2009, 11:06
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
 |
Ответов
(1 - 49)
|
Jun 29 2009, 13:49
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(rezident @ Jun 29 2009, 16:14)  Все неиспользуемые пины должны быть настроены как GPIO с функцией вывода лог.0. AVCC нельзя отставлять неподключенным ни в коем случае! Либо напрямую к питанию подключить, либо через LC или RC-фильтр. Присоединил AVCC напрямую к батарее. ADC стал завышать напряжение (что в принципе можно и устранить вычитанием константы), но временами, проскакивают ошибки.  Вот еще что: если делать несколько циклов "ацепирования", ну например через одну секунду десять раз, то ошибка появляется на первом, втором измерении, а все последующие - ок.
Сообщение отредактировал Буратино - Jun 29 2009, 14:14
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jun 29 2009, 15:12
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Буратино @ Jun 29 2009, 16:49)  Присоединил AVCC напрямую к батарее. ADC стал завышать напряжение (что в принципе можно и устранить вычитанием константы), но временами, проскакивают ошибки. Завышает напряжение, наверное, потому, что согласно DS при MUX3..0=1110 к АЦП подключается 1.1V (Vbg). У Вас же в формуле 1.22 Цитата(Буратино @ Jun 29 2009, 16:49)  если делать несколько циклов "ацепирования", ну например через одну секунду десять раз, то ошибка появляется на первом, втором измерении, а все последующие - ок. То, что в первом измерении неверный результат - ему верить нельзя (в DS об этом прямо сказано: "The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result."). Со вторым неверным - хуже... У Вас REFS10=01 (т.е. "AVCC with external capacitor at AREF pin"). Про конденсатор в первом посте нет ни слова...
|
|
|
|
|
Jun 29 2009, 17:21
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(rezident @ Jun 29 2009, 19:02)  А в чем заключается ошибка "ацепирования"? Результат измерения "скачет": то 3,96В (правильно), то 2,78В (ошибка) Цитата(rezident @ Jun 29 2009, 19:02)  А можно схему посмотреть? Нет никакой схемы! Вообще ничего (ну конденсатор 100н на питании проца, 1мкФ+10к на ресете, кварц и два по 27пФ это все). По идее АЦП измеряет напряжение питания относительно внутренней опоры. Цитата(Палыч @ Jun 29 2009, 19:12)  Завышает напряжение, наверное, потому, что согласно DS при MUX3..0=1110 к АЦП подключается 1.1V (Vbg). У Вас же в формуле 1.22
То, что в первом измерении неверный результат - ему верить нельзя (в DS об этом прямо сказано: "The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result."). Со вторым неверным - хуже... У Вас REFS10=01 (т.е. "AVCC with external capacitor at AREF pin"). Про конденсатор в первом посте нет ни слова... Поставил в формулу 1,1В, Припаял к AREF электролит на 10мкФ, потом 100н. Теперь меряет так: Показания прибора: 3,87В Результат преобразования: 3,96В Однако ошибка остается. Мне кажется, что она появляется после перехода из энергосберегающего режима (Power Down) в активный режим. Результат ошибочного преобразования: 2,72-2,99В
Сообщение отредактировал Буратино - Jun 29 2009, 17:27
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jun 30 2009, 00:41
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Палыч @ Jun 29 2009, 19:12)  То, что в первом измерении неверный результат - ему верить нельзя (в DS об этом прямо сказано: "The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result."). Как надоело читать эту глупость...  Вам перевести "в предпоследний раз" что там написано ? Перевод почти дословный: "Если между преобразованиями сменилось опорное напряжение, то следующее измерение после такого изменения может быть не точным, и пользователь должен это иметь в виду." Хде Вы тут увидели смену опоры ?
|
|
|
|
|
Jun 30 2009, 05:36
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(singlskv @ Jun 30 2009, 03:41)  "Если между преобразованиями сменилось опорное напряжение, то следующее измерение после такого изменения может быть не точным,и пользователь должен это иметь в виду." Хде Вы тут увидели смену опоры ?  Точнее, наверное, перевести так: "Первое измерение после смены опорного напряжения может быть неточным..." А вот - и смена опоры: Цитата ADMUX = (1<<REFS0)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1);
|
|
|
|
|
Jun 30 2009, 07:31
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Код AREF = AVCC = Vbat Тут уже говорилось автору, что он вот так ничего не измерит. То, что у него есть какой-т там результат, говорит о том, что автор неизвестно чего измеряет на самом деле. И ни о каких энергосберегающих режимах речи не идет. Тем более с конденсатором в 10 микрофарад на AREF. Это выход опорника, мкротоковый и заряжать 10 микрфарад он будет очень долго. Если уж экономить на резистивных делителях, то стоит замерять собственный уровень логической единицы поданный на измерительный вход через делитель. Тогда этот делитель можно отключать для экономии.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Jun 30 2009, 07:54
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(DpInRock @ Jun 30 2009, 10:31)  Тут уже говорилось автору, что он вот так ничего не измерит. То, что у него есть какой-т там результат, говорит о том, что автор неизвестно чего измеряет на самом деле. Ну, почему же? Автор измеряет внутреннее напряжение 1.1В, используя в качестве опорного AVCC. Кстати, для точности измерения Vбат (которое равно VCC) индуктивность между VCC и AVCC, наверное, ставить не нужно. Цитата(DpInRock @ Jun 30 2009, 10:31)  И ни о каких энергосберегающих режимах речи не идет. Выше автор говорил: "Мне кажется, что она появляется после перехода из энергосберегающего режима (Power Down) в активный режим." Цитата(DpInRock @ Jun 30 2009, 10:31)  Тем более с конденсатором в 10 микрофарад на AREF. Это выход опорника, мкротоковый и заряжать 10 микрфарад он будет очень долго. Об этом уже сказали выше, и, надеюсь, автор вопроса этому внял... Может быть, измерения неверные ещё и из-за того, что напряжение на батарее проседает при увеличении потребляемого тока в момент просыпания? Не лучше ли проверить измерения, запитав устройство от хорошего источника питания?
|
|
|
|
|
Jun 30 2009, 09:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Палыч @ Jun 30 2009, 13:18)  Вы измерение делаете один раз в секунду? Или в цикле - подряд? Или каждую секунду - серию измерений? "Первые два - ошибочны" - это какие два? Ну например так: есть в устройстве кнопка, когда ее нажимаете, запускается одиночный процесс преобразования. Если кнопку нажимать один раз в секунду то получается: первый раз - ошибка второй раз - ошибка (иногда правильно) все последующие - точно. если сделать паузу в несколько секунд - все повторяется: первый раз - ошибка второй раз - ошибка (иногда правильно) все последующие - точно.
Сообщение отредактировал Буратино - Jun 30 2009, 10:01
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jun 30 2009, 10:26
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(DpInRock @ Jun 30 2009, 13:59)  Относительно чего ПЕРВЫЙ РАЗ? Например, после сброса, после выхода из слипа? Вообще - первое преобразование практически всегда неточно. И "ПЕРВЫМ" называется такое преобразование, перед которым трогали ADMUX, выключали питание ADC.
Также имеет значение емкость на AREF. Чтобы что-то быстро замерить и уйти в слип эту емкость надо делать как можно меньше. Иначе после переключения мультиплексора эта емкость будет очень долго заряжаться. И результат будет неверным, пока емкость не зарядится до конца.
Проверьте напряжение на рефе перед ПЕРВЫМ нажатием (то, которое дает ошибку). Один раз в секунду проссыпаюсь из режима Power Down, и делаю вот так: __disable_interrupt();adc_init();ADCSRA |= (1<<ADEN); __enable_interrupt(); DelayMs(5); f_bat=(1.1*1024/value_ADC); V_BAT=(f_bat*100); __disable_interrupt();ADCSRA &= ~(1<<ADEN); __enable_interrupt(); и снова в спячку Напряжение на AREF всегда равно питанию.
Сообщение отредактировал Буратино - Jun 30 2009, 10:33
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jun 30 2009, 10:34
|

developer
   
Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032

|
Цитата(rezident @ Jun 30 2009, 14:10)  А может кто-то наконец внятно объяснить что и относительно чего измеряется? А то из datasheet мне это как-то неочевидно. Схема я думаю примерно такая
И меряется Bandgap Reference. При изменении AVCC (которое и опорное) изменяются значения АЦП. Ведь Bandgap Reference = const
--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
|
|
|
|
|
Jun 30 2009, 13:29
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Палыч @ Jun 30 2009, 14:51)  Кстати! Bandgap Reference включен, если 1) включен BOD или 2) включен компаратор или 3) включен АЦП. После включения ADEN нужно дождаться выхода на рабочий режим Bandgap Reference (это, наверное, десятки мкс - под рукой нет DS чтобы проверить). Поэтому нельзя выставлять ADEN и ADSC вместе! все что понял попробовал. BOD у меня включен, после инициализации АЦП делаю паузу, потом запускаю преобразование, но на первых измерениях всегда ошибка. Блин, ну что в ADC может давать такой "фифект"?
Сообщение отредактировал Буратино - Jun 30 2009, 13:30
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jun 30 2009, 14:18
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Jun 30 2009, 03:41)  Перевод почти дословный: "Если между преобразованиями сменилось опорное напряжение, то следующее измерение после такого изменения может быть не точным, и пользователь должен это иметь в виду." Неточный у вас перевод. Не должен иметь в виду, а рекомендуется выбрасывать этот (первый после смены reference) результат измерения. Цитата(Буратино @ Jun 30 2009, 16:29)  все что понял попробовал. BOD у меня включен, после инициализации АЦП делаю паузу, потом запускаю преобразование, но на первых измерениях всегда ошибка. Блин, ну что в ADC может давать такой "фифект"? После выхода из спячки (включения АЦП) сделайте последовательно два измерения, первое выбрасывайте, второе оставляйте. Будет всегда правильно. ADCSRA = (1 < ADEN); ADCSRA |= (1 << ADSC) | (1 << ADIF); while( !(ADCSRA & ADIF)); // <-- дождаться первого результата и выбросить его ADCSRA |= (1 << ADSC) | (1 << ADIF); <<-- еще раз оцифровать while( !(ADCSRA & ADIF)); // <-- дождаться второго результата преобразования result = ADC; <-- пользовать этот результат второго преобразования
|
|
|
|
|
Jun 30 2009, 19:03
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Палыч @ Jun 30 2009, 09:36)  Точнее, наверное, перевести так: "Первое измерение после смены опорного напряжения может быть неточным..." А вот - и смена опоры: Нету там смены опоры, REFSx устанавливаются только 1 раз за всю прогу..., другое дело что включение/выключение заново все переинициализирует и требует перезарядки конденсатора на AREF, а с измерительным конденсатором все путем(при соблюдении требований даташита по входному сопротивлению), первый цикл после включения занимает не 13 а 25 тактов fADC. Цитата(Буратино @ Jun 30 2009, 14:26)  Один раз в секунду проссыпаюсь из режима Power Down, и делаю вот так: __disable_interrupt();adc_init();ADCSRA |= (1<<ADEN); __enable_interrupt(); DelayMs(5); f_bat=(1.1*1024/value_ADC); V_BAT=(f_bat*100); __disable_interrupt();ADCSRA &= ~(1<<ADEN); __enable_interrupt(); и снова в спячку value_ADC объявлено как volatile ? чтение value_ADC в основной проге нужно делать с выключенными прерываниями ну и покажите наконец схему...
|
|
|
|
|
Jun 30 2009, 20:04
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(DpInRock @ Jun 30 2009, 23:32)  А у кого вы научились так АЦП опрашивать? Вот отчего бы не взять способ из даташита? просмотрел главу с ацп, но примеров не нашел. Цитата(DpInRock @ Jun 30 2009, 23:32)  Уберите ненужные прерывания наконец. Тем более, не видно описаний переменных. Если слова volatile в программе не присутствует, то фигня будет... Ну, и кроме того, не видно к какой слип входит процессор. переменная "value_ADC" объявлена,как глобальная и volatile. энергосберегающий режим: SMCR = (1<<SM1)|(1<<SE); Я вот тут подумал, Что ошибка измерения всегда одинаковая и составляет что-то около 1,1В! (проверю завтра предметно) Я завтра соберу вместе все рекомендации, запишу в столбик и поправлю код, но все же может есть возможность в железе проверить у кого? Ведь хорошая штука получается, но у меня шото не работающая  Цитата(singlskv @ Jun 30 2009, 23:03)  ну и покажите наконец схему... схему чего? всего устройства? обвязки АЦП? Если второе, то повторяю - нет ничего вообще! ну разве только керамика в 10n на AREFe (но вопросу она не помогла) и 100n на питании проца.
Сообщение отредактировал Буратино - Jun 30 2009, 20:05
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jul 1 2009, 05:45
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Буратино @ Jun 30 2009, 21:49)  Код #pragma vector= ADC_vect __interrupt void ADC_vect_isr (void) { value_ADC=ADCL; value_ADC|=(int)ADCH << 8; }
void adc_init(void) { ... ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); }
main(void) { ... adc_init(); ... while(1) { ... ADCSRA = (1<<ADEN); ADCSRA |= (1 << ADSC) | (1 << ADIF); ... } } Чего-то Вы немного промахнулись. 1. В main включать ADEN нужно, примерно, так ADCSRA |= (1<<ADEN); или как-то так ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); В общем, нужно выставить ADEN и при этом не сбросить другие, нужные биты настроек! 2. Вы встроили пример от defunct, но этот пример не использует прерываний (по готовности), а остальная часть Вашей программы осталась неизменной. Вы уж решите для себя: будите использовать прерывания или нет? Честно говоря, необходимости в прерываниях от АЦП в Вашем случае я не вижу. 3. Bandgap Reference (если он выключен) выходит на режим за 70 мкс. Значит, между установкой в единицу ADEN и стартом преобразования должна быть задержка. 4. Мелочь, конечно, но считать значение АЦП, обычно, лучше так value_ADC= ADC; P.S. При инициализации АЦП Вы старт преобразования зачем делаете? Убрать первое после смены опоры преобразование?
|
|
|
|
|
Jul 1 2009, 08:10
|

developer
   
Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032

|
Вот еще одна шибка. MUXn и REFS1:0 биты имеют буферизацию. И новые значения вступают в силу после одного такта АЦП. DS стр. 249 Цитата The MUXn and REFS1:0 bits in the ADMUX Register are single buffered through a temporary register to which the CPU has random access. Цитата Note that the conversion starts on the following rising ADC clock edge after ADSC is written. The user is thus advised not to write new channel or reference selection values to ADMUX until one ADC clock cycle after ADSC is written. Отсюда у вас первое ошибочное измерение. И при смене опоры первое измерение тоже ошибочное. Вот вам и второе ложное измерение.
--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
|
|
|
|
|
Jul 1 2009, 08:41
|

developer
   
Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032

|
Цитата(Палыч @ Jul 1 2009, 12:30)  Все эти биты размещены в одном регистре ADMUX и изменяются в программе один раз. Биты REFS1:0 собственно и определяют опору - поэтому одно действие вызвать два ложных измерения, имхо, не может. Да и между инициализацией АЦП и просыпанием из спячки (когда производится измерение АЦП) пройдёт больше одного такта АЦП. Вот код автора Код void adc_init(void) { ADMUX = (1<<REFS0)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1); ADCSRB = 0x00; ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); } В первой строчке он изменяет мультиплексор. В третий дает старт АЦП. АЦП стартанет не с этим состояние мультиплексора, а в это состояние он придет после первого преобразования. А после первого преобразование обнаружится, что и опора сменилась. Вот и еще одно потерянное преобразование. А это мое ИМХО
--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
|
|
|
|
|
Jul 1 2009, 11:24
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
А вот и нет. Цитата the reference voltage can be made more immune to noise by connecting a capacitor between the AREF pin and ground. VREF can also be measured at the AREF pin with a high impedance voltmeter. Бангап также подключается (проходит) через АРЕФ. И емкость на этом выводе убьет быстродействие. Кстати и это напряжение есть функция питающего напряжения. А раз опора - питающее напряжение - то точность хуже не станет. Вернее станет, но не настолько.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Jul 1 2009, 11:29
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Всем спасибо. Работает ниже приведу код: Код ... static volatile unsigned int value_ADC; ...
void adc_init(void) { ADMUX = (1<<REFS0)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1); ADCSRB = 0x00; ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS0); }
main(void) { unsigned char V_BAT; float f_bat; ... adc_init(); ...
while(1) { ... for (i=0;i<5;i++) { ADCSRA=0x87; DelayMs(1); while((ADCSRA&(1<<ADSC))!=0); ADCSRA=0xC7; } value_ADC= ADC; f_bat=(1.1*1024/value_ADC); V_BAT=(f_bat*100) - 250; // отнимаю 250 для того, чтоб результат уложился в восемь бит (так нужно) ... } } Не понял: почему если объявить "value_ADC" локально и, как "unsigned int" программа не работает. Вообще виснет и фик его знает где. Всем большое спасибо! Палычу и DpInRock - вселенский респект! По поводу точности могу сказать следующее: С закороченым AVCC на VBAT, без конденсатора на AREF - больше, чем на 0,04-0,08 вольта АЦП не врал. (это при том, что я меряю 3,6вольтовую сборку аккумов) Мои цели, такой точностью, замечательно достигаются.
Сообщение отредактировал Буратино - Jul 1 2009, 11:50
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jul 1 2009, 12:03
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Буратино @ Jul 1 2009, 14:29)  Код ... while(1) { ... for (i=0;i<5;i++) { ADCSRA=0x87; DelayMs(1); while((ADCSRA&(1<<ADSC))!=0); ADCSRA=0xC7; } ... } } Ну-у-у... Странная конструкция... Вы пять раз запускаете преобразование, и только последний результат берёте (да и тот сразу после последнего пуска!)... За что боролись? Вроде бы получить верное измерение с первого (ну, может быть, со второго) раза. Выключения АЦП (сброса ADEN) в программе не наблюдается... Регистр ADCSRA в main портится: в init задаётся (1<<ADEN)|(1<<ADPS2)|(1<<ADPS0) в main (1<<ADEN)|(1<<ADPS2)| (1<<ADPS1)|(1<<ADPS0). Присваивать регистрам константы (типа 0x87, 0xC7) - моветон! Имхо, если АЦП не выключать, то этот кусок программы можно записать так Код ... while(1) { ... for (i=0;i<5;i++) { ADCSRA|= (1<<ADSC); while((ADCSRA&(1<<ADSC))!=0); } ... } } (Р.S. думаю, что и for здесь лишний, раз не выключаете АЦП) Или ADEN всё-таки сбрасывается\устанавливается, но не приведено здесь? Цитата(Буратино @ Jul 1 2009, 14:29)  По поводу точности могу сказать следующее: С закороченым AVCC на VBAT, без конденсатора на AREF - больше, чем на 0,04 вольта АЦП не врал. Из документации не видно от чего зависит истинное значение Vbg. Может быть от партии к партии МК оно разное, от температуры, питающего напряжения, фиг его знает от чего ещё...
|
|
|
|
|
Jul 2 2009, 06:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Палыч @ Jul 2 2009, 09:14)  Плавающая запятая - не напрягает? Или ресурсов - валом? Наверное лучше было бы как-то так:
V_BAT=(112640L / value_ADC) - 250; Да, спасибо. И еще последнее: все таки после "ADCSRA |= (1<<ADEN);" в реальной программе проходит время. Около 2-5ms. Включается "ацепометр" сразу после выхода из режима сна, потом проделывается определенная работа ,и только потом запускается сам процесс преобразования "ADCSRA|= (1<<ADSC);"
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|