Можете ли вы определить, почему после операции вычитания или сложения с отрицательным числом значение флага С является дополнением к биту заема?
Подсказка: вспомните правила двоичной арифметики в дополнительных кодах (стр. 22).
Решение
Операция вычитания во всех микроконтроллерах PIC реализована одинаково: байт данных переводится в дополнительный код, а затем выполняется сложение, как показано на Рис. 2.9 на стр. 39. В этой ситуации итоговый бит переноса равен 0, если результат сложения получается отрицательным, и 1, если положительным. Например:
1. 06 — 0А —> 00000110 + 11110110 = (0) 11111100 или -4 (нет переноса).
2. 0А — 06 —> 00001010 + 11111010 = (1) 00000100 или +4 (есть перенос).
В обоих случаях флаг переноса соответствует инвертированному биту заема. Такое поведение соответствует философии RISC PIC-микроконтроллеров — процессор должен быть максимально простым и понятным.
Точно такая же инверсия происходит при использовании отрицательного операнда в командах сложения, например в команде addlw -6. Это выражение будет преобразовано транслятором в addlw h’FC’, где h’FC’, конечно же, представляет собой дополнительный код числа 6.
Один умник решил скопировать содержимое регистра STATUS в регистр h’40’, с тем чтобы использовать его в дальнейшем. Однако бит 2 регистра STATUS оказался сброшен в 0. Почему?
Решение
Из текста на стр. 67 мы узнали, что команда movf устанавливает флаг Z, если содержимое регистра-адресата равно нулю, в противном случае флаг Z сбрасывается. Так что следующий фрагмент программы
movf STATUS,w; Скопировать содержимое регистра h’03’(STATUS) в W,
movwf h’40’; а потом в регистр h’40’
действительно скопирует содержимое регистра h’03’ в регистр h’40’. Но до тех пор, пока все биты регистра STATUS не будут равны нулю, флаг Z будет постоянно сбрасываться. При нормальной работе флаги
Разумеется, это ограничение можно обойти. Одно из таких решений показано на стр. 217.
Как бы вы задали следующую конфигурацию некоторых РСН из 1-го банка:
• OPTION_REG b’10101111’
• TRISA b’00011110’
• TRISB b’11111111’
Решение
Поскольку все три регистра находятся в 1-м банке, нам необходимо будет переключить банки перед записью данных и переключиться на 0-й банк после конфигурирования регистров.
STATUS equ 3; Регистр STATUS расположен по адресу h’03’
RP0 equ 5; Бит RP0 — 5-й
OPTION_REG equ h’81’; Регистр OPTION_REG расположен по адресу h’81’
TRISA equ h’85’; Регистр направления порта
TRISB equ h’86’; Регистр направления порта
bsf STATUS,RP0 ; Переходим к 1-му банку
movlw b’10101111’ ; Первую константу
movwf OPTION_REG; в регистр OPTION_REG
movlw b’00011110’; Вторую константу
movwf TRISA; в TRISA
movlw b’11111111’; Третью константу
movwf TRISB; в TRISB
bcf STATUS,RPO; Возвращаемся к 0-му банку
Напишите программу для инкрементирования упакованного BCD-числа, находящегося в памяти данных по адресу h’20’.
Решение
Два двоично-десятичных (BCD) разряда можно
Из приведенных примеров можно увидеть, что если после инкрементирования какого-либо разряда BCD-числа он равен 10, то необходимо его обнулить, а к старшему разряду прибавить единицу. Воспользовавшись этим рассуждением, сформулируем перечень задач, которые должна выполнять наша программа:
1. Инкрементировать BCD-число по правилам обычной двоичной арифметики.
2. Если младший полубайт результата равен 10, прибавить к результату число 6.
3. Если старший полубайт результата равен 10, прибавить к нему число 6.