II
"РЛ" - НАЧИНАЮЩИМ
II
Глава 28. Подводные камни
и изюминки программирования
В этой главе мы коснемся некоторых моментов, ко-
торые хотя и редко возникают, но способны немало
попортить кровь начинающему программисту-разра-
ботчику микроконтроллерных устройств. Как правило,
подобные ситуации возникают из-за недостаточно глу-
бокого понимания процессов, происходящих “внутри”
аппаратных устройств микроконтроллера, но иногда
могут быть связаны и с внешней “обвязкой”. Постара-
юсь подготовить вас заранее.
Прежде всего, давайте рассмотрим работу с 16-раз-
ряджными регистрами, которых, как вы знаете, в мик-
роконтроллере несколько - счетчики таймеров, RCAP2
и DPTR. Последний регистр вряд ли способен доста-
вить вам неприятности, чего не скажешь о первых.
Так как ядро микроконтроллера 8-разрядное, то
считывание и запись 16-разрядных регистров осуще-
ствляется побайтно, т.е. сначала младший байт, за-
тем старший (или наоборот). Счетчики таймеров из-
меняют свое значение аппаратно, то есть независимо
от действий программы (если таймер включен, разу-
меется). Давайте рассмотрим следующий пример: нам
необходимо считать значение счетчика TimerO, к мо-
менту считывания таймер работает, и его счетчик со-
держит значение 01 FFh. Для считывания мы исполь-
зуем следующий код:
MOV
DPH, ТНО
MOV
DPL, TL0
Как вы считаете, какое значение в DPTR будет пос-
ле выполнения этого кода? Если вы думаете, что 01 FFh
- то вы ошибаетесь, DPTR будет содержать 0201 h, что
на 2 больше, чем желаемое значение. Увеличение зна-
чения относительно истинного в данном случае пол-
ностью предсказуемо и равно числу тактов, в течение
которых исполняется команда считывания младшего
байта счетчика. Мы имеем дело, во-первых, с неболь-
шой, а во-вторых, с легко корректируемой погрешно-
стью, т.е. вполне можем либо ею пренебречь, либо
скорректировать ее математически. Если же для счи-
тывания счетчика таймера мы применим следующий
код:
MOV
DPL, TLO
MOV
DPH, THO
to
DPTR будет содержать уже .
.. 02FFh! А такая “по-
грешность” просто недопустима. Возникает она в силу
того, что к моменту копирования значения в DPH счет-
чик таймера уже содержит число 0201 h (таймер-то про-
должает считать, пока мы выполняем свои команды!).
Вот и получается, что DPL содержит старое значение
TLO, a DPH - уже новое значение ТНО!
Роман Абраш
^
v I I I
г
I
/
г. Новочеркасск
E-mail:
arv@radioliga.com
Если вы убеждены, что при считывании первым
способом мы всегда будем получать почти правиль-
ное значение (точнее, значение с прогнозируемой по-
грешностью), то и тут вы ошибаетесь! Ведь между ко-
мандами вполне могло возникнуть прерывание, а зна-
чит, к моменту выполнения второй команды таймер
мог насчитать неизвестно сколько! И погрешность в
этом случае будет уже такой, что попросту сведет на
нет любые попытки адекватного анализа считанного
значения.
Из подобной ситуации есть два выхода:
1. Останавливать таймер перед тем, как считывать
его значение.
2. Запрещать прерывания на время считывания зна-
чения таймера и использовать при этом первый метод.
Выбор конкретного варианта остается за вами. Вы-
бирая, вы должны помнить, что в первом случае вы по-
лучаете максимально точный результат при любой пос-
ледовательности считывания регистров, но можете на-
рушить синхронизацию работы вашего устройства
(ведь таймер на время останавливается, значит, иска-
жается и период возникновения прерываний от него).
Во втором случае вы рискуете получить лишнюю за-
держку в обработке важных прерываний, например от
внешних сигналов. Комбинация обоих способов даст
вам минимум проблем со значением счетчика и макси-
мум проблем в остальном. Ищите компромисс ©!
Похожая проблема может быть и с записью в счет-
чик таймера без его предварительной остановки, что
может требоваться в обработчике прерываний по пе-
реполнению. В момент входа в обработчик прерыва-
ния по переполнению таймера его счетчик всегда со-
держит 0 в старшем байте и некоторое число (не боль-
ше 8) в младшем, что мы должны учитывать при об-
новлении его значения. В большинстве случаев мож-
но безопасно записывать новые значения старшего и
младшего байтов счетчика в произвольном порядке,
но в некоторых случаях порядок имеет значение: ре-
комендуется всегда сначала заносить значение в ТН,
а затем в TL, причем делать это подряд идущими ко-
мандами. Во всех разумных случаях зто даст наибо-
лее точный период переполнения таймера (под нера-
зумным случаем я подразумеваю занесение в счет-
чик значения в диапазоне 0FFFD.
..0FFFFh внутри об-
работчика прерывания - вы понимаете, что в этом слу-
чае переполнение счетчика произойдет еще до завер-
шения обработчика, в какой последовательности не
заноси значения).
Аналогичные ситуации возможны и при чтении
RCAP2, только тут проблема не в переполнении тай-
мера, а в возможном возникновении “захвата”, что мо-
жет привести К считыванию в один байт из “дозахват-
ного” значения RCAP2, а в другой - уже из захваченного.
В режимах Тнпег2, когда значение RCAP2 аппаратно
38
У Радиолюбитель - 0 3 /2 0 0 8
предыдущая страница 38 Радиолюбитель 2008-03 читать онлайн следующая страница 40 Радиолюбитель 2008-03 читать онлайн Домой Выключить/включить текст