Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/25: Рейтинг темы: голосов - 25, средняя оценка - 4.92
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
1

Mega8 ADC - иногда не переключается канал

13.01.2013, 19:55. Просмотров 4441. Ответов 13
Метки нет (Все метки)

Доброго дня. Взываю к коллективному разуму, так как сам совершенно не понимаю, в чём дело. Суть проблемы: измеряю попеременно двумя каналами АЦП, но иногда (1 на 100...200) канал АЦП не переключается. В качестве пруфа результаты измерений с UART:
Код
...
#42: 51.2 25.9
#43: 51.2 25.9
#44: 51.2 26.0
#45: 26.0 25.9
#46: 51.2 25.9
#47: 51.2 25.9
#48: 51.2 25.9
...
- На первом канале явно значение второго! Проблема явно программная, с железом всё чётко.

Вот кусок кода с настройками АЦП:
Код
...
OUT   ADMUX, tmp1
OUTI   MCUCR, 0b10010000
OUTI   ADCSRA, 0b11001101
SEI
SLEEP
CLI
in      tmp1, ADCL
in      tmp2, ADCH
out      ADCSRA, zero
...
Измерения происходят каждые 1/60 сек. по таймеру, каждую итерацию канал переключается, прерывания на момент выполнения кода запрещены. Частота ядра - 4МГц, частота АЦП - 125КГц.
В чём может быть проблема? Не соблюдаю тайминги при настройке АЦП или не в том порядке пихаю значения в регистры? Пробовал ставить задержки перед включением АЦП, чтобы коммутатор успел переключиться, не помогает. В последовательности загрузки значений в регистры разницы нет, вроде бы. Главное ведь, чтобы ADMUX был загружен до запуска АЦП. Подскажите, где тут косяк!
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.01.2013, 19:55
Ответы с готовыми решениями:

Мультиплексор ADC на Mega8
Здравствуйте. Не могу сам разобраться с АЦП Меги 8. Всё симулирую в протеусе, но ничего не...

ADC mega8 Proteus
Вот такой возник вопрос, у кого-нибудь работает АЦП на ATMEGA8 в протеусе? #ymstude <avr/io.h>...

Не переключается канал wi-fi
Собственно переключаю в ручную канал wi-fi на роутере, он долго думает и делает вид, что...

Курсор иногда переключается на другую строку
Всем привет,вот такая проблема,иногда пишу пишу текст,потом курсор переключается совершенно на...

Почему иногда отслеживается нажатие на три клавиши сразу, а иногда нет
Доброй ночи, кто может объяснить почему иногда отслеживает нажатие на три кнопки сразу, а иногда...

13
_moysi
0 / 0 / 0
Регистрация: 19.11.2010
Сообщений: 790
13.01.2013, 20:21 2
задержки перед включением АЦП, чтобы коммутатор успел переключиться
Чтобы ёмкость успела перезарядиться от нового входа. Это не мгновенный процесс, задержки надо много. Для эксперимента пусть будет например секунда.

Цитата Сообщение от 8159, стр. 33
If the ADC is enabtid, a conversion storts outomatically when this mode is entered
Типа как бы обещает само запускаться при входе в слип, без дополнительных ручных манипуляций над ADCSRA. А так оно вроде как запускается и сразу ещё раз перезапускается.
По идее не страшно, но и не лишне экспериментнуть.

Прерывание ADC разрешено? Его обработчик состоит из reti? Тогда флаг ADIF должен сбрасываться автоматически при входе в прерывание, иначе его надо руками.
Другие прерывания запрещены все, просыпается по ADC строго без вариантов? ... есть ли уверенность в выполнении cli после обработки прерывания ADC? Что получается, если sei/cli вообще убрать нах?

"Копирование" второго канала в первый имеет место бывать иногда, а наоборот?

На всякий случай напомнил про снять подтяжки с порта и обратил внимание на magic numbers.

---

Самой первой строкой в продемонстрированном куске кода он меняет ADMUX. OUT ADMUX, tmp1.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.01.2013, 20:24 3
И где Вы меняете ADMUX?
0
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
13.01.2013, 20:40 4
[QUOTE="_moysi"][QUOTE="Цитата:[/QUOTE]
задержки перед включением АЦП, чтобы коммутатор успел переключиться
Чтобы ёмкость успела перезарядиться от нового входа. Это не мгновенный процесс, задержки надо много. Для эксперимента пусть будет например секунда.
Попробовал делать измерения каждую 1/10 секунды, результат тот же.
Прерывание ADC разрешено? Его обработчик состоит из reti? Тогда флаг ADIF должен сбрасываться автоматически при входе в прерывание, иначе его надо руками.
Бит ADIE устанавливается перед каждым измерением. В обработчике reti. На всякий случай бит ADIF обнуляю после измерений.
Другие прерывание запрещены все, просыпается по ADC строго без вариантов? ... есть ли уверенность в выполнении cli после обработки прерывания ADC?
А вот здесь уверенности нет. Вроде бы, после команды sleep мк загружает следующую команду (cli, в данном случае) и засыпает. Если это так, то остальные прерывания не должны обрабатываться. Этот момент уточню, спасибо.
"Копирование" второго канала в первый имеет место бывать иногда, а наоборот?
Замечен был только глюк с первым каналом, во втором всё ок.
Цитата:
На всякий случай напомнил про снять с подтяжки с порта и обратил внимание на magic numbers.
Спасибо, проверил:)
0
13.01.2013, 20:40
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
13.01.2013, 20:49 5
Цитата Сообщение от YTYOUT
И где Вы меняете ADMUX?
ADMUX меняется так: проводится серия из 64 измерений, каждое нечётное - один канал (выбирается из четырёх программно), каждое чётное - второй (для теста подключён к Vbg). После серии счётчик обнуляется и результат отправляется на вычисления. В коде всё видно:
Код
measure:   ;Get data from ADC
lds   tmp1, data+2
cpi   tmp1, meas_num
brlo   channel_sw
sts   data+2, zero
rjmp   div

channel_sw:
yms   tmp1
sts   data+2, tmp1
sbrc   tmp1, 0
rjmp   get_amps

get_volts:
lds      tmp2, param+13
cpi      tmp2, 0
brne   PC+2
ldi      tmp1, 0b01000110   ;ADC6
cpi      tmp2, 1
brne   PC+2
ldi      tmp1, 0b01000111   ;ADC7
cpi      tmp2, 2
brne   PC+2
ldi      tmp1, 0b01000011   ;ADC3
cpi      tmp2, 3
brne   PC+2
ldi      tmp1, 0b01000010   ;ADC2

OUT      ADMUX, tmp1
OUTI   MCUCR, 0b10010000
OUTI   ADCSRA, 0b11001101
SEI
SLEEP
CLI
in      tmp1, ADCL
in      tmp2, ADCH
out      ADCSRA, zero

lds      YH, data+0
lds      YL, data+1
add      YL, tmp1
adc      YH, tmp2
sts      data+0, YH
sts      data+1, YL
ret

get_amps:
OUTI   ADMUX, 0b01001110      ;1.23V (Vbg)
OUTI   MCUCR, 0b10010000
OUTI   ADCSRA, 0b11001101
SEI
SLEEP
CLI

in      tmp1, ADCL
in      tmp2, ADCH
out      ADCSRA, zero

lds      YH, data+4
lds      YL, data+5
add      YL, tmp1
adc      YH, tmp2
sts      data+4, YH
sts      data+5, YL
ret
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.01.2013, 21:19 6
На всякий случай бит ADIF обнуляю после измерений.
Код
out      ADCSRA, zero
Ottirnatively,ADIF is cleared by writing a logical one to the flag.
Код
brne   PC+2
Один уважаемый человек говорил.
За такое пожизненный подвес за яйца
Когда я 3 часа убил в поисках ошибки , я его понял.
С остальным пока разбираемся, но если Вы сами себе не будите писать комменты - через месяц сами не поймёте что написали.

Код
in tmp1,ADCSRA
sbrs tmp1,ADIF
rjmp PC-2
sbi ADCSRA,ADIF
Поставьте вместо
Код
 SEI
SLEEP
CLI
И не включайте ADIE
Посмотрите, что получится

Код
OUTI   ADCSRA, 0b11001101 = OUTI   ADCSRA, 1<<ADIM|1<<ADSC|1<<ADIE|1<<ADPS2|1<<ADPS0
И больше НИКОГДА эту хрень 0b11001101 не пишите
0
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
13.01.2013, 21:56 7
Ottirnatively,ADIF is cleared by writing a logical one to the flag.
То есть, ноль в ADIF вызывает прерывание? Значит, если поставить 1 в ADIE, мк тут же уйдёт по вектору прерывания ацп? Не очень понимаю инверсную логику в этом месте, но раз так, учту.

