Выбрать главу

В дальнейшем мы будем игнорировать команду sublw и использовать вместо нее addlw. Вообще-то мы уже так делали в Программе 5.2, где нам было нужно вычесть константу h’80’ из W. Ассемблер просто преобразует отрицательное число в его эквивалент в дополнительном коде, например, вместо addlw — 6 будет addlw h’FA’.

* * *

Одной из наиболее важных операций является операция сравнения двух чисел. С математической точки зрения это можно сделать при помощи вычитания байта (обозначаемого ниже как [f] и для регистра данных, и для константы) из содержимого рабочего регистра [W]. Результат [W] — [f] представляет реальную разность величин операндов. Однако в большинстве случаев достаточно определить отношение между величинами, т. е. узнать, не больше ли W, чем байт данных? Для этого необходимо контролировать состояния флагов С и Z регистра STATUS.

Рабочий регистр больше, чем байт данных… нет заема, не ноль

Рабочий регистр равен байту данных… ноль

Рабочий регистр меньше, чем байт данных… заем, не ноль

В нашем процессоре флаг С является дополнением к биту переноса, а флаг Z устанавливается при нулевом результате. Таким образом:

[W] больше, чем или равно [f]: [W] — [f] дает отсутствие заема (С = 1).

[W] равно [f]: [W] — [f] дает ноль (Z = 1).

[W] меньше, чем [f]: [W] — [f] дает заем (С = 0).

Эти варианты приведены на Рис. 5.11, где показано сравнение значения, находящегося в W, с содержимым регистра h’36’. Команда subwf h’36’,w формирует разность и изменяет флаги Z и С, как показано на рисунке. Собственно, разность двух чисел, находящаяся в W, нас не интересует, однако она перезаписывает исходное содержимое, которое может потребоваться сохранить перед сравнением.

Рис. 5.11. Сравнение содержимого W и регистра данных командой subwf h’26’

Рассмотрим следующий пример. Имеется топливная цистерна объемом 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), так что пропускаем