На чем набиваются шишки, или тонкости МК AVR

(-: написано в основном на собственном опыте :-) 


Если пишете программу на ассемблере, используйте символические имена из .def файлов, а не константы! При переносе программ на другой МК требуемые биты в регистрах ввода-вывода могут оказаться в другом месте! Пример из собственного опыта. Разрешил прерывание по переполнению таймера 0 (для МК 8535) следующим образом:

ldi R16,1
out TIMSK,R16

и потом долго не мог понять, почему эта программа не работает после переноса на МК 8515. У которого бит разрешения прерывания таймера 0 не TIMSK.0, как у 8535, а TIMSK.1

написал бы вот так:

ldi R16, 1<<TOIE0

и сэкономил бы тот час, который искал - почему не работает отлаженная давным-давно процедура обработки прерывания. Кстати, то же самое относится и к векторам прерываний!


Если устройство должно потреблять минимум энергии и оно по алгоритму работы может находиться в режиме power down, то, во первых, перед входом в этот режим отключите ненужную периферию (например, АЦП - оставленный включенным, он потребляет не менее 2 мкА). 

Аналоговый компаратор почему-то по умолчанию, то есть по сбросу - включен! Следовательно, его надо тоже выключить.


При работе с флагами надо помнить о следующих тонкостях:

Во первых, проверка флага в команде ветвления имеет вид

sbrc регистр,Nфлага

где Nфлага - это число от 0 до 7, порядковый номер бита в регистре. А установка и сброс флагов производятся командой с мнемоникой

sbr регистр,маска

где маска - это... проще напишем так - для бита 0 это 0x01, для бита 1 это 0x02, для бита 2 это 0x04 и так далее. Это затрудняет написание читабельной программы - если дать флагу имя, то в при проверке все получается красиво, а при установке - надо будет написать

sbr регистр,1<<Nфлага

что, на мой взгляд, некрасиво и путано. К тому же - важно! - надо иметь в виду, что команда sbr это просто команда or ! То есть - она модифицирует флаги состояния МК, что по мнемонике вовсе не очевидно. Правда, дает возможность установить сразу несколько флагов.

Вообще в AVR множество команд (точнее-мнемоник) написаны, на мой взгляд, только для того, чтобы гордо заявить в даташите - 118 команд! :-) на самом деле их минимум на треть меньше. Не верите? Проверьте! напишите, например,

ser R16
ldi R16,$FF

clr R1
eor R1,R1

bset 0
sec

откомпилируйте и сравните коды этих команд.


Команда COM Rd процессора не просто "переворачивает" биты - она вычисляет их как Rd=($FF-Rd). Результат тот же, но при этом устанавливается бит переноса C! Что из мнемоники команды вовсе неочевидно.


У МК Tiny15, который работает со встроенным RC генератором, калибровочный байт при включении не заносится в регистр OSCCAL! Хотя, казалось бы по логике... В результате, если это не сделать самому, МК будет работать на изрядно заниженной частоте.

Вообще-то это очень неудобно. Калибровочный байт можно прочесть только программатором (кстати, в первых версиях даташита команда чтения калибровочного байта для SPI режима не указана!), после чего вставить в программу. Следовательно, программа будет меняться для каждого конкретного экземпляра МК! Можно, конечно, копировать калибровочный байт в EEPROM... Но все равно, на мой взгляд - криво.


Вот недавно еще на одной тонкости обломался... Это относиться к "стандартному" AVR,  как обстоит дело у более новых - mega и tiny - пока что не успел посмотреть.

Оказывается, если USART принял байт с ошибкой стоп-бита, то флаг приема RXC он тоже выставит, вместе с флагом ошибки FE ! То есть, если вы работаете с каналом, на котором реальны помехи, то проверять FE обязательно!

Да, если флаг FE установлен (то есть байт по сути не принят, а принято черт знает что) то регистр UDR прочесть все-таки надо. Просто прочесть. Иначе флаг RXC не сбросится.


печать на футболках розница ·· У нас круглые матрасы сложные формы ·· продажа нива шевролет ·· магазин алмер ·· рено логан black

 

(с)nml 11-Jul-2009