Разработка программного обеспечения

Обзор команд

Каждая команда 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




Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: