Главная страница

Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.


Скачать 3.49 Mb.
НазваниеСистема команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
АнкорСамоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
Дата30.01.2017
Размер3.49 Mb.
Формат файлаpdf
Имя файлаСамоучитель по программированию PIC контроллеров для начинающих .pdf
ТипПрограмма
#1195
КатегорияПромышленность. Энергетика
страница49 из 57
1   ...   45   46   47   48   49   50   51   52   ...   57
andlw 0Fh
; в младший полубайт LED1.
movwf LED1 ;
--------------------------------
movfw LED0
; Запись младшего полубайта LED0
andlw 0Fh
; в младший полубайт LED0.
movwf LED0 ;
--------------------------------
;--------------------------------------------------------------------
; Конец распределения.
В
младших полубайтах регистров LED0...7
; установлены двоично
-
десятичные числа в
порядке возрастания разрядности.

; Старшие полубайты = 0.
;--------------------------------------------------------------------
return
; Переход по стеку в
группу подпрограмм ; разрядной динамической индикации.

;================================================================================
; Запись в
регистр
FSR адресов регистров LED0...3 для дальнейшей косвенной адресации к
ним в
ПП
adjBCD.
; Переход к
обработке следующего LED - после возврата по стеку.

;================================================================================
adjDEC movlw LED0
; Запись в
регистр
FSR, через регистр W,
movwf FSR
; адреса регистра LED0 с дальнейшим переходом call adjBCD
;
в
ПП
adjBCD (адрес следующей команды ; закладывается в
стек
).
;---> Возврат по стеку из
ПП
adjBCD.
movlw LED1 ;
-----------------------------
movwf FSR
; Тоже самое для регистра LED1.
call adjBCD
; -----------------------------
;---> Возврат по стеку из
ПП
adjBCD.
movlw LED2
; -----------------------------
movwf FSR
; Тоже самое для регистра LED2.
call adjBCD
; -----------------------------
;---> Возврат по стеку из
ПП
adjBCD.
movlw LED3
; -----------------------------
movwf FSR
; Тоже самое для регистра LED3.
call adjBCD
; -----------------------------
;---> Возврат по стеку из
ПП
adjBCD.
goto Loop16
; Проход всех LED (с LED0 по LED3). Переход в ;
ПП
Loop16, то есть наследующее кольцо ; числовых преобразований.
;================================================================================
; Основные операции преобразования двоичных чисел в
двоично
-
десятичные
:
; операции сложения LED0...3 и констант 03h,30h с условиями по 3-
му и 7-

му битам.

