Основное тело обработчика прерывания разбито на секции в соответствии с составленным алгоритмом. После каждого инкрементирования из нового значения вычитается константа, равная основанию счета. Если эти значения равны, регистр обнуляется и инкрементируется следующий байт числа. Вместо проверки флага нуля можно было бы контролировать значение флага переноса, проверяя, чтобы полученное значение было равно или больше значения основания, btfss STATUS,С[106].
В примере предполагается, что данные хранятся в упакованном BCD-формате. То есть число 59 хранится в виде h’0101 1001’ или h’59’. Это означает, что операция инкрементирования должна соответствовать формату BCD. Эту коррекцию можно осуществить после обычного инкрементирования, проверяя, чтобы младший полубайт не стал больше девяти. В противном случае к числу прибавляется шесть. Поскольку число не может принимать значения более 59, нам не нужно выполнять аналогичную проверку для старшего полубайта. С алгоритмом полного инкрементирования упакованного BCD-числа можно познакомиться в Примере 4.5 на стр. 111.
Поскольку эту операцию надо выполнить 3 раза (для всех байтов, исключая JIFFY, который никогда не становится больше девяти), лучше всего оформить ее в виде подпрограммы. Код такой подпрограммы приведен в Программе 7.5. В данном случае регистр FSR указывает на регистр, который содержит подлежащее инкрементированию упакованное BCD-число. Это значение просто инкрементируется непосредственно в регистре с использованием косвенной адресации. После этого оно корректируется описанным выше способом. Предполагается, что данные, на которые указывает FSR, уже находятся в BCD-формате, т. е. в подпрограмме отсутствует преобразование натурального двоичного числа в двоично-десятичное.
; *************
; * ФУНКЦИЯ: Прибавляет 1 к упакованному BCD-числу (98 макс) *
; * ВХОД: FSR указывает на регистр с числом *
; * ВЫХОД: BCD-число инкрементируется *
; * W и STATUS изменяются *
; *************
BCD_INC incf INDF,f; Прибавляем 1 к адресованному байту
movf INDF,w; Считываем его
addlw 6; Прибавляем шесть
btfss STATUS,DC; Проверяем десятичный перенос
goto BCD_EXIT; ЕСЛИ нет, ТО выходим
movwf INDF; ИНАЧЕ возвращаем скорректированное значение
BCD_EXIT return
В торговом автомате монеты разных номиналов проходят через один из шести микропереключателей, подключенных к порту В. При прохождении монеты переключатель замыкается, что вызывает появление на соответствующем выводе сигнала НИЗКОГО уровня, как показано на Рис. 7.8.
Напишите процедуру обработки прерывания, которая будет накапливать значение суммы в регистре MONEY. Предполагается, что в фоновой программе регистр INTCON будет сконфигурирован таким образом, чтобы разрешить внешнее прерывание с вывода RB0/INT.
Рис. 7.8.
Решение
Как показано в Программе 7.6, после сохранения контекста и сброса флага INTF производится последовательная проверка всех переключателей. НИЗКОМУ уровню на каком-либо выводе порта соответствует лог. О в соответствующем бите регистра PORTB. В соответствии с логикой работы механизма монетоприемника одновременно может быть замкнут только один переключатель, поэтому нет необходимости выходить из процедуры после неудачного поиска.