|
Если
пишете программу на ассемблере,
используйте символические имена из .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 не сбросится.
|