В Программе 4.1 приведена эффективная реализация описанного алгоритма. После инкрементирования по правилам обычной двоичной арифметики к результату прибавляется число 6 и проверяется состояние флага DC. Этот флаг установится только в том случае, если исходное значение полубайта было равно десяти (h’0A’ + h’06’ = h’10’). В этом случае сумма сохраняется как необходимая коррекция, иначе производится вычитание для возврата к исходному значению. Старший полубайт (BCD-разряд) проверяется и корректируется аналогичным образом, только при этом используется уже флаг полного переноса С. Если он установлен, то результат сложения с числом h’60’ сохраняется, в противном случае это число вычитается. При необходимости флаг переноса может использоваться для установки разряда сотен, чтобы показать переполнения с 99 до 100.
Программа 4.1. Инкрементирование упакованного BCD-числа
; ****************************
; * ФУНКЦИЯ: Инкрементирует число в BCD-формате *
; * ВХОД: BCD в регистре h’20’ *
; * ВЫХОД: BCD+1 в регистре h’20’ *
; * ПРИМЕР: 10011000 (98) + 1 = 10011001 (99) *
; ****************************
STATUS equ 3; Регистр STATUS
C equ 0; Флаг переноса — бит 0
DC equ 1; Флаг десятичного переноса — бит 1
BCD equ h’20’; Исходное BCD-число — в регистре h’20’
; -----------------------------
BCD_INC
incf BCD, w; Инкрементируем число и помещаем в W
addlw 6; Прибавляем шесть
btfss STATUS,DC; Это было нужно, ЕСЛИ был десятичный перенос,
addlw -6; ИНАЧЕ не нужно
;Теперь проверим старший разряд, прибавляя к нему 6 и проверяя флаг переноса
addlw h’60’; Прибавим h’60’ (т. е. шесть к старшему разряду)
btfss STATUS,С; Это было нужно, ЕСЛИ был перенос,
addlw — h’60’; ИНАЧЕ отменяем коррекцию
; Инкрементированное и скорректированное BCD-число теперь в W
movwf BCD; Помещаем его в память
В качестве альтернативного варианта можно было бы вычитать перед инкрементированием число девять и, если в результате инкрементирования флаг Z окажется установленным, инкрементировать старший разряд, в противном случае прибавить 10. Ту же операцию следует повторить для старшего разряда.
4.1. Когда микропроцессор используется в вычислительном устройстве общего назначения, программа обычно загружается в ОЗУ, доступное как для чтения, так и для записи, и выполняется уже оттуда. Это означает, что в один момент времени в системе может выполняться текстовый редактор, а в другой — программа работы с электронными таблицами. Разумеется, это неприменимо к встраиваемым приложениям, в которых программа хранится в энергонезависимом ПЗУ какого-либо типа. Объясните, для чего так сделано, и укажите преимущества различных вариантов исполнения энергонезависимой памяти — ПЗУ (ROM), СППЗУ (EPROM) и ЭСППЗУ (EEPROM).
4.2. Микроконтроллер среднего уровня PIC16F877 имеет память программ объемом 8 Кбайт, в которой может храниться до 8192 14-битных команд, расположенных в диапазоне адресов h’0000’…h’1FFF’. Как, не прибегая к помощи команды goto, которая имеет определенные ограничения (см. Рис. 5.1 на стр. 117), можно выполнить переход к команде, расположенной в памяти программ по адресу h’1234’, из любого места программы?
4.3. Учитывая, что команда movf воздействует на флаг Z (см. Пример 4.3), как можно использовать эту команду для проверки на ноль содержимого любого регистра данных?
4.4. Из Табл. 1.1, приведенной на стр. 18, можно увидеть, что коды заглавных букв A…Z отличаются от кодов соответствующих строчных букв только значением 5-го бита, который равен 0 в случае заглавных и 1 — в случае строчных букв. Можете ли вы, используя команды, которые фактически были представлены в этой главе, написать процедуру перевода символа ASCII, находящегося в регистре h’20’, из нижнего регистра в верхний?
4.5. Используя конфигурационные значения из Примера 4.4, напишите программу, формирующую положительный импульс на выводе RA0 длительностью 4 мкс. Предполагается, что тактовая частота равна 4 МГц.
4.6. Можете ли вы написать последовательность команд, которая выдаст на вывод RA1 ВЫСОКИЙ уровень, затем сформирует на выводе RA0 четыре импульса и в завершение выставит на вывод RA1 НИЗКИЙ уровень? Не забудьте сконфигурировать регистр TRISA.
4.7. В большинстве электронных часов используется кварцевый резонатор частотой 32.768 кГц, часто называемый «часовым». Из-за больших объемов выпуска эти резонаторы имеют низкую стоимость. Хотя использование такого резонатора и снизит скорость выполнения программы, из Рис. 10.3 на стр. 306 можно увидеть, что мощность, рассеиваемая микроконтроллером, прямо пропорциональна тактовой частоте. Поэтому «часовой» резонатор является достаточно привлекательным выбором для многих экономичных приложений.