і
"РЛ" - НАЧИНАЮЩИМ
|}
считывается, надо быть осторожными при записи но-
вых значений в ЯСАР2, надеюсь, это уже вам понятно
и без дополнительных пояснений.
В общем, универсальный совет для работы с двух-
байтными регистрами таймеров, следующий - оста-
навливайте таймер при любых модификациях его ре-
гистров! Если это нежелательно, придется скрупулез-
но разрабатывать свою программу, предусматривая
модификацию (или считывание) только в “безопасные”
моменты. Например, вы ведь заранее можете пред-
сказать диапазон длительностей, формируемых тай-
мером в вашем конкретном случае, и скорее всего он
не будет простираться от минимального до максималь-
ного возможных значений счетчика, следовательно,
всегда найдется момент, когда можно считать значе-
ние регистра без угрозы его аппаратного изменения в
процессе чтения.
Еще одна проблема может быть с многобайтными
значениями переменных, если они изменяются в обра-
ботчике прерываний, а считываются в основном теле
программы (или наоборот). Источник проблемы все в
том же: в процессе считывания нескольких байтов од-
ной переменной может произойти прерывание, изме-
няющее ее значение, и тогда результат считывания не-
предсказуем. Выход тут только один - запрещать пре-
рывания на время обращения к такой переменной, при-
чем лучше всего как при считывании, так и при записи.
Это гарантирует однозначность ее значения.
Небольшое дополнение. Иногда можно позволить
себе проверять на корректность считанное значение хоть
16-разрядных регистров, хоть многобайтных перемен-
ных по следующему алгоритму: значение необходимо
считать дважды и вычислить разность между ними. Если
эта разность лежит в допус тимых пределах (которые лег-
ко вычисляются по длительности выполнения команд
считывания), значит изменения переменной (регистра)
аппаратными средствами или прерываниями не было.
Если же разность слишком велика, значит, во время счи-
тывания произошло изменение переменной (или регис-
тра) - надо считать значение еще раз. Например, в слу-
чае считывания счетчика таймера можно поступить так:
М1:
MOV
А
,
ТНО
MOV
в.
TL0
CJNE
А,
ТНО
; А,В содержат корректное значение
; счетчика таймера О
Приведенный пример кода использует проверку
только значения ТНО: если оно не изменилось, зна-
чит, ТЮ не переполнялся, т.е. считанное только что
значение - верное. Используя этот код, надо помнить,
что он склонен к зацикливанию, если прерывания воз-
никают очень часто.
Еще один подводный камень заключается в особен-
ности применения операций “чтение-модификация-за-
пись” для работы с портами ввода-вывода. Давайте рас-
смотрим следующий пример: порт Р2.0 используется
для управления транзистором по следующей схеме
(рис. 22). На этой схеме сиг-
нал на базу транзистора по-
дается сразу без токоограни-
чительного резистора, т.к.
роль ограничителя тока ус-
пешно играет внутренняя схе-
ма порта, о чем я говорил в
одной из первых глав.
Чтобы транзистор открылся, мы должны вывести в
порт Р2.0 единицу. Теперь подумайте и ответьте, чему
будет равно значение С после выполнения следующих
команд:
SETB
Р2.о
NOP
MOV
С, Р2.0
“Разумеется, единице!” - скажут многие и будут не
правы! Команды, считывающие значения с выводов
контроллера, всегда возвращают фактически присут-
ствующий на них уровень: помните, об этом я говорил
в самом начале? Первая команда откроет транзистор,
напряжение на его базе будет не более 0,6 В, следо-
вательно, значение С будет равно нулю. Кстати, об-
ратите внимание на команду NOP: очень часто она тре-
буется в подобных случаях для того, чтобы сигналы
во внешних цепях установились, иначе возможно счи-
тывание в то время, когда сигнал еще изменяется (не
забывайте, что ток высокого уровня порта очень мал
и не может быстро изменить напряжение в цепи, осо-
бенно при емкостной нагрузке).
Теперь ответьте, как будет вести себя схема при
выполнении следующего кода:
Ml:
СРЬ
Р2.0
тар
М1
Команда СР1. работает по схеме “чтение-модифика-
ция-запись”, т.е. сначала считывает значение бита, за-
тем его инвертирует, а затем уже выводит новое значе-
ние. Казалось бы, при чтении Р2.0 команда всегда будет
получать 0, инвертировать его и выводить 1, т.е. схема
не изменит своего состояния никогда, однако, зто не так!
Вы можете собрать схему, запрограммировать указанный
код и убедиться, что сигнал на Р2.0 будет периодически
меняться! Как же так?! Дело в том, что все команды, ра-
ботающие по принципу “чтение-модификация-запись” (а
это, помимо СР1-, все логические команды, в которых опе-
ранд-приемник - порт или ячейка памяти, а так же иВС),
при работе со значениями портов используют
не реаль-
но считанное с вывода значение, а
то значение, которое
было выведено в порт ранее
(оно хранится в отдельном
триггере-защелке, входящем в состав порта). Знание это-
го нюанса позволит избежать разного рода недоразуме-
ний при практической работе с портами.
А теперь немного того, что я называю изюминками
программирования, т.е. нетипичными способами реа-
лизации тех или иных задач. Все эти изюминки оче-
видны для профессиональных программистов, но для
начинающих могут оказаться достаточно заниматель-
ными. Вам может показаться, что во многих случаях
Радиолюбитель - 0 3 /2 0 0 8 У
39
предыдущая страница 39 Радиолюбитель 2008-03 читать онлайн следующая страница 41 Радиолюбитель 2008-03 читать онлайн Домой Выключить/включить текст