Код:
brne PC+2 Один уважаемый человек говорил.
За такое пожизненный подвес за яйца
Когда я 3 часа убил в поисках ошибки , я его понял.
Я бы с вами согласился, если бы было что-то типа PC+21, а дальше двух- и четырёхбайтовые операнды вперемешку. А чем вам PC+2 не угодило? Всё же наглядно, и код не перегружен лишними метками, по-моему, читается даже лучше.

Код:
in tmp1,ADCSRA
sbrs tmp1,ADIF
rjmp PC-2
sbi ADCSRA,ADIF

Здесь же вроде sbrc должно быть?
Попробовал, пока не работает, на обоих каналах нули. Но идею понял - подумаю в этом направлении, спасибо.

Код:
OUTI ADCSRA, 0b11001101 = OUTI ADCSRA, 1<<ADIM|1<<ADSC|1<<ADIE|1<<ADPS2|1<<ADPS0 И больше НИКОГДА эту хрень 0b11001101 не пишите
Лично мне всегда было удобнее писать в двоичном виде. Я прихожу в ужас от этих палочек и скобочек. Ну, здесь кому как удобнее...
0
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
13.01.2013, 22:03 8
Заработало с кодом:
Код
         in tmp1,ADCSRA
sbrs tmp1,ADIF
rjmp PC-2
cbi ADCSRA,ADIF
Значит, бит ADIF таки не инверсный?

И внезапно - каналы поменялись местами:) Что за хрень:)
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.01.2013, 22:07 9
В нормальном состоянии ADIF- сброшен.
Код
After the conversion is somplete (ADIF is high),
После окончания преобразования он уст. в 1. Фраза на почти русском означает , что сбросить флаг ADIF можно записав в данный бит 1. Если разрешено прерывание ADIE и SEI установлен- то флаг сбросится аппаратно.
Что за хрень:)
хрень 0b11001101 и ей подобная
Я прихожу в ужас от этих палочек и скобочек.
Вы знаете их можно копировать по всему тексту и вместо 1 запросто писать 0 если надо
0
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
13.01.2013, 22:52 10
А, теперь понял. Логика бита стандартная, но чтобы сбросить его, нужно записать туда 1. Это, видимо, чтобы жить было интереснее.
Вот такой код заработал:
Код
   ...
OUT   ADMUX, tmp1
OUTI   ADCSRA, 0b11010101      ;бит ADIF сбрасывается перед пуском ацп

in   tmp1, ADCSRA
sbrs   tmp1, ADIF
rjmp   PC-2

in   tmp1, ADCL
in   tmp2, ADCH
...
Каналы не путаются, наблюдал 10 минут, всё путём! YTYOUT, Спасибо большое!
Думал, что без усыпления ядра появятся помехи, а нет - качество измерений вообще не пострадало.
Ещё заметил такую вещь: канал 1 подключён к делителю на резисторах Vcc/2, и на нём железно одинаковое значение. А канал 2 подключён программно к Vbg, и значение постоянно плавает на 2-4 единицы.
Интересно однако, из-за чего появлялся глюк? Что-то подсказывает, что это какая-то проблема с прерываниями...
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.01.2013, 23:54 11
Vbg- что это?
0
Virsymkitoryx
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 37
14.01.2013, 01:47 12
Цитата Сообщение от YTYOUT
Vbg- что это?
Vbg - Bomdgap reference voltage, внутренний источник опорного напряжения. Используется с компаратором, вроде как. К нему можно подключить АЦП установкой MUX 3...0 в 1110. Иногда полезно для наладки.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
14.01.2013, 02:23 13
Тут недавно была тема , как раз про стабильность сего напряжения- почитайте
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
14.01.2013, 03:47 14
Совсем забыл.
Я бы с вами согласился, если бы было что-то типа PC+21, а дальше двух...
Вы думаете я три часа искал ошибку на переходе больше 2 . Нет, как у Вас всего лишь PC+2.
0
14.01.2013, 03:47
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.01.2013, 03:47

Openssl. Иногда вызов функций шифрования проходит нормально, иногда нет
Всем привет! Использую библиотеку openssl для шифрования / дешифрования. Генерирую ключи...

Компьютер зависает, иногда с полоской по монитору, иногда с синим экраном.
У меня такая штука с компом: включаешь компьютер, можешь подолгу за ним сидеть: играть, смотреть...

Почему иногда функции передается значение int, а иногда - нет?
1 случай: void Function_1(int* &amp; rVarOne, int* &amp;rVarTwo) { /* Какие-то операции с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.