Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
24.07.2011, 13:20
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 9
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
AVR, UART и режим IDLE
Всем привет!
Имеется девайс, который должен в основное от работы время жрать как можно меньше, но с возможностью обмена данными с компом через интерфейс UART (через USB-UART переходник). Девайс просыпается 16 раз в секунду, делает некие ненпряжные замеры и опять ложится спать до следующего подъёма.
Идея была такая: если нет долго сигналов по UART, то засыпаем "как следует" (режим POWER_SAVE). Если обнаруживаем, что нас тыркают через UART, на некоторое время заменяем POWER_SAVE на режим IDLE, потому как по документации в режиме IDLE подсистема UART продолжает работать.
Пока же реализовал режим исключительно IDLE. И сразу напоролся на проблему.
Частенько байты пролетают "мимо кассы". То есть байт послан, а до микроконтроллера он не дошёл. Весь обмен через UART реализован на прерываниях, то бишь, в случае прихода байта, по идее, микроконтроллер автоматически должен будиться и тут же "ловить" приехавший байт (скорость 9600 бод, частота МК 1 МГц, должен успевать не напрягаясь).
Однако на практике вижу часто ситуации, когда посылается пакет A,B,C,D а МК "видит" только A, B, D.
Если вместо cpu_sleep() воткнуть просто _delay_ms (1000/16), то всё работает шоколадно, никакие байты не проглатываются.
Я чего-то упустил, или это баг микроконтроллера?
|
|
|
|
24.07.2011, 13:26
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Вы где-то что-то упустили...
Сообщение от anpaza
|
посылается пакет A,B,C,D а МК "видит" только A, B, D.
|
Первый и второй байт у вас проходит без ошибок...
|
|
|
|
24.07.2011, 15:10
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 9
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Да, именно так - просто произвольный байт "выпадает" из серии, такое ощущение что он принимается, но прерывание не вызывается. Не могу поверить, что байт теряется из-за ошибки - если вместо режима IDLE использовать обычный _delay_ms, никаких ошибок приёма нет.
|
|
|
|
24.07.2011, 15:26
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: AVR, UART и режим IDLE
МК здесь не при делах...
ИМХО, вы с переменными накосячили... в частности не использовали квалификатор volatile...
|
|
|
|
24.07.2011, 18:12
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 9
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Если бы проблема была в volatile, программа бы глючила каждый раз одинаково.
Я кажись нащупал в чём дело. У меня почти сразу после команды cpu_sleep() стояла cli(). То есть общий вид цикла такой:
Код:
|
int main ()
{
...
for ( ; ; )
{
set_sleep_mode (SLEEP_MODE_IDLE);
sleep_enable ();
sleep_cpu ();
sleep_disable ();
cli ();
// здесь делаем замеры и подсчёты через АЦП
sei ();
}
} |
Вся обработка UART (приём и передача) выполняется, как я говорил, полностью в прерываниях.
Если закоментировать cli и sei то входящие байты не теряются. Посылаемые МК байты, кстати, не теряются никогда.
Вижу пока такое объяснение: в МК аппаратный баг (МК, кстати, атмега48 ), который проявляется следующим образом: если во время спячки возникает прерывание UART, и через несколько команд после команды SLEEP есть команда cli(), то он после просыпания успевает сделать несколько шагов (спросонья ), доходит до cli() и каким-то образом теряет прерывание. Подтверждение этому в том, что если заменить cpu_sleep() на _delay_ms(), байты не теряются никогда, несмотря на наличие cli.
|
|
|
|
24.07.2011, 18:17
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Как у вас во время спячки UART работает? В синхронном режиме что ли? В асинхронном он от тактового генератора работает, который в спячке остановлен.
Я в таком случае заводил линию RX на INT и будил по спаду фронта. Контроллер успевал проснуться и начать прием данных. Ничего не терялось.
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
24.07.2011, 18:36
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Сообщение от anpaza
|
Вижу пока такое объяснение: в МК аппаратный баг (МК, кстати, атмега48 )
|
Баг у вас от недопонимания работы МК, а не в самом МК...
Пересмотрите концепцию проги... нельзя произвольно запрещать прерывания и в то же время ждать неукоснительного выполнения этих самых прерываний...
|
|
|
|
24.07.2011, 18:38
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Сообщение от Easyrider83
|
Я в таком случае заводил линию RX на INT и будил по спаду фронта. Контроллер успевал проснуться и начать прием данных. Ничего не терялось.
|
Проц у него просыпается нормально... иначе терялись бы первые 1-2 байта...
|
|
|
|
24.07.2011, 18:44
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Сообщение от st_1
|
Проц у него просыпается нормально... иначе терялись бы первые 1-2 байта...
|
Это я понимаю. Я не понимаю, как он просыпается?
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
24.07.2011, 18:55
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: AVR, UART и режим IDLE
Сообщение от anpaza
|
в МК аппаратный баг (МК, кстати, атмега48 ), который проявляется следующим образом: если во время спячки возникает прерывание UART, и через несколько команд после команды SLEEP есть команда cli(), то он после просыпания успевает сделать несколько шагов (спросонья ), доходит до cli() и каким-то образом теряет прерывание
|
Этот баг у нас фичей зовется. ВСЕ контроллеры после выхода из спячки выполняют одну операцию, параллельно в фоне проверяют прерывания, и если прерывание есть - во второй операции переходят по вектору. При выходе из прерывания проц выполняет ещё одну операцию из основного цикла, после которой переходит к следующему прерыванию (если во время спячки и/или выполнения первого прерывания произошло несколько прерываний)
Читаем даташиты, там всё есть
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Литература по микроконтроллерам (AVR, PIC, ПЛИС и т.д.). Сборка книг - (256 книг+ 27 CD c примерами из книг) [обновление 2011, PDF, DJVU]
|
yurinform |
Микроконтроллеры, АЦП, память и т.д |
5 |
05.07.2011 19:00 |
Проблема правильного приема пакета UART AVR
|
Saadov |
Микроконтроллеры, АЦП, память и т.д |
16 |
27.04.2011 20:11 |
Проблема с передачей данных между avr по uart
|
code-by |
Proteus |
2 |
21.01.2011 12:24 |
Симуляция UART для AVR studio
|
mm12345 |
Микроконтроллеры, АЦП, память и т.д |
0 |
22.11.2010 15:40 |
Управление энергопотреблением и режим idle
|
day177 |
Микроконтроллеры, АЦП, память и т.д |
9 |
28.12.2007 23:53 |
Часовой пояс GMT +4, время: 06:55.
|
|