Подсчитать количество элементов, равных FF, в байтовом массиве внутренней памяти, адрес начала которого содержится в R1, а количество элементов - в R3.
Распределение ресурсов: Задача аналогична задаче 2.5.1, только сравнение происходит не с 0, а с FF. Кроме того, программа упрощается, так как оператор CJNE сам определяет, что надо делать обход операции увеличения счетчика при неравенстве байта FF, так что надобность в операторе SJMP отпадает. Пусть счетчик числа будет организован в регистре R5.
NAME COUNT1
Beg: mov r5, #00h ;обнуление счетчика числа элементов
mov r0,#ADDR1 ;загрузка в указатель адрес начала массива во внутр. памяти
mov r3,#NUMB ;загрузка в счетчик количества чисел
m1: mov a,@r0 ;пересылка в А числа из массив во внутренней памяти
cjne a,#0ffh,m2 ;сравнение байта с FF и переход на m2, если не FF
inc r5 ;увеличение счетчика на 1
m2: inc r0 ;увеличение адреса во внутренней памяти на 1
djnz r3,m1 ;вычитание из счетчика числа байт 1 и проверка его на 0, если не 0, то повтор загрузки
END
Подсчитать количество элементов, равных FFFF, в массиве двухбайтовых чисел внутренней памяти, адрес начала которого содержится в R0.
Распределение ресурсов: Задача аналогична задаче 2.5.2, только сравнение происходит не с FF, а с FFFF. Поэтому необходимо осуществить двойное сравнение и только в случае двойного совпадения можно увеличивать счетчик числа. Следует обратить внимание на оператор с меткой m4. Он предусмотрен, когда уже первое сравнение дало отрицательный результат. В этом случае надо увеличить указатель на ячейку внутренней памяти на 2. В случае, когда только второе сравнение отрицательно, надо увеличивать адрес только на 1. Пусть счетчик числа будет организован в регистре R5.
NAME COUNT3
Beg: mov r5, #00h ;обнуление счетчика числа элементов
mov r0,#ADDR1 ;загрузка в указатель адрес начала массива во внутр. памяти
mov r3,#NUMB ;загрузка в счетчик количества чисел
m1: mov a,@r0 ;пересылка в А первого числа из массива во внутренней памяти
cjne a,#0ffh,m4 ;сравнение первого байта с FF и переход на m4, если не FF
inc r0 ;увеличение адреса во внутренней памяти на 1
mov a,@r0 ;пересылка в А числа из массив во внутренней памяти
cjne a,#0ffh,m2 ;сравнение второго байта с FF и переход на m2, если не FF
inc r5 ;увеличение счетчика на 1
m4: inc r0 ;увеличение адреса во внутренней памяти на 1, если первое число не равно FF
m2: inc r0 ;увеличение адреса во внутренней памяти на 1
djnz r3,m1 ;вычитание из счетчика числа байт 1 и проверка его на 0, если не 0, то повтор загрузки
END
2.5.4. Подсчитать количество элементов, равных FF, в массиве чисел внешней памяти, адрес начала которого содержится в паре ячеек внутренней памяти ADDR1, ADDR1+1, а количество элементов - в R3.
Распределение ресурсов: Задача аналогична задаче 2.5.1, только сравнение происходит не с 0, а с FF. Кроме того, программа упрощается, так как оператор CJNE сам определяет, что надо делать обход операции увеличения счетчика при неравенстве байта FF, так что надобность в операторе SJMP отпадает. Пусть счетчик числа будет организован в регистре R5.
NAME COUNT2
Beg: mov r5, #00h ;обнуление счетчика числа элементов
mov r1,#ADDR1 ;загрузка в указатель адрес начала массива во внутр. памяти
mov r3,#NUMB ;загрузка в счетчик количества чисел
m1: mov a,@r1 ;пересылка в А числа из массив во внутренней памяти
cjne a,#0ffh,m2 ;сравнение байта с FF и переход на m2, если не FF
inc r5 ;увеличение счетчика на 1
m2: inc r1 ;увеличение адреса во внутренней памяти на 1
djnz r3,m1 ;вычитание из счетчика числа байт 1 и проверка его на 0, если не 0, то повтор загрузки
END
Работа с элементами таблицы
В табл.2.6 отражены две команды, предназначенные для чтения табличных данных, размещенных в программной памяти.
Таблица 2.6.
Команды для работы с таблицами.
Мнемоника Операция
MOVC A, @A+DPTR Чтение ПК по адресу (A+DPTR)
MOVC A, @A+PC Чтение ПК по адресу (A+PC)
С помощью этих команд, осуществляющих доступ исключительно к памяти программ, возможно только чтение таблиц, но не их изменение, мнемонически эти команды выглядят как MOVC ("move constant"). Если таблица расположена во внешней программной памяти, то чтение байта из нее сопровождается стробом (Program Store Enable).
Первая команда MOVC предназначена для обращения к таблице с максимальным числом входов - до 256 (от 0 до 255). Номер требуемого входа в таблицу загружается в аккумулятор, а регистр DPTR устанавливается на точку начала таблицы. Вторая команда MOVC работает аналогичным образом за исключением того, что в качестве указателя базы используется счетчик команд - РС и обращение к таблице производится из подпрограммы. Вначале номер требуемой точки входа загружается в аккумулятор, затем вызывается подпрограмма:
MOV A, Entry Number
CALL Table
Подпрограмма "Table" будет выглядеть следующим образом:
Table: MOVC A, @A+PC
RET
Таблица должна находится в памяти программ непосредственно за инструкцией RET, причем такая таблица может иметь до 255 точек входа (от 1 до 256). Номер 0 не может быть использован, потому что во время выполнения инструкции MOVC A, @A+PC счетчик команд содержит адрес инструкции RET, и значением точки входа "0" будет сам код этой инструкции.
2.6.1. Загрузить элемент из таблицы во внешней памяти программ - в А. Базовый адрес таблицы (её начало) содержится в ячейках внутренней памяти BАSE, BАSE+1 а номер выбираемого элемента -в А.
Распределение ресурсов: Это классический случай расположения таблицы в памяти команд. Поэтому надо использовать команду MOVC. В приведенной ниже программе в качестве базового используется регистр DPTR.
NAME TABL1
Beg: mov dptr, #BASE ;загрузка базового адреса таблицы в DPTR
movc a, @a+dptr ;пересылка байта из таблицы в А
END
2.6.2. Загрузить элемент в таблицу во внешней памяти данных - из регистра R5. Базовый адрес таблицы (её начало) содержится в ячейках внутренней памяти BАSE, BАSE+1, а номер в ячейке NUMB.
Распределение ресурсов: Этот случай похож на задачу 2.6.1, но направление передачи меняется на обратное. Так как это память данных, то запись в ячейки возможна. Однако проблема состоит в том, чтобы установить в DPTR правильный адрес элемента таблицы. Для определения текущего адреса вставки надо просуммировать содержимое DPTR и номера строки в таблице.
NAME TABL1
Beg: mov dptr, #BASE ;загрузка базового адреса
mov a,NUMB ;загрузка номера строки в таблице
add a, dpl ;сложение базового адреса с номером для получения относительного адреса
mov a,dph ;учет возникновения переноса из мл. байта
addc a, #0 ;сложение возможного переноса со старшим байтом указателя
mov dph,a ;
mov a, r5 ;загрузка в А значения для таблицы
movx @dptr,a ;заполнение ячейки таблицы значением
END
Битовые операции
Микросхемы MCS-51 содержат в своем составе "булевый" процессор, который можно рассматривать как независимый процессор побитовой обработки, имеющий свое побитово-адресуемое ОЗУ, свой ввод-вывод и выполняющий свой набор команд. Внутреннее ОЗУ имеет 128 прямоадресуемых бит, пространство регистров SFR также поддерживает до 128 битовых полей. Побитно-адресуемыми являются все порты ввода-вывода, каждая линия которых может рассматриваться как однобитовый порт.
Набор булевых инструкций перечислен в табл. 2.7.
Каждый из отдельно адресуемых бит может быть установлен в "1", сброшен в "0", инвертирован, передан в разряд "Carry" или принят из него. Между любым прямоадресуемым битом и флагом переноса могут быть произведены логические операции "И" и "ИЛИ". Кроме того, по результату анализа состояния адресуемого бита возможно осуществление короткого (Short) условного перехода в соответствии с байтом смещения (relative).
Таблица 2.7.
Команды побитовой обработки.
Мнемоника Операция
ANL C, bit C=C.AND.bit
ANL C, /bit C=C.AND.(.NOT.bit)
ORL C, bit C=C.OR.bit
ORL C, /bit C=C.OR.(.NOT.bit)
MOV C, bit C=bit
MOV bit, C bit=C
CLR C C=0
CLR bit bit=0
SETB C C=1
SETB bit bit=1
CPL C C=.NOT.C
CPL bit bit=.NOT.bit
JC rel Переход, если C=1
JNC rel Переход, если C=0
JB bit, rel Переход, если bit=1
JNB bit, rel Переход, если bit=0
JBC bit, rel Переход, если bit=1; и обнуление bit
2.8. Работа с операндами увеличенной длины
В МК MCS-51 команды 16-разрядной арифметики отсутствуют, за исключением работы с указателем данных DPTR. Поэтому для простейших операций можно использовать пересылку слова в DPTR, а для более сложных - побайтовая обработка числа. При этом надо помнить, что возможно переполнение либо старшего, либо младшего байтов, и бит переноса надо учитывать в дальнейших операциях.
2.8.1.Увеличить содержимое регистров R4, R5 (16-ти разрядное число) на 3 (с проверкой возможного переполнения младшего разряда 16-ти разрядного числа).
Распределение ресурсов: Для операции увеличения 16-разрядного числа на не очень большую цифру можно использовать операцию инкремента регистра DPTR. При этом не надо проверять перенос из младшего байта в старший, так для DPTR он происходит автоматически.
NAME INCR1
Beg: mov dph,r4 ;пересылка содержимого старшего байта числа в старший регистр DPTR
mov dpl,r5 ;пересылка содержимого младшего байта числа в младший регистр DPTR
inc dptr ;увеличение числа на 3
inc dptr ;
inc dptr ;
mov r4,dph ;обратная пересылка полученного числа в R4, R5
mov r5,dpl ;
END