Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
Скачать 3.49 Mb.
|
;-------------------------------------------------------------------------------- 236 No_Dot movf Temp,W ; Копирование содержимого регистра Temp (7- ; сегментные коды индицируемых двоично- ; десятичных чисел) в регистр W. movwf PortB ; Копирование содержимого регистра W ; в 8 защелок порта В . ;-------------------------------------------------------------------------------- ; Группа команд формирования адресного кода управления дешифратором. ;-------------------------------------------------------------------------------- movf Index,W ; Копирование содержимого регистра Index ; в регистр W. movwf PortA ; Копирование содержимого регистра W впервые защелки порта А (работа "на выход, ; управляющие адресными входами внешнего ; дешифратора. ;-------------------------------------------------------------------------------- ; Группа команд задержки, определяющей время нахождения одного сегментного индикатора в активном состоянии (определяющей время прохождения малого кольца индикации. ; "Грубое" формирование времени полного цикла динамической индикации. ;-------------------------------------------------------------------------------- movlw Const1 ; Запись в регистр W константы Y1 ( см " шапку ") movwf Temp ; Копирование содержимого регистра W ; в регистр Temp. PAUSE decfsz Temp,F ; Декремент содержимого регистра Temp c ; сохранением результата в нем же. goto PAUSE ; Если результат декремента не, ; то переход в ПП PAUSE. ; Если результат декремента =0, ; то программа исполняется далее. ;-------------------------------------------------------------------------------- ; Увеличение на 1 содержимого счетчика количества малых колец индикации Index с последующей проверкой результата инкремента на равенство (или нет) числу .08. ;-------------------------------------------------------------------------------- incf Index,F ; Увеличение на 1 содержимого регистра Index ; с сохранением результата в нем же. movlw .08 ; Запись в регистр W константы .08. bcf Status,Z ; Сброс флага нулевого результата Z. subwf Index,W ; Вычесть из содержимого регистра Index ; содержимое регистра W, с сохранением ; результата в регистре W. btfss Status,Z ; Результат операции вычитания равен ; или нет нулю goto CYCLE ; Если не =0 (в регистре Index - число неравное, то переход к циклу активизации ; следующего по старшинству сегментного ; индикатора (переход на новое малое кольцо ; индикации, то есть, в ПП CYCLE). ; Если =0 (в регистре Index - число равное ; 8), то программа исполняется далее. ;-------------------------------------------------------------------------------- ; Начало перехода на новое большое кольцо индикации после того, как последовательно активируются все 8 сегментных индикатора линейки (после прохождения ми малых колец индикации. ;-------------------------------------------------------------------------------- nop ; Выравнивающий NOP. clrf Index ; Сброс в 0 содержимого регистра Index. ;-------------------------------------------------------------------------------- ; Уменьшение на 1 содержимого счетчика количества больших колец индикации Count. ;-------------------------------------------------------------------------------- decfsz Count,F ; Декремент содержимого счетчика количества ; больших колец индикации Count, ; с сохранением результата в нем же. goto CYCLE ; Если результат декремента не, то переход ; в ПП CYCLE ; (переход на новое большое кольцо индикации) ; Если результат декремента =0, то программа 237 ; исполняется далее (переход на новый полный ; цикл динамической индикации. nop ; Выравнивающий NOP. ;================================================================================ ; Группы подпрограмм и команд , осуществляющие различные операции. ;================================================================================ ; "Точное" формирование времени полного цикла динамической индикации (если требуется точно калиброванное время полного цикла динамической индикации для использования его в качестве измерительного интервала. ;-------------------------------------------------------------------------------- movlw Const2 ; Запись в регистр W константы Y2 ( см " шапку ") movwf Temp ; Копирование содержимого регистра W ; в регистр Temp. PAUSE_1 decfsz Temp,F ; Декремент содержимого регистра Temp с ; сохранением результата в нем же. goto PAUSE_1 ; Если результат декремента не, ; то переход в ПП PAUSE_1. ; Если результат декремента =0, ; то программа исполняется далее. ;-------------------------------------------------------------------------------- ; Гашение активного разряда линейки. ;-------------------------------------------------------------------------------- movlw 0 ; Запись в регистр W константы .00. movwf PortB ; Сброс в 0 всех защелок порта В . ;-------------------------------------------------------------------------------- ; ........................................ ; ........................................ ; ........................................ ; ........................................ ; ........................................ ; ........................................ ; На данный момент, регистры LED0 ... LED7 заполнены двоичными числами, которые, ; в дальнейшем, нужно преобразовать в двоично - десятичные и сохранить их все в тех ; же регистрах LED0 ... LED7. goto Bin2_10 ; Безусловный переход в ПП Bin2_10. ;-------------------------------------------------------------------------------- ; Применение вычисляемого перехода. ; (преобразование двоично - десятичного кода в код сегментного индикатора) ;-------------------------------------------------------------------------------- TABLE addwf PC,F ; Содержимое счетчика команд PC увеличивается ; на величину содержимого аккумулятора W. retlw b'00111111' ; ..FEDCBA = Происходит скачек по таблице retlw b'00000110' ; .....CB. = на строку со значением retlw b'01011011' ; .G.ED.BA = записанным в аккумуляторе , retlw b'01001111' ; .G..DCBA = и далее - возврат по стеку. retlw b'01100110' ; .GF..CB. = 4 retlw b'01101101' ; .GF.DC.A = 5 retlw b'01111101' ; .GFEDC.A = 6 retlw b'00000111' ; .....CBA = 7 retlw b'01111111' ; .GFEDCBA = 8 retlw b'01101111' ; .GF.DCBA = 9 ;******************************************************************************** end ; Конец программы. Часть этой программы мы уже разобрали, а остаток "разложим на молекулы " сейчас Начну с "шапки ". Вы видите, что в ней дополнительно "прописаны " 2 регистра специального назначения ( регистры управления защелками портов А и В : и) и один регистр общего назначения, который выполняет функции многоцелевого регистра оперативной памяти (" Фигаро здесь, Фигаро там "). В него , походу исполнения ПП динамической индикации, будут записываться константы различного функционального предназначения И еще один новый "прибамбас ": названия также можно присвоить и константам Собственно , объяснять тут особо и нечего (см. "шапку "). 238 Переходим к рабочей части программы После отработки ПП TABLE , возврат из нее происходит на первую команду группы команд установки запятой Temp В этой группе команд, можно выставить десятичную запятую в любом знакоместе линейки, что есть "привязка " к единице измерения (например, гц , Кгц , Мгц ...). Предположим, что запятую нужно выставить в 5- м знакоместе Чтобы не было путаницы, обращаю Ваше внимание на то, что в данном случае, речь идет о нумерации от 0 до 7. Если "привязаться " к "обывательской " нумерации (от 1 до 8), то это будет соответствовать- му знакоместу Анализируем то, что мы имеем после возврата из ПП TABLE После этого возврата, в зависимости оттого, какое из 8- ми малых колец индикации отрабатывается, в регистре W , будет записано какое- либо одно из 10- ти двоичных чисел (не забывайте, что ПИК работает только с двоичными числами) результата кодировки (или перекодировки, что по сути, одно и то же. Напоминаю, что такая разновидность двоичных чисел позволяет отобразить, водном из активированных знакомест, один из символов цифр ( от 0 до 9 ). Если речь идет о 5- м знакоместе , тонам "витке " малого кольца индикации, необходимо изменить кодировку таким образом, чтобы не воздействуя на секторы 7- сегментного индикатора с названиями A, B, C, D, E, F, G (иначе будет индицироваться не то, что нужно, выставить " единицу в секторе H (загорание " запятой. В интервале времени отработки остальных 7- ми "витков " малого кольца индикации, процедура установки запятой должна игнорироваться (обходиться. То есть, имеет место быть 2 сценария исполнения программы Следовательно , должна быть применена команда ветвления, проверяющая состояния какого- то флага Речь идет о выборе одного- разъединственного числа (из группы чисел) и "привязке ", к этому числу, одного из 2- х сценариев работы программы Первое , что приходит на ум, - задействование флага нулевого результата Z Его состояния должны анализироваться с помощью байт- ориентированных команд btfsc или btfss Если задействуется флаг, то есть, осуществляется "привязка " к нулевому или ненулевому результату исполнения некой команды, влияющей на состояние этого флага, то одним из результатов исполнения этой команды должен быть ноль При "разборках " с флагом Z , мы это уже проходили (команда. После возврата по стеку, нужно скопировать содержимое регистра W в какой- нибудь регистр оперативной памяти В данном случае, это регистр ( movwf Temp ). Необходимость этого сохранения обусловлена тем, что в дальнейшем , регистр W будет задействован, и если не принять мер по сохранению его содержимого, то оно, после записи поверху, будет "потеряно ". Если содержимое регистра W сохранено в регистре Temp , то регистр "высвобождается " ив него можно записать константу .05 ( movlw 5 ), для последующего ее использования в операции вычитания Для разнообразия, в команде movlw 5 , я указал числовое значение константы без атрибутов систем исчисления (о такой возможности говорилось ранее, но можно "настучать " и .05 или, или b'00000101'. Далее, командой Status,Z флаг Z поднимается По большому счету, эта команда ненужна флаг 1- й группы ), ноя ее ввел в текст программы для удобства отслеживания работы процедуры в симуляторе (в обучающих целях. При этом, я исходил из того, что 5- е знакоместо одно, а количество остальных знакомест – 7. Поэтому и поднял флаг Z Если эта команда Вам не нравится, то можете ее убрать После исполнения команды Index,W , флаг Z будет либо опущен (если в регистре Index " лежит " одно из чисел .00, .01, .02, .03, .04, .06, .07), либо поднят (если в регистре Index лежит " число .05). Если флаг Z поднялся , то сначала исполнится "виртуальный " NOP , а затем будет исполнена команда Temp,7 239 В регистре Temp, "лежит " результат перекодировки, в котором запятая программно "погашена " (бит = 0). Установка единицы в бите № 7 ( bsf Temp,7 ), соответствует активации запятой (загорится " сектор 5- го знакоместа. Так как для установки запятой применяется бит- ориентированная команда, то она не будет воздействовать на секторы, B, C, D, E, F, G (воздействует только на сектор. После исполнения команды Temp,7 , рабочая точка программы переходит наметку Если флаг Z опущен , то с помощью команды No_Dot , рабочая точка программы переходит наметку, "перескакивая " через команду Temp,7 (это называется обходом. В этом случае, запятая не может быть выставлена В конечном итоге, в 5- м знакоместе , запятая будет "высвечиваться " одновременно с "высвечиванием " символа цифры, а в остальных знакоместах, сектор H будет "погашен ", и на индикацию будут выводиться только символы цифр Вопрос : "Как изменить положение запятой "? Ответ : очень просто В команде movlw 5 , пятерку нужно заменить на номер того знакоместа, в котором ее нужно выставить Всё Запятая выставлена Переходим к исполнению группы команд вывода десятичной цифры (символа) на индикацию Так же, как и "все пути ведут в Рим ", оба сценария группы команд установки запятой "уперлись " в команду movf Далее, movwf подготовка к выводу символа на индикацию "Подготовка " потому, что нужное знакоместо не активировано Значит , нужно озаботиться формированием адресного кода, который управляет внешним дешифратором Что и сделано : movf и После этого, символ "высветится " в нужном знакоместе, а проще говоря, он будет выведен на индикацию На всякий случай, "сделаю второй заход " (хуже от этого не будет. В регистре Temp, находится двоичное число (результат кодировки, предназначенное для отображения в текущем знакоместе, в виде символа цифры После исполнения команды Temp,W , это число копируется в регистр W (сразу его скопировать в защелки порта В нельзя ), а затем , из регистра W, в защелки вовсе штук) порта В ( movwf PortB ). Таким образом, на анодах светодиодов линейки, выставлен код одного из символов цифр ... 9 ). Какое именно знакоместо будет активировано, зависит оттого, каким будет числовое значение адресного кода, который управляет внешним дешифратором Числовое значение этого кода, в свою очередь, зависит оттого, на каком именно, из 8- ми "витков " большого кольца индикации (одно большое кольцо индикации имеет в своем составе малых колец индикации, находится рабочая точка программы Как раз этим "делом и занимается " группа команд формирования адресного кода Задача сводится к выводу , впервые 3 защелки порта А , числа (.00 … .07), "лежащего " в регистре Index (рулевой "). Для этого достаточно всего двух команд movf Index,W и Естественно, что в этом случае, выводы порта А , управляющие внешним дешифратором, перед " влётом " в ПП динамической индикации, должны быть настроены на работу "на выход ". После выхода рабочей точки программы из ПП динамической индикации, их можно перестраивать под решение других задач Но только после этого выхода Направления работы остальных 2- х выводов порта А не важны (они не задействуются в ПП динамической индикации, но эти выводы могут быть как- то задействованы в группах подпрограмм и команд , осуществляющих различные операции, что на практике и происходит Соответственно , направления работы этих 2- х выводов будут определяться тем, что происходит в этих "различных операциях ". Идем дальше После того, как адресный код управления дешифратором сформирован (активировалось одно из знакомест, рабочая точка программы устанавливается на первую команду группы 240 команд задержки Эта группа команд есть нечто иное, как стандартная ПП задержки без "врезок ", на основе простейшего, однобайтного счетчика Это мы уже разбирали ранее, так что остановлюсь только на особенностях Команда movlw обращается к константе не напрямую, а через ее название, "прописанное " в "шапке " "программы ". Регистр Temp последний раз задействовался в группе команд вывода символов на индикацию При этом, свою функцию он исполнили на момент начала группы команд задержки, он является "свободным как ветер в поле ". А раз это так, то его можно повторно задействовать, но уже для записи в него (через регистр) константы, что и сделано Подобного рода многофункциональность я называю совмещением функций (Фигаро здесь, Фигаро там "). С регистрами Index или Count подобные "манипуляции проделывать " нельзя, так как любой из них, в течение бОльшей части цикла динамической индикации, выполняет одну функцию и поэтому , "со свободой у них проблемы ". Изменяя величину константы (это делается в "шапке "), можно "грубо " регулировать время отработки одного цикла малого кольца индикации, а соответственно , и большого тоже Вопрос : "Можно лине присваивать константе названия (а также и, а указать ее числовое значение в команде |