Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
Скачать 3.49 Mb.
|
PIC16F84A имеет 2 порта В порте В , можно использовать все 8 выводов В порте А , можно использовать 5 выводов Порт В , "в полном составе ", выделяется под управление сегментами 7- сегментных индикаторов (включая и запятую ), а функция последовательной активации знакомест передается в порт А Рассмотрим случай организации динамической индикации для линейки 7- сегментных индикаторов, состоящей из 8- ми знакомест Подпрограмма динамической индикации, о которой будет рассказано, достаточно универсальна, то есть, она может быть " врезана / встроена " в другие программы Разрядность можно будет уменьшить (просто) или увеличить (сложнее. Я об этом расскажу Советую Вам как следует разобраться стем, что Вы прочитаете Это очень востребовано Лично я, таки не встретил хотя бы более- менее внятного объяснения работы подобного рода подпрограммы, не говоря ужо какой- то универсальной "заготовке ", рассчитанной на начинающих (и не только. Потрошить " подпрограмму динамической индикации будем в 2 этапа - нам этапе, сформируем "скелет, - нам этапе, "нарастим на нем мясо ". По идее, при "разборках " с подпрограммами , нужно "отталкиваться " от ее блок - схемы В данном случае, я совместил текст подпрограммы с ее блок – схемой Это позволяет, не "распыляя " внимания, отслеживать и то , и другое , водном месте (в тексте подпрограммы. Походу дела, разберемся с косвенной адресацией, и я расскажу о "хитром " способе записи константы в регистр Первый этап Предмет разбирательства представляет собой текст программы с названием Fsr.asm , в которую "врезана " подпрограмма динамической индикации, обслуживающая линейку из 8- ми- сегментных индикаторов с общим катодом Это означает то, что внутри линейки, аноды светодиодов всех одноименных секторов запараллелены Таким образом, получается 8 " проволочин ", которые, через гасящие резисторы, подключаются к 8- ми выводам порта В 223 8 выводов общих катодов индикаторов подключаются к 8- ми выходам дешифратора 555 ИД 7 подробнее об этом ниже. Файл программы называется (находится в папке " Тексты программ. Это выглядит так ;******************************************************************************** ; ПРИМЕР ОРГАНИЗАЦИИ ДИНАМИЧЕСКОЙ ИНДИКАЦИИ С ИСПОЛЬЗОВАНИЕМ ; КОСВЕННОЙ АДРЕСАЦИИ ПРИ ОБРАЩЕНИИ К ТАБЛИЦЕ ДАННЫХ . ;******************************************************************************** ; " ШАПКА ПРОГРАММЫ " ;******************************************************************************** ; Универсальная группа подпрограмм разрядной динамической индикации. ;================================================================================ ; Определение положения регистров специального назначения. ;================================================================================ Indf equ 00h ; Регистр INDF. PC equ 02h ; Регистр счетчика команд. Status equ 03h ; Регистр Status. FSR equ 04h ; Регистр FSR. ;............................................................. ;............................................................. ;================================================================================ ; Определение названия и положения регистров общего назначения. ;================================================================================ LED0 equ 10h ; Регистр го сегментного индикатора. LED1 equ 11h ; ------- го ------------------------- LED2 equ 12h ; ------- го ------------------------- LED3 equ 13h ; ------- го ------------------------- LED4 equ 14h ; ------- го ------------------------- LED5 equ 15h ; ------- го ------------------------- LED6 equ 16h ; ------- го ------------------------- LED7 equ 17h ; ------- го ------------------------- Index equ 0Ch ; Регистр счетчика количества ; малых колец индикации. Count equ 0Dh ; Регистр счетчика количества ; больших колец индикации. ;............................................................. ;............................................................. ;================================================================================ ; Определение места размещения результатов операций. ;================================================================================ W equ 0 ; Результат направить в аккумулятор . F equ 1 ; Результат направить в регистр . ;================================================================================ ; Присваивание битам названий. ;================================================================================ Z equ 2 ; Флаг нулевого результата. ;............................................................. ;............................................................. ;================================================================================ org 0 ; Начать выполнение программы goto START ; с подпрограммы START. ;******************************************************************************** ;******************************************************************************** ; РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ ;******************************************************************************** ; Подготовительные операции. ;-------------------------------------------------------------------------------- 224 START ...................................... ;-------------------------------------------------------------------------------- ; Группа подпрограмм преобразования двоичных чисел в двоично - десятичные . ;-------------------------------------------------------------------------------- Bin2_10 ...................................... На данный момент, регистры LED0 ... LED7 заполнены двоично - десятичными числами, которые необходимо вывести на индикацию (отобразить) в линейку из 8- ми 7- сегментных индикаторов. На момент начала группы подпрограмм динамической индикации, все прерывания должны быть запрещены, выводы разрядного порта, к которому подключена линейка должны быть настроены на работу "на выход, работа должна происходить в нулевом банке. ;-------------------------------------------------------------------------------- ; Подготовка счетчика количества малых колец индикации Index к началу полного цикла динамической индикации. ;-------------------------------------------------------------------------------- clrf Index ; Сброс в 0 содержимого счетчика ; малых колец индикации Index. ;-------------------------------------------------------------------------------- ; Предварительная закладка количества больших колец индикации, которое нужно "пройти" за один полный цикл динамической индикации в регистр Count. ;-------------------------------------------------------------------------------- movlw X ; Запись константы X (количество больших ; колец индикации, задается программистом) ; в регистр W. movwf Count ; Копирование содержимого регистра W в ; регистр счетчика количества больших колец ; индикации Count. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Использование косвенной адресации при работе с таблицей данных. ;================================================================================ ; Подготовка к косвенной адресации запись в регистр W адреса регистра младшего разряда линейки сегментных индикаторов (привязка" к сегментному индикатору, с активации которого начинается полный цикл первого большого кольца индикации. ;-------------------------------------------------------------------------------- CYCLE movlw LED0 ; Запись в регистр W адреса регистра LED0. addwf Index,W ; Увеличение адреса регистра LED0 на величину ; числа, записанного в регистре счетчика ; количества малых колец индикации Index, ; c сохранением результата в регистре W. ;-------------------------------------------------------------------------------- ; Косвенная адресация. ;-------------------------------------------------------------------------------- movwf FSR ; Копирование содержимого регистра W ; в регистр FSR. movf Indf,W ; Копирование содержимого регистра с адресом , ; записанным в регистре FSR, в регистр W. call TABLE ; Условный переход (адрес следующей команды ; закладывается в стек ) в ПП TABLE. ;---> Возврат по стеку из ПП TABLE. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Группа команд установки запятой. ;-------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------- ; Группа команд формирования адресного кода управления дешифратором. ;-------------------------------------------------------------------------------- 225 ;-------------------------------------------------------------------------------- ; Группа команд вывода десятичной цифры на индикацию (в порт. ;-------------------------------------------------------------------------------- Начало визуального отображения цифры водном из сегментных индикаторов (зависит от адресного кода управления дешифратором- ; Группа команд задержки, определяющей время нахождения одного сегментного индикатора в активном состоянии (определяющей время прохождения малого кольца индикации. ;-------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------- ; Увеличение на 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, то программа ; исполняется далее (переход на новый полный ; цикл динамической индикации. nop ; Выравнивающий NOP. ;-------------------------------------------------------------------------------- ; Группы подпрограмм и команд , осуществляющие различные операции. ;-------------------------------------------------------------------------------- На данный момент, регистры LED0 ... LED7 заполнены двоичными числами, которые, в дальнейшем, нужно преобразовать в двоично - десятичные и сохранить их все в тех же регистрах LED0 ... LED7. 226 goto Bin2_10 ; Безусловный переход в ПП Bin2_10. ;-------------------------------------------------------------------------------- ; Применение вычисляемого перехода. ; (преобразование двоично - десятичного кода в код сегментного индикатора) ;-------------------------------------------------------------------------------- TABLE addwf PC,F ; Содержимое счетчика команд PC увеличивается ; на величину содержимого аккумулятора W. retlw b'00111111' ; ..FEDCBA = 0 Происходит скачек по таблице retlw b'00000110' ; .....CB. = 1 на строку со значением retlw b'01011011' ; .G.ED.BA = 2 записанным в аккумуляторе , retlw b'01001111' ; .G..DCBA = 3 и далее - возврат по стеку 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 ; Конец программы. Отталкиваемся " от общего принципа динамической индикации, суть которого заключается в последовательной активации 7- сегментных индикаторов (знакомест. Активация индикатора это, образно выражаясь, его "загорание ". Чаще всего, полный цикл активации начинается с младшего по разрядности, 7- сегментного индикатора (правого в линейке ). К этому и "привяжусь ". Некоторое время, он находится в активном состоянии, после чего "гасится " (переводится в пассивное состояние, и тут же активируется следующий индикатор (более старшего разряда. Некоторое время, он находится в активном состоянии, после чего "гасится " (переводится в пассивное состояние, и тут же активируется следующий индикатор (более старшего разряда. Ну итак далее До тех пор, пока не "погаснет " индикатор самого старшего разряда Сразу же после его "погасания " (перехода в пассивное состояние, текущий, полный цикл активации заканчивается, и начинается следующий, полный цикл активации (активируется самый младший разряд. Всё повторяется снова И так происходит много раз Вот Вам и типичная " закольцовка ", которую и нужно реализовать в группе подпрограмм динамической индикации Назовем это кольцо большим кольцом индикации . Время "прохождения ", рабочей точкой программы, большого кольца индикации, равно суммарному времени активации всех 8- ми разрядов линейки После активации, каждый из индикаторов должен какое- то время "погореть " (какое- то время находиться в активном состоянии, что вполне понятно, а иначе мы просто ничего не увидим Таким образом, речь идет о задержке , суть которой - всё та же " закольцовка ". Вот Вам и еще одна " закольцовка ", которую нужно реализовать в группе подпрограмм динамической индикации Назовем это кольцо малым кольцом индикации. Время "прохождения ", рабочей точкой программы, малого кольца индикации, будет враз меньше времени "прохождения " большого кольца индикации Следовательно , время "прохождения ", рабочей точкой программы, большого кольца индикации, ставится в зависимость (привязывается ") от времени "прохождения " малого кольца индикации Таким образом, интервал времени "прохождения ", рабочей точкой программы, малого кольца индикации, является "базовым ". От него зависит и скорость последовательной активации разрядов линейки, и время отработки цикла большого кольца индикации Если эту скорость сделать маленькой, то будет визуально наблюдаться процесс так называемых " мерцаний " (визуально ощущаемых активаций. 227 Естественно, что это неудобно Поэтому, скорость последовательной активации знакомест линейки нужно стремиться сделать как можно большей, нов пределах разумного (компромисс. То есть, эта скорость должна быть такой, чтобы и минимизировать негативные последствия " мерцаний ", и существенно не снизить яркость свечения индикаторов Далее , возникает вопрос о "рулевом ", ведь процессом последовательной активации нужно как- то "рулить ". То есть, должно быть нечто, дающее "отмашку " на начало активации следующего разряда линейки (после того, как активация предыдущего разряда линейки закончится. По здравому разумению, это нечто должно быть "встроено " в малое кольцо индикации и иметь "привязку " к количеству задействованных индикаторов линейки После окончания активации текущего знакоместа линейки, содержимое этого нечто должно измениться на 1 ( увеличиться / уменьшиться ) таким образом, чтобы наследующем, малом кольце индикации, произошла активация следующего, по старшинству, индикатора линейки С учетом сказанного, нетрудно догадаться, что "роль этого нечто исполняет " регистр общего назначения В данном случае, это регистр с названием |