;================================================================================
adjBCD movlw 3
; Сложить содержимое текущего LED (LED0...3) с addwf 0,W
; числом 03h, c записью результата операции movwf Mem
; через регистр W, в регистр Mem.
btfsc Mem,3
; Анализ состояния го бита регистра Mem.
movwf 0
; Если бит 3 =1, то содержимое регистра Mem
; копируется в
текущий
LED.
movlw 30
; Если бит =0, то содержимое текущего LED
addwf 0,W
; складывается с
константой
30h, с последующей movwf Mem
; записью результата операции, через регистр ; W, в регистр Mem.
btfsc Mem,7
; Анализ состояния го бита регистра Mem.
movwf 0
; Если бит =1, то содержимое регистра Mem
; копируется в
текущий
LED.
retlw 0
; Если бит =0, то регистр W очищается и ; происходит возврат по стеку в
ПП
adjDEC.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
ГРУППА
КОМАНД
ПРЕОБРАЗОВАНИЯ
ДВОИЧНО
-
ДЕСЯТИЧНОГО
КОДА
В
КОД
СЕГМЕНТНОГО ИНДИКАТОРА (относится к
группе подпрограмм динамической индикации.

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TABLE .....................................
; .....................................

247
; .....................................
;********************************************************************************
end
; Конец программы. Сначала разберемся с
общей "конструкцией " программы
В
начале ее исполнения, рабочая точка программы начинает свое движение по "линейному " участку
ПП
START
, начиная с 1- й
ее команды и
до команды После исполнения команды Bin2_10

, рабочая точка программы "прыгает " на 1- ю
команду
ПП
преобразований чисел, после чего она начнет исполняться
В
результате исполнения команды Bin2_10

, адрес команды, следующей за командой Bin2_10
, "закладывается " в
стек и
находится там до окончания отработки
ПП
Bin2_10
После окончания отработки
ПП
Bin2_10
(после исполнения команды, из вершины стека "выгружается " указанный выше адрес, и
после отработки всех оставшихся команд
ПП
START
, начинается исполнение
ПП
динамической индикации (то, о
чем говорилось в
предыдущем разделе. После отработки
ПП
динамической индикации, рабочая точка программы переходит в
ПП
формирования
4- байтного
, двоичного числа
Обращаю
Ваше внимание на то, что этот переход происходит без использования команды перехода, так как работа происходит на "линейном " участке программы (просто исполняется следующая команда. Конструкций " подпрограмм формирования 4- байтного
, двоичного числа может быть множество
Это зависит от функциональности устройства, которое обслуживает программа
Главное
, чтобы в
результате работы этой
ПП
, тем или иным способом, было сформировано- байтное
, двоичное число
После того как это произошло, для обеспечения перехода в
ПП
преобразований чисел
("
закольцовки "), осуществляется безусловный переход наметку, входящую в
состав
ПП
START
Таким образом, мы "прошлись " по кольцу полного цикла программы
По ходу исполнения программы, таких колец может быть "намотано " множество
Это зависит от времени, в
течение которого устройство находится во включенном состоянии
Разбираемся с
возможными "
непонятками ". Вопрос "Зачем осуществлять безусловный переход наметку Если этого не делать
(
команда
goto и метка
NEW
отсутствуют
), то из
ПП
формирования
4- байтного
, двоичного числа, в
ПП
преобразований чисел, рабочая точка программы перейдет самоходом (стык находится на линейном участке программы.
Ответ
:
да
, таким образом рабочая точка программы войдет в
ПП
преобразований чисел, но выйти из нее она не сможет, так как стек будет пустой (куда переходить "Глюк ").
А
пустой он будет потому, что перед исполнением
ПП
преобразований чисел, в
него не "заложился " адрес возврата (не исполнена команда. Для того чтобы обеспечить эту "закладку ", а
заодно и
вернуться "туда, куда положено ", необходимо выполнить команду NEW

(перейти на исполнение команды Bin2_10
). Разбираемся с
ПП
START
С
точки зрения обеспечения надежности работы устройства, полный цикл программы лучше начинать с
исполнения
ПП
START
, а
не с
команды
, которая не входит в
ее состав
В
противном случае,
ПП
START
будет исполнена всего один раз (после включения питания устройства, нам "витке " полного цикла программы, ив ходе дальнейшей работы программы (от 2- го "витка " и
далее
),
ПП
START
будет обходиться
В
этом случае, при неконтролируемом изменении содержимого задействованных в
программе регистров (например, в
результате какого- то сбоя, существует вероятность "зависания " программы
Если предприняты меры по "борьбе с
зависаниями " (например, работает сторожевой таймер, тов принципе, это нестрашно, но если этих мер не предпринято или существуют сомнения, или речь идет об обеспечении максимальной надежности работы устройства, то перестраховаться не помешает
При наличии такой перестраховки, последствия некоторых сбоев будут ликвидированы за счет приведения "поврежденного " содержимого регистров к
норме
Насколько я
понимаю
, в
ответах на этот "скользкий вопрос ", единого мнения нет
Можно
, начиная со 2- го "витка " полного цикла программы, обойти
ПП
START.
Можно не обходить

248 Можно включить в
полный цикл программы (от 2- го "витка " и
далее
) наиболее "ответственные ", подготовительные операции
ПП
START это что- то типа компромиссного варианта. Реализацию именно такого подхода
Вы и
видите в
тексте программы
Bin2_10.asm
"
Ответственные " (эта оценка субъективна) команды подготовительных операций
ПП
START
располагаются ниже команды Bin2_10
, а
команды подготовительных операций, "рангом пониже ", располагаются выше ее
Это означает то, что команды подготовительных операций, располагающиеся выше команды Bin2_10
, будут исполнены нам "витке " полного цикла программы, ив дальнейшем (от- го "витка " и
далее
), они исполняться не будут
Команды подготовительных операций, располагающиеся ниже команды Bin2_10
, будут исполняться на каждом "витке " полного цикла программы
В
"перестраховочном " случае, нужно заменить команду на команду Если есть такое желание, то ничто не мешает осуществить такую замену
А
теперь давайте разберемся в
сути преобразований двоичных чисел в
двоично
- десятичные
Предположим
, что группа
ПП
формирования
4- байтного
, двоичного числа "выдала на гора "
4- байтное
, двоичное число
По определению, такое число должно быть "заложено " в 4 регистра общего назначения
Пусть они будут называться
Timer...
Так как регистров 4 штуки, то нужно определиться с
порядком их старшинства
TimerHH, TimerH, TimerM, Ранее об этом говорилось
Если нужно что- то подсчитать, то речь идет о
многоразрядном
, двоичном счетчике, которому можно поставить в
соответствие
, например, двоичный счетчик нами микросхемах 555
ИЕ
5 каждая 555
ИЕ
5 работает с
полубайтом
, а
не с
байтом
, и
поэтому таких м
/
схем нужно 8 штук. Эта аналогия относится к
форме представления результатов счета
По этому показателю, аналогия полная
То есть, в
обоих случаях, 32- битное
, двоичное число будет отображаться в
стандартном весовом коде
Что же касается принципов счета, то существуют весьма существенные различия, связанные стем, что в 555
ИЕ
5, счет реализуется только аппаратными средствами
Пошли дальше
Линейка
7- сегментных индикаторов, состоящая из 8- ми знакомест, может отобразить десятичное число не более 99 999 999. Двоичный эквивалент этого числа в
стандартном весовом коде 11110101 11100000 11111111 См конвертор систем исчисления, который у
Вас имеется (можете проверить. Вопрос "Что такое двоично- десятичное число "?.
Ответ
:
двоично
-
десятичное число это одно из чисел числового диапазона … 9

, представленное в
двоичной форме
.
Двоично
- десятичное число, по определению, не может быть больше 9- ти
Из этого следует то, что оно отображается только в
младшем полубайте байта, а
старший полубайт байта всегда будет равен нулю (
0000
хххх
). Например, десятичное число 99 999 999, в
двоичном виде, может быть отражено в 4- байтном регистре, нов двоично- десятичном виде, такое число не может быть отражено в
четырех регистрах
В
последнем случае, для отображения этого числа потребуется 8 регистров
Число
99 999 999, в
двоично
- десятичном виде, выглядит так
0000
1001
0000
1001
0000
1001
0000
1001
0000
1001
0000
1001
0000
1001
0000
1001 Вы видите, что во всех младших полубайтах всех 8- ми регистров, "лежат " девятки, а
во всех старших полубайтах, нули
Вот зачем и
нужны
8 регистров, "прописку " которых
Вы видите в "шапке " программы
Первые четыре из них (
LED0...3
), в
ПП
преобразований чисел, задействуются для хранения промежуточных и
конечных результатов преобразований
Регистры
LED4...7
для этого не задействуются
На конечной стадии работы
ПП
преобразований чисел, из младших и
старших полубайтов

249 регистров, в
младшие полубайты регистров (это не ошибка, никакой ошибки нет, переписываются конечные результаты преобразований чисел
Это и
есть то, что в
дальнейшем
, подлежит кодировке
При этом, в
старших полубайтах "выставляются " нули
Это как раз то, что
Вы видите в
примере
(для случая 99999999).
В
конечном итоге, в
младших полубайтах регистров, на все время полного цикла
ПП
динамической индикации, фиксируются двоично- десятичные числа, с
которыми эта
ПП
и будет работать
В
общем виде, работу
ПП
преобразований чисел можно описать так После "
влёта " рабочей точки программы в
ПП
преобразований
, в
предварительно назначенный счетчик "проходов "
Count
, записывается константа, значение которой равно суммарному количеству битов 4- байтного регистра (в нем находится 4- байтное
, двоичное число, которое нужно преобразовать в
двоично
- десятичное. То есть, в
данном случае, числовое значение этой константы, должно быть равно .32. На каждом из 32- х "витков " внутреннего цикла
ПП
преобразований чисел, содержимое счетчика "проходов "
Count
декрементируется
, и
если результат декремента неравен, то происходит переход рабочей точки программы наследующий "виток " внутреннего цикла
ПП
преобразований чисел
Таким образом, войдя в
ПП
преобразований чисел, рабочая точка программы "наматывает "
32 "витка " внутреннего цикла
ПП
преобразований чисел, которые, в
сумме
, составляют полный цикл
ПП
преобразований чисел
После этого, она выходит из
ПП
преобразований чисел по сценарию "программа исполняется далее ". При этом, содержимое счетчика "проходов " равно нулю
Что происходит, в
процессе "прохождения " рабочей точкой программы, каждого из 32- х "витков " внутреннего цикла
ПП
преобразований чисел Сначала производится групповой, циклический сдвиг содержимого 8- байтного регистра
TimerL/TimerM/TimerH/TimerHH/LED0/LED1/LED2/LED3
влево
(через бит
С
регистра
STATUS
). Перед этим, (вначале исполнения полного цикла
ПП
преобразований чисел, в
регистры
LED0...7
записываются нули
То есть, их "старое " содержимое удаляется, после чего они готовы к
работе
В
результате каждого такого группового сдвига (последовательный сдвиг содержимого 8- ми регистров. 8 команд, происходит перенос содержимого старшего бита регистра
TimerHH
в младший бит регистра
LED0
Таким образом, через 32 таких сдвига, содержимое
TimerL/TimerM/TimerH/TimerHH
переместится в
LED0/LED1/LED2/LED3
Если это трудно себе представить, то вспомните про "бегущую строку " или "бегущие огни ". Если просто переместить содержимое
TimerL/TimerM/TimerH/TimerHH
в
LED0/LED1/LED2/LED3
, то это ничего полезного не даст, так как конечным результатом такого перемещения будет исходное, двоичное число
Следовательно
, после очередного группового сдвига, необходимо преобразовать содержимое 4- байтного регистра
LED0/LED1/LED2/LED3
таким образом, чтобы на момент завершения всех 32- х
групповых сдвигов (счетчик проходов
Count
очищен
), во всех 8- ми полубайтах 4- байтного регистра, с
соблюдением порядка старшинства, "осели " двоично
-
десятичные числа (любое из них можно отобразить в
полубайте
), точно отражающие значение исходного, двоичного числа
То есть, речь идет о
процедуре типа "чтение – модификация – запись
Так как запись результатов числовых преобразований производится в
те же регистры, из которых производилось чтение (
LED0...3
), то при модификации, должен задействоваться регистр оперативной памяти (в нашем случае -
Mem
), в
котором будут храниться как промежуточные, таки конечные результаты преобразований чисел
По окончании текущего цикла модификации, модифицированное число, "осевшее " в
регистре
Mem
, копируется в
текущий
LED
Предположим
, что это происходит
После того как будет "отмотано " 32 "витка " внутреннего цикла
ПП
преобразований чисел, во всех 8- ми полубайтах 4- байтного регистра
LED0/LED1/LED2/LED3
будут "лежать " 8 двоично- десятичных чисел

250 Остается только "раскидать " их (также с
соблюдением порядка старшинства) по младшим полубайтам регистров, LED1, LED2, LED3, LED4, LED5, LED6, LED7

, а
в их старшие полубайты, "принудительно " записать нули (см пример двоично- десятичного представления числа 99999999).
Всё
Конец преобразования
После этого, содержимое регистров
LED0...7
можно обрабатывать в
ПП
динамической индикации
Не смотря на достаточно сложный алгоритм числовых преобразований, работать с
ПП
преобразований чисел совсем несложно В "шапке " программы, "прописываются " 2 регистра общего назначения счетчик числа проходов и
регистр оперативной памяти (в нашем случае, и.
В
начале
ПП
преобразований чисел, в
счетчик проходов, нужно записать число битов двоичного числа
Например
, если нужно отобразить символы десятичных чисел не в 8- ми, а
в
4- х
знакоместах
(
максимальное значение
1   ...   45   46   47   48   49   50   51   52   ...   57


написать администратору сайта