Обзор команд
Каждая команда PIC16F84 - это 14-битовое слово, которое разделено по смыслу на следующие части:
1. Код операции,
2. Поле для одного и более операндов, которые могут участвовать или нет в этой команде.
Система команд PIC16F84 включает в себя байт-ориентированные команды, бит-ориентированные, операции с константами и команды передачи управления. В таблицах 1.3, 1.4 и 1.5 представлены команды микроконтроллера PIC16F84.
Для байт-ориентированных команд "f" обозначает собой регистр, с которым производится действие; "d" - бит определяет, куда положить результат. Если
"d" = 0, то результат будет помещен в W регистр, при "d" = 1 результат будет помещен в "f", упомянутом в команде, в отличии от бит-ориентированных команд, в которых "b" обозначает номер бита, участвующего в команде, а "f" - это регистр, в котором этот бит расположен.
Для команд передачи управления и опреаций с константами, "k" обозначает восьми или одинадцатибитную константу.
Все команды выполняются в течение одного командного цикла. В двух случаях исполнение команды занимает два командных цикла:
|
|
1. Проверка условия и переход,
2. Изменение программного счетчика как результат выполнения команды.
Один командный цикл состоит из четырех периодов генератора. Таким о разом, для генератора с частотой 4 МГц время исполнения командного цикла будет 1 мкс.
Таблица 1.3 — Бит ориентированные команды
Мнемокод | Название команды |
BCF f,b | Сброс бита в регистре f |
BSF f,b | Установка бита в регистре f |
BTFSC f,b | Пропустить команду, если бит = 0 |
BTFSS f,b | Пропустить команду, если бит = 1 |
Таблица 1.4 — Байт ориентированные команды
Мнемокод | Название команды |
ADDWF f,d | Сложение W с f |
ANDWF f,d | Логическое И W и f |
CLRF f | Сброс регистра f |
CLRW | Сброс регистра W |
COMF f,d | Инверсия регистра f |
DECF f,d | Декремент регистра f |
DECFSZ f,d | Декремент f, пропустить команду, если 0 |
INCF f,d | Инкремент регистра f |
INCFSZ f,d | Инкремент f, пропустить команду, если 0 |
IORWF f,d | Логическое ИЛИ W и f |
MOVF f,d | Пересылка регистра f |
MOVWF f | Пересылка W в f |
NOP | Холостая команда |
RLF f,d | Сдвиг f влево через перенос |
RRF f,d | Сдвиг f вправо через перенос |
SUBWF f,d | Вычитание W из f |
SWAPF f,d | Обмен местами тетрад в f |
XORWF f,d | Исключающее ИЛИ W и f |
ADDLW k | Сложение константы с W |
ANDLW k | Логическое И константы и W |
IORLW k | Логическое ИЛИ константы и W |
SUBLW k | Вычитание W из константы |
MOVLW k | Пересылка константы в W |
XORLW k | Исключающее ИЛИ константы и W |
OPTION | Загрузка W в OPTION регистр |
TRIS f | Загрузка TRIS регистра |
Таблица 1.5 — Команды переходов
Мнемокод | Название команды |
CALL k | Вызов подпрограммы |
CLRWDT | Сброс Watchdog таймера |
GOTO k | Переход по адресу |
RETLW k | Возврат из подпрограммы с загрузкой константы в W |
RETFIE | Возврат из прерывания |
RETURN | Возврат из подпрограммы |
SLEEP | Переход в режим SLEEP |
Программа PIC-контроллерного устройства измерения временных велечин сигналов
|
|
Начальная инициализация
START
clrf port а ; Обнулить порт А.
clrf portb ; Обнулить порт В.
bsf status,5 ; Обращение к банку 1.
movlw 27 ; Синхронизация таймера 0 по заднему фронту
внешних тактов, включение таймера.
movwf option_reg
movlw 10
movwf trisa ; RAO - RA3 выходы, RA4 вход.
clrf trisb ; RBO - RB7 выходы.
bcf status, 5 ; Обращение к банку 0.
movlw 08 ; Для контроля дисплея
movwf Dig_x ; Загрузить во все регистры индикации 8.
MovwfDig_y
movwfDig_z
movwfDig_exp
Основной цикл программы
movlw 0A ; Установить счетчик циклов индикации.
movwf cnt_r
loop1 call refresh ; Вывод на индиторы.
decfsz cnt_r, f
goto loop1
loop5 clrf tmr0 ; Сброс таймера.
bsf status, 5 ; Обращение к банку 1.
movlw 0001 ; Разрешить прохождение внешних тактов на
вход таймера, RBO вход.
movwf trisb
bcf status,5 ; Обращение к банку 0.
movlw.199 ; 1 мс ожидания для измерения
высокочастотных сигналов.
movwf cnt1
in_ms nор
clrwdt
decfsz cntl, f
goto in_ms
bsf status, 5 ; Обращение к банку 1.
clrf trisb ; Заблокировать прохождение внешних тактов
на вход таймера, RBO выход.
bcf status, 5 ; Обращение к банку 0.
call prescaler ; Считать накопленное значение таймера.
movf H_byte, f
btfss status,2 ; Старший байт значения таймера = 0?
goto call_ms ; Нет, переход на обработку.
btfsc L_byte,7; Старший разряд младшего байта значения=0?
goto call_ms ; Нет, переход на обработку.
clrf tmr0 ; Сброс таймера.
bsf status,5 ; Обращение к банку 1.
movlw 01 ; Разрешить прохождение внешних тактов на
вход.
movwf trisb ; таймера, RBO вход.
bcf status,5 ; Обращение к банку 0.
nор ; 0.5 с ожидания для измерения низкочастотных сигналов.
nор
movlw 0A ; Установить счетчик циклов индикации.
movwf cnt_r
loopr call refresh ; Вывод на индикацию.
decfsz cnt_r, f
goto loopr
nор
nор
nор
bsf status,5 ; Обращение к банку 1.
clrf trisb ; Заблокировать прохождение внешних тактов
на вход таймера, RBO выход.
bcf status,5 ; Обращение к банку 0.
call prescaler ; Считать накопленное значение таймера.
movf H_byte, f
btfss status,2 ; Старший байт значения таймера = 0?
goto cal05 ; Нет, переход на обработку.
btfsc L_byte,7 ; Старший разряд младшего байта значения=0?
goto cal05 ; Нет, переход на обработку.
clrf Dig x ; Да, обнулить текущее значение индикации.
clrf Dig_y
clrf Dig_z
clrf Dig_exp
goto loop5 ; Переход на начало основного цикла.
Обработка измерения высокочастотных сигналов.
call_msclrf U ; Очистка десятичных регистров.
clrf D clrf H
clrf M
clrf DM
clrf CM
movlw 03 ; Коррекция порядка результата для
высокочастотных сигналов.
movwf Dig_exp
call segment ; Преобразование DEC в семисегментный код.
movwf portb ; Вывод цифры на индикатор.
bcf porta,1 ; Активизировать индикатор.
call Delay ; Задержка времени для сканирования.
bsf porta, 1 ; Отключить индикатор.
movf Dig_z, W ; Значение сотых для индикации.
call segment ; Преобразование DEC в семисегментный код.
movwf portb ; Вывод цифры на индикатор.
bcf porta,2 ; Активизировать индикатор.
|
|
call Delay ; Задержка времени для сканирования.
bsf porta,2 ; Отключить индикатор.
movf Dig_exp, W ; Значение порядка результата для индикации.
call segment ; Преобразование DEC в семисегментный код.
movwf portb ; Вывод цифры на индикатор.
bcf porta,3 ; Активизировать индикатор.
call Delay ; Задержка времени для сканирования.
bsf porta, 3 ; Отключить индикатор.
return
prescaler ; Считать накопленное значение таймера.
movf tmr0, W
movwf H_byte ; Сохранить значение таймера 0.
Извлечение значения предделителя TMR00.
clrf N ; Обнулить счетчик.
cicl bcf portb,0 ; Сформировать тактовый импульс на входе
синхронизации таймера.
bsf portb,0
bcf portb,0
incf N, f ; Инкремент счетчика.
movf H_byte, W
xonvf tmrO, W ; Значение таймера 0 изменилось? btfsc status,2
goto cicl ; Нет, повторить цикл.
movlw 00FF
movwf L_byte
movf N, W
subwf L_byte, f; Получить и сохранить значение
предделителя.
incf L_byte, f
return
calc ; Преобразование формата: HEX в DEC.
movlw.16 ; Установить счетчик разрядов.
movwf N
coder
rlf L_byte, f ; Сдвиг старшего разряда значения таймера в
бит С.
rlf H_byte, f
btfsc status,0 ; Бит С = 1?
call sessn ; Да, прибавить десятичное значение разряда к десятичным регистрам.
decfsz N, f ; Декремент счетчика разрядов.
goto coder ; Продолжить преобразование.
call report ; Коррекция значений десятичных регистров.
; Вычисление порядка значения индикации.
movlw 05 ; Установить счетчик разрядов после запятой.
movwf E movlw CM+1 ; Загрузить адрес строки десятичных разрядов
для косвенной адресации.
movwf fsr
calc_ext ; Поиск старшего значащего разряда.
decf fsr, f ; Коррекция счетчика разрядов.
movf indf, W
btfss status,2 ; Значение = О?
goto end_ext ; Нет, закончить поиск.
|
|
decfsz E, f ; Все разряды проверены?
goto calc_ext ; Нет, продолжить поиск.
end_ext
movlw 2
subwf E,W
btfss status,0 ; Значение порядка < 2? goto err ; Да, ошибка - обнулить значение индикации.
btfsc status,2 ; Значение порядка = 2? goto no_app ; Да, обход округления.
; Округление выходного значения.
addlw U ; Получить адрес отбрасываемого разряда для косвенной адресации.
movwf fsr ;
decf fsr, f movlw 05 ; Сравнить значение разряда с 5.
subwf indf, W
btfss status,0 ; Значение > 5?
goto no_app ; Нет, обход округления.
incf fsr, f
incf indf, f ; Да, инкремент следующего разряда.
no_app
call report ; Коррекция значений десятичных регистров после округления. movf E,W ; Формирование значения для индикации.
addwf Dig_exp, f ; Сохранить значение Е.
addlw U ; Получить адрес строки десятичных разрядов
для косвенной адресации.
movwf fsr
movf indf, W
movwf Dig_x ; Переслать значение X.
decf fsr, f
movf indf, W
movwf Dig_y ; Переслать значение Y.
decf fsr, f
movf indf, W
movwf Dig_z ; Переслать значение Z.
return
Ошибка - обнулить значение индикации.
err movlw 0
movwf Dig_x
clrf N
call calc ; Вычисление значения для индикации.
movlw 0A ; Загрузить счетчик циклов индикации.
movwf cnt_r
goto loop1 ; Переход на начало основного цикла.
Обработка измерения низкочастотных сигналов.
саl05 clrf U ; Очистка десятичных регистров.
clrf D clrf H
clrf M
clrf DM
clrf CM
movlw.17 ; Установить счетчик разрядов.
movwfN
btfsc H_byte,7 ; Старший разряд значения таймера =1?
call sessn ; Да, загрузить в десятичные регистры
216=65536.
bcf status, 0
rlf L_byte, f ; Коррекция значения таймера до 1с.
rlf H_byte, f
clrf Dig_exp ; Коррекция порядка результата для
низкочастотных сигналов.
clrf N
call calc ; Вычисление значения для индикации.
goto loop5 ; Переход на начало основного цикла.
Delay ; Подпрограмма задержки времени для
сканирования индикации.
movlw.10
movwf cnt 1
nор
beta movlw.248
movwf cnt2
clrwdt ; Сброс сторожевого таймера.
Alfa nор
nор
decfsz cnt2, f
goto alfa
nор
nор
decfsz cntl, f
goto beta
nор
return
refresh ; Процедура сканирования индикации.
movf Dig_x, W ; Значение единиц для индикации.
call segment ; Преобразование DEC в семисегментный код.
movwf portb ; Вывод цифры на индикатор.
bcf porta, 0 ; Активизировать индикатор.
call Delay ; Задержка времени для сканирования.
bsf porta, 0 ; Отключить индикатор.
movf Dig_y, W ; Значение десятых для индикации.
movwf Dig_y
movwf Dig_z
movwf Dig_exp
return
report ; Коррекция значений десятичных регистров.
movlw 05 ; Установить счетчик разрядов,
movwf cnt_r movlw U ; Загрузить адрес строки десятичных разрядов для косвенной адресации.
movwf fsr
loop_rep
clrf i ; Очистить поправку следующего разряда.
movf indf, W
movwf N ; Загрузить значение во временный регистр.
calc_rep
movf N, W
movwf indf ; Сохранить значение.
incf i, f ; Инкремент поправки следующего разряда.
movlw 0А
subwf N, f ; Вычесть 10.
btfsc status, 0 ; Результат отрицательный?
goto calc_rep ; Нет, продолжить коррекцию.
decf i, f ; Скорректировать поправку следующего разряда.
incf fsr, f
movf i, W
addwf indf, f ; Прибавить поправку к следующему
разряду.
decfsz cnt_r, f ; Все разряды скорректированы?
goto loop_rep ; Нет, продолжить коррекцию.
return
sessn ; Преобразование значения двоичного разряда в десятичное.
movf N, W ; Загрузить номер разряда.
call tab_dec ; Получить смещения в таблице для разряда.
movwf E
call tab_dec ; Получить значение десятков тысяч.
addwf DM, f
incf E, f
movf E, W
call tab_dec ; Получить значение единиц тысяч.
addwf M, f
incf E, f
movf E, W
call tab_dec ; Получить значение сотен.
addwf H, f
incf E,f
movf E, W
call tab_dec ; Получить значение десятков.
addwf D, f
incf E, f
movf E, W
call tab_dec ; Получить значение единиц.
addwf U, f
return
END