Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
Скачать 3.49 Mb.
|
Intcon equ 0Bh ; Регистр Intcon. Status equ 03h ; Регистр Status. EEData equ 08h ; EEPROM - данные equ 08h ; EECON1 - банк. EEAdr equ 09h ; EEPROM - адрес equ 09h ; EECON2 - банк. ;............................................................. ;================================================================================ ; Определение названия и положения регистров общего назначения. ;================================================================================ Registr equ 0Ch ; Регистр оперативной памяти, используемый ; при работе с EEPROM. ;............................................................. ;================================================================================ ; Определение места размещения результатов операций. ;================================================================================ W equ 0 ; Результат направить в аккумулятор . F equ 1 ; Результат направить в регистр . ;================================================================================ ; Присваивание битам названий. ;================================================================================ RP0 equ 5 ; Бит выбора банка. GIE equ 7 ; Бит глобального разрешения прерываний. ;================================================================================ 180 org 2100h ; Обращение к EEPROM памяти данных. DE 0h,0h,64h ; Записать в ячейки с адресами .0, .1, .2 ; числа 0h, 0h, 64h (.100) соответственно. DE 0h,0h,0h ; Записать в ячейки с адресами .3, .4, .5 ; числа 0h, 0h, 0h соответственно. DE "Korabelnikow E.A. Rus. Lipetsk. 03.2005" ; Записать ; символы в ячейки с адресами с .6 по .46 ;================================================================================ org 0 ; Начать выполнение программы goto START ; с подпрограммы START. ;******************************************************************************** ;******************************************************************************** ; РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ ;******************************************************************************** START ; ......................... ;............................................................. ;================================================================================ ; Чтение данных из EEPROM ;================================================================================ ; Считывание содержимого байта с адресом 02h и запись его в регистр общего назначения Registr. ;-------------------------------------------------------------------------------- bcf Status,RP0 ; Переход в нулевой банк. movlw 2 ; Записать в регистр W константу 02h. movwf EEAdr ; Скопировать 02h, из регистра W, ; в регистр EEAdr. bsf Status,RP0 ; Переход в первый банк. bsf EECon1,0 ; Инициализировать чтение. bcf Status,RP0 ; Переход в нулевой банк. movf EEData,W ; Скопировать число из ячейки EEPROM ; с адресом 02h, в регистр W. movwf Registr ; Скопировать число, из регистра W, ; в регистр Registr. ;-------------------------------------------------------------------------------- ; Изменение содержимого регистра Registr. ;-------------------------------------------------------------------------------- incf Registr,F ; Увеличить на 1 содержимое регистра Registr с ; сохранением результата в нем же. ;================================================================================ ; Запись данных в EEPROM. ;================================================================================ ; Запись содержимого регистра Registr в ячейку EEPROM с адресом 02h. ;-------------------------------------------------------------------------------- bcf Intcon,GIE ; Глобальный запрет прерываний. movlw 2 ; Записать в регистр W константу 02h. movwf EEAdr ; Скопировать константу 02h, из регистра W, ; в регистр EEAdr. movf Registr,W ; Скопировать число, из регистра Registr, в ; регистр W. movwf EEData ; Скопировать число, из регистра W, в ячейку ; EEPROM с адресом 02h. bsf Status,RP0 ; Переход в первый банк. bsf EECon1,2 ; Разрешить запись movlw 055h ; Обязательная movwf EECon2 ; процедура movlw 0AAh ; при записи. movwf EECon2 ; ----"---- bsf EECon1,1 ; ----"---- bcf EECon1,4 ; Сбросить флаг прерывания по окончании ; записи в EEPROM. 181 bcf Status,RP0 ; Переход в нулевой банк. ;------------------------------------------------------------------ ; Примечание время исполнения полного цикла программы должно быть более времени, необходимого для окончания записи в EEPROM. ;------------------------------------------------------------------ ;................................................................... goto START ; Переход на новый цикл программы. ;******************************************************************************** end ; Конец программы. В ней организован полный цикл программы и точками с запятыми заблокировано то, по поводу чего "ругается ". Смысл примечания время исполнения полного цикла программы должно быть более времени, необходимого для окончания записи в EEPROM , будет раскрыт позднее Под программу, создайте проект, загрузите ее в проект и произведите ассемблирование После этого, откройте окно Window ( Window EEPROM Memory ), назначьте точку остановки на команде START на той, ниже которой расположена директива) и сбросьте программу на начало А теперь от души пощелкайте по кнопке с зеленым светофором (или по клавише) и обратите внимание на ячейку EEPROM памяти с адресом 02h. Вы увидите, что с каждым таким "щелчком ", ее содержимое будет увеличиваться на единицу В ПИКах предусмотрены меры по предотвращению случайной записи в EEPROM память данных, при сбоях в работе программы, снижении напряжения питания и других "гадостях ". Если бит защиты (см биты конфигурации) установлен, то считать данные, из EEPROM памяти данных, с помощью программатора, теоретически, нельзя На работе программы, "зашитой " в ПИК , это не отражается При записи, теоретически, могут быть совершены ошибки, но практически, их вероятность мала В "особо ответственных " программах, задействующих EEPROM память данных, организуются проверки правильности записи По принципу сверки "эталона " (того, что должно записаться) c фактическим (считываемым после записи) результатом записи (так называемая верификация. По результатам этой сверки, делается вывод о том , должна ли программа исполняться далее или нужно повторить запись дополучения совпадения, а только после этого исполнять ее далее Это случай побайтной проверки В том случае, если требуется проверить правильность записи группы байтов (массива " данных, то критерием безошибочности или ошибочности записи может быть так называемая "контрольная сумма ". Во многих случаях, контрольная сумма есть результат простейшего, последовательного суммирования по кольцу (для того чтобы сформировать однобайтный результат суммирования) всех числовых значений байтов "массива " данных Естественно , что для того чтобы было с чем сравнивать, до проверки на контрольную сумму, должен быть сформирован "эталон ". В случае обнаружения расхождения, производится перезапись всего этого "массива " данных, вплоть до устранения этого расхождения Можно применить и другие виды проверок, например, по признаку четности или нечетности Это , как говорится, личное дело каждого программиста " Самоучитель по программированию PIC контроллеров для начинающих" http://ikarab.narod.ru E-mail: karabea@lipetsk.ru 182 13. Флаги Работа с флагами Как работает цифровой компаратор Перенос и заем Ранее , во 2- м разделе , я упоминал о флагах Пришла пора с некоторыми из них разобраться Посмотрите в распечатки регистров специального назначения Названия битов флагов выделены зеленым цветом Естественно , что слово "флаг " нельзя воспринимать буквально Это аналогия Факт поднятие флага "сигнализирует" о том, что произошло какое - то конкретное событие. Факт "опущения" (сброса) флага "сигнализирует" о том, что этого конкретного события не произошло . Каждый флаг "привязывается " к "своему " типу события Например , один флаг "реагирует " на факт наличия или отсутствия нулевого результата произведенной операции (флаг, другой флаг "реагирует " на факт наличия или отсутствия переполнения сторожевого таймера (флаг, третий, на факт наличия или отсутствия переноса- зама (флаги т д Исходя из этого, становится понятными их практическое предназначение анализируя состояния флагов, программист может осуществлять контроль за результатом исполнения задуманных им операций, совершаемых при помощи команд, к которым "привязаны " те или иные флаги (см правый столбец распечатки команд. В этом смысле, они удобны тем, что как бы выполняют функции "виртуального пробника ", ведь программист не может "заглянуть " внутрь ПИКа и что - тов нем замерить, с использованием реального пробника С помощью флагов, программист может поставить ход исполнения программы в зависимость от фактов их поднятия или "опущения ", что наиболее востребовано на практике Существуют 2 группы флагов К первой группе относятся флаги, после поднятия которых, их ненужно программно сбрасывать . Они "реагируют " и на наличие факта "привязанного " к ним события (флаг поднят, и на его отсутствие (флаг опущен. Например, если с помощью команды (ноне с помощью команды, так как она не оказывает влияния на флаги) осуществляется декремент числа .01, то, после первого декремента (результат операции .00), флаг нулевого результата автоматически поднимется ( бит Z установится в 1), а после следующего декремента (результат операции .255), он автоматически сбросится ( бит Z установится в 0). Ко второй группе относятся флаги, после поднятия которых, их нужно программно сбрасывать . Проще говоря, один раз поднявшись, эти флаги не сбросятся до тех пор, пока программист их "принудительно " не сбросит программными средствами Например , в ранее рассмотренной программе, флаг внешнего прерывания по входу INT с названием, при наличии внешнего прерывания по входу, устанавливается в 1 (поднимается. Если его не сбросить (0) в интервале времени отработки ПП прерывания (до команды, то после возврата из ПП прерывания , факт поднятия этого флага будет "восприниматься " ПИКом как наличие управляющего сигнала "ухода " в прерывание по входу INT, со всеми вытекающими из этого, "мерзопакостными " последствиями (работа программы нарушится. Именно по этой причине, флаг, до исполнения команды, нужно обязательно сбросить Посмотрите в распечатки регистров специального назначения Те флаги, в комментариях к которым указано " сбрасывается программно, относятся ко 2- й группе флагов, а те флаги, в комментариях к которым этого нет, относятся к 1- й группе флагов Таким образом, флаги 1- й группы можно назвать как бы "безобидными ". В том смысле, что если их состояния программно не анализируются (об этом будет рассказано далее, тона работу программы они не оказывают влияния Проще говоря, в этом случае, они "всем скопом " могут как угодно подниматься и опускаться Работа устройства от этого не нарушится Флаги 2- й группы не такие "безобидные ". За их состояниями нужно следить (учитывать при составлении программы. 183 Если такие флаги задействованы в программе , то после того как любой из них поднялся, его обязательно нужно программно сбросить Если этого не сделать, то "наказание " последует незамедлительно (нарушение работы программы. Посмотрите в распечатку команд В правом столбце, с названием Флаги, Вы увидите стандартные названия флагов (битов флагов, на которые воздействует таили иная команда Есть команды, которые воздействуют сразу на несколько флагов (например, ADDWF ), есть команды, которые воздействуют на один флаг (например, CLRF ), а есть и команды , которые не воздействуют на флаги (например, DECFSZ ). Если Вы сравните общее количество различных флагов "прописанных " в распечатке команд ив распечатках регистров специального назначения, то Вы заметите, что в распечатке команд, их количество меньше, чем в распечатках регистров специального назначения Объяснение этому следующее В распечатках регистров специального назначения, Вы видите все флаги, а команды воздействуют только на их часть В правом столбце распечатки команд, Вы не найдете флагов 2- й группы Проанализировав содержимое этого столбца, Вы убедитесь в том , что наиболее часто встречается флаг нулевого результата Z П о этой причине, он заслуживает особого внимания Возникает вопрос "Могут ли флаги, кроме контрольных функций, выполнять какие- либо более значимые функции Например , каким- то образом воздействовать на ход исполнения программы "? Ответ : да , могут И еще как могут. Ранее уже говорилось о том , к чему может привести отсутствие программного сброса флагов- й группы Это есть нечто иное, как прямое воздействие на ход исполнения программы Флаги 1- й группы также могут влиять на ход исполнения программы, но только несколько иным, косвенным образом Далее , будем работать с одним из самых "ходовых " флагов, флагом нулевого результата Z Изначально , в обучающе - тренировочных целях, принцип работы с ним можно определить так перед исполнением команды (эта команда должна воздействовать на флаг, флаг Z сбрасывается (2- й бит регистра STATUS устанавливается в 0), а потом выполняется команда, с последующим анализом его ( Z ) состояния Сразу оговорюсь такое определение принципа работы с флагом Z (и вообще, с флагами 1- й группы ), совсем не является рациональным, но позволяет " вжиться / вживиться " в "механику " его работы, а это сейчас и есть самое главное Результат исполнения команды (число) может быть нулевым или ненулевым, то есть возможны 2 сценария Из этого следует то, что если проанализировать состояние флага Z после исполнения команды, которая влияет на состояние флага, то можно "разветвить " программу на 2 сценария Таким образом, выбор одного из двух сценариев дальнейшей работы программы ставится в зависимость от ответа на вопрос "Каков результат исполнения команды нулевой или ненулевой Анализ состояния флага (и других флагов тоже) осуществляется с помощью бит- ориентированных команд ветвления btfsc или btfss В результате исполнения любой из них, происходит ветвление на 2 сценария - в один из них, рабочая точка программы "уходит " при нулевом результате исполнения, команды (она должна воздействовать на флаг, которая предшествует команде ветвления, - а в другой, при ненулевом результате исполнения той же команды Пример . Допустим, что необходимо составить программу под устройство типа "реле времени " например, для фотопечати. То есть, имеется кнопка, после нажатия на которую, производится отсчет заданного интервала времени Таким образом, речь идет о счетчике , который, конечно же, можно реализовать так, как это 184 сделано в программах Multi или cus Но в нашем случае, нужно пофантазировать и "родить " вычитающий счетчик, работающий по принципу анализа состояния флага нулевого результата Z Фрагмент этого счетчика будет выглядеть так .................... XYZ .................... .................... bcf Status,2 decf ABC,F btfss Status,2 goto XYZ .................... .................... ABC - название регистра общего назначения, XYZ - название циклической подпрограммы, строки с точками - предыдущие и последующие команды программы Вы видите, что этот фрагмент "врезан " в программу , и по логике работы устройства, эта группа команд должна начать работать только после нажатия на кнопку запуска Пока кнопка не нажата, рабочая точка программы должна "крутиться " где- тов программе, обходя " указанную выше группу команд, и при этом, состояние кнопки запуска должно опрашиваться (состояние ожидания нажатия кнопки. После нажатия на кнопку и последующего , очередного опроса клавиатуры, факт ее нажатия будет обнаружен, и рабочая точка программы, на некоторое время, " закольцуется " в циклической подпрограмме, "поставленной на счетчик " (задержка. Указанная выше группа команд, должна входить в состав этой циклической подпрограммы "на правах отфутболивателя рабочей точки ". При таком "раскладе ", рабочая точка программы может выйти из циклической подпрограммы только при условии, что флаг нулевого результата поднялся ( |