Рассмотрим следующий пример. Имеется топливная цистерна объемом 255 л, на дне которой установлен датчик, показывающий оставшееся количество топлива как линейную функцию от давления. Предположим, что значение выходного сигнала датчика представляется в виде байта, считываемого с порта В (см. стр. 105), который мы назовем FUEL. Нам нужно написать процедуру, которая будет включать световой сигнал «Пусто» (бит 0 порта А), если в цистерне осталось меньше 20 л, и включать звуковой излучатель (бит 1 порта А), если осталось меньше 5 л (см. Рис. 5.12). Активный уровень на обоих выходах — ВЫСОКИЙ. Эта задача может быть реализована следующим образом:
STATUS ecu 3; Регистр STATUS расположен по адресу h’03’
С equ 0; Флаг переноса — 0-й бит
Z equ 2; Флаг нуля — 2-й бит
FUEL equ 6; Уровень топлива можно считать из регистра h’06’ (порт В)
DISPLAY equ 5; Порт А — регистр h’05’
LAMP equ 0; Сигнальная лампочка управляется 0-м битом
BUZZ equ 1; Звуковой излучатель управляется 1-м битом
ALARM
bcf DISPLAY,BUZZ; Выключим пищалку
bcf DISPLAY,LAMP; Выключим лампочку
movf FUEL, w; Считываем значение уровня топлива в W
addlw -5; FUEL — 5. ЕСЛИ БОЛЬШЕ ИЛИ РАВНО,
btfss STATUS,С ; ТО заема не будет (С == 1), так что пропускаем
bsf DISPLAY,BUZZ; ИНАЧЕ включаем пищалку
movf FUEL,W; Снова считываем значение уровня топлива в W
addlw — d’20’; FUEL — 20. ЕСЛИ БОЛЬШЕ ИЛИ РАВНО,
btfss STATUS,С; ТО заема не будет <С == 1), так что пропускаем
bsf DISPLAY.LAMP; ИНАЧЕ включаем лампочку
NEXT:
... ...;
Рис. 5.12.
После каждого вычитания флаг переноса будет равен 1 (т. е. нет заема), если число в рабочем регистре (количество топлива) больше или равно значению константы, с которым оно сравнивается посредством вычитания. Обратите внимание на использование команды bsf для установки соответствующих битов порта А (предполагается, что эти линии уже сконфигурированы как выходы). Точно так же команда bcf используется для выключения светового сигнала и звукового излучателя в самом начале процедуры.
К операциям сравнения можно отнести и операцию проверки, во время которой байт данных проверяется на равенство нулю. Мы уже видели (см. стр. 67), что содержимое любого регистра данных можно проверить на нулевое значение простым копированием его в себя самого, например movf h’36’,f. Если в регистре находится нулевое значение, то флаг Z установится в 1[85]. Аналогичная проверка рабочего регистра может быть выполнена прибавлением к нему нуля, т. е. addlw 0. Эта команда установит флаг Z при нулевом значении в рабочем регистре, не изменяя его содержимого.
Микроконтроллеры PIC могут выполнять все четыре базовые логические операции — НЕ, И, ИЛИ и Исключающее ИЛИ, как показано в Табл. 5.3.
Операция НЕ
Логическая функция НЕ, показанная на Рис. 1.1 (стр. 26), инвертирует (формирует обратный код) логическое состояние входа.
∙ comf
С помошью этой команды можно инвертировать содержимое любого заданного регистра данных. Так, команда comf h’26’,f вычисляет обратный код содержимого регистра h’26’:
Как обычно, результат может быть помещен либо в исходный регистр данных, либо в W (в последнем случае исходное содержимое остается неизменным), например:
В микроконтроллерах PIC отсутствует команда типа comw для инвертирования содержимого рабочего регистра, однако эту операцию можно выполнить за один машинный цикл посредством вычитания W из числа b’11111111’, что дает в результате тот самый обратный код, т. е. sublw h’FF’. Например (см. также стр. 147):
Операция И
Из Рис. 1.2 (стр. 27) можно увидеть следующие соотношения:
• Логическое И любого бита и 0 всегда дает в результате 0.
• Логическое И любого бита и 1 дает в результате исходный бит.
Используя эти свойства, мы можем обнулять группы битов в байте данных посредством логического умножения этого байта на соответствующую битовую маску.