Рассмотрим следующий пример. Имеется топливная цистерна объемом 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
; Считываем значение уровня топлива в Waddlw -5
; FUEL — 5. ЕСЛИ БОЛЬШЕ ИЛИ РАВНО,btfss STATUS,С
; ТО заема не будет (С == 1), так что пропускаемbsf DISPLAY,BUZZ
; ИНАЧЕ включаем пищалкуmovf FUEL,W
; Снова считываем значение уровня топлива в Waddlw — 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 дает в результате исходный бит.
Используя эти свойства, мы можем обнулять группы битов в байте данных посредством логического умножения этого байта на соответствующую битовую маску.