Файл: Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 16.06.2025
Просмотров: 3584
Скачиваний: 3
2. В ПП прерывания, интервал времени отработки одного цикла задержки: 5,62 мс. (точка остановки одна: btfsc PortB,0 (от этой точки остановки, и через один "виток", до нее же). Примечание: собственно говоря, отладки, как таковой, и не было (константы не менялись), а была просто проверка величин задержек, которые уже были отлажены ранее.
Чтобы процесс отладки был "полноценным", для тренировки, можете изменить исходные требования к этим величинам, и руководствуясь принципом отладки, описанным при отладке программы cus, произвести отладку программы Retr_1.asm.
Итак, отладка закончена, и HEX-файл программы Retr_1.asm можно открывать в программе, обслуживающей Ваш программатор, после чего можно "прошить" ПИК.
При этом, вероятность того, что устройство будет работать именно так, как задумано, велика. А теперь о программе, выполняющей то же самое, но без уходов в прерывания.
Файл текста программы называется Retr_3.asm (находится в папке "Тексты программ").
Программа выглядит так:
;********************************************************************************
; Retr_3.asm |
ВАРИАНТ БЕЗ |
ПРЕРЫВАНИЙ |
|
; |
Сканер для ретранслятора VERTEX-7000VXR. |
||
; Автор: Корабельников Евгений Александрович |
г.Липецк декабрь 2004г. |
||
; E-mail: karabea@lipetsk.ru |
http://ikarab.narod.ru |
||
;********************************************************************************
;Позволяет перевести VERTEX-7000VXR и другие подобные ретрансляторы из режима
;односторонней ретрансляции в режим двухсторонней ретрансляции без потери
;качества работы.
;Объем программы: 40 слов в памяти программ.
;Используется микроконтроллер PIC16F84A. Частота кварца 4000кГц.
;********************************************************************************
LIST |
p=16F84a |
; |
Используется |
PIC16F84A. |
|
__CONFIG |
03FF5H |
; |
WDT включен, |
бит защиты |
не установлен. |
;================================================================================
; Определение положения регистров специального назначения.
;================================================================================
OptionR |
equ |
01h |
; Option - банк1 |
||
Status |
equ |
03h |
; Регистр Status |
||
PortB |
equ |
06h |
; Порт |
B |
|
TrisB |
equ |
06h |
; |
Tris |
B - Банк1 |
IntCon |
equ |
0Bh |
; |
Регистр IntCon |
|
;================================================================================
; Определение названия и положения регистров общего назначения.
;================================================================================
Trigg |
equ |
0Ch |
; Переключатель направления ретрансляции. |
SecH |
equ |
1Eh |
; Старший байт счетчика времени сканирования. |
SecL |
equ |
1Fh |
; Младший байт счетчика времени сканирования. |
SecH_1 |
equ |
1Ch |
; Старший байт счетчика защитного интервала |
; времени. |
|||
SecL_1 |
equ |
1Dh |
; Младший байт счетчика защитного интервала |
; времени. |
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
F equ 1 ; Результат направить в регистр.
;================================================================================
; Определение положения бита выбора банка.
;================================================================================
RP0 equ 5 ; Бит выбора банка.
;================================================================================
; Точка входа в программу.
;================================================================================
org |
0 |
; |
Начать |
выполнение программы с нулевого |
goto |
START |
; |
адреса |
PC |
;********************************************************************************
156
;******************************************************************************** ; РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ
;********************************************************************************
; Подготовительные операции. |
|||
;-------------------------------------------------------------------------------- |
|||
START |
clrf |
IntCon |
; Запретить все прерывания. |
clrwdt |
; Сбросить сторожевой таймер WDT. |
||
bsf |
Status,RP0 |
; Установить банк 1. |
|
movlw |
.1 |
; RB0 работает на вход, |
|
movwf |
TrisB |
; остальные - на выход. |
|
movlw |
.0 |
; Включить подтягивающие резисторы порта В. |
|
movwf |
OptionR |
; Остальное - не существенно. |
|
bcf |
Status,RP0 |
; Установить банк 0. |
|
;-------------------------------------------------------------------------------- |
|||
; Выбор направления ретрансляции. |
|||
;-------------------------------------------------------------------------------- |
|||
TRIGGER |
btfsc |
Trigg,0 |
; Проверка значения нулевого бита |
; регистра Trigg. |
|||
goto |
Metka148 |
; Если это значение =1, то переход |
|
; на метку Metka148. |
|||
; Если это значение =0, то программа |
|||
; исполняется далее. |
|||
movlw |
.251 |
; Закладка константы .251 (1111 1011) |
|
; в регистр W. |
|||
movwf |
PortB |
; Копирование .251 из регистра W |
|
; в регистр PortB (выбор прямого направления |
|||
; ретрансляции: ПРМ-X, ПРД-Y). |
|||
goto |
Metka_1 |
; Безусловный переход на метку Metka_1. |
|
Metka148 |
movlw |
.255 |
; Закладка константы .255 (1111 1111) |
; в регистр W. |
|||
movwf |
PortB |
; Копирование .255 из регистра W |
|
; в регистр PortB (выбор обратного направления |
|||
; ретрансляции: ПРМ-Y, ПРД-X). |
|||
;-------------------------------------------------------------------------------- |
|||
;Формирование защитного интервала времени (ожидание окончания переходных
;процессов, возникающих при смене направлений ретрансляции) равного,
;примерно, 60 мс.
;-------------------------------------------------------------------------------- |
|||
Metka_1 |
movlw |
.197 |
; Закладка в регистр W константы .197 |
movwf |
SecH_1 |
; Копирование константы .197 из регистра W |
|
; в регистр SecH_1. |
|||
movlw |
.121 |
; Закладка в регистр W константы .121 |
|
movwf |
SecL_1 |
; Копирование константы .121 из регистра W |
|
; в регистр SecL_1. |
|||
PAUSE_D |
clrwdt |
; Сброс WDT. |
|
decfsz |
SecL_1,F |
; Декремент содержимого младшего разряда |
|
; счетчика SecL_1. |
|||
goto |
PAUSE_D |
; Если результат декремента не=0, то переход |
|
; в ПП PAUSE_D. |
|||
incfsz |
SecH_1,F |
; Если результат декремента =0, то инкремент |
|
; старшего разряда счетчика SecH_1. |
|||
goto |
PAUSE_D |
; Если результат инкремента не=0, то переход |
|
; в ПП PAUSE_D. |
|||
; Если результат инкремента =0, то программа |
|||
; исполняется далее. |
;================================================================================
; Формирование интервала времени сканирования.
;================================================================================
movlw |
.245 |
; Закладка константы .245 в регистр W. |
|
movwf |
SecH |
; Копирование .245 |
из регистра W |
; в регистр SecH. |
|||
movlw |
.255 |
; Закладка константы .255 в регистр W. |
|
movwf |
SecL |
; Копирование .255 |
из регистра W |
; в регистр SecL. |
|||
157
;-------------------------------------------------------------------------------- |
||||
PAUSE |
clrwdt |
; Сброс WDT. |
||
btfss |
PortB,0 |
; Несущая есть? |
||
goto |
PAUSE |
; Да. |
||
btfss |
PortB,0 |
; Нет. Программа |
выполняется далее. |
|
; Несущая есть ? |
||||
goto |
PAUSE |
; Да. |
||
decfsz |
SecL,F |
; Нет. Декремент |
содержимого младшего разряда |
|
; счетчика SecL. |
||||
goto |
PAUSE |
; Если результат |
декремента не=0, то переход |
|
; в ПП PAUSE. |
||||
incfsz |
SecH,F |
; Если результат |
декремента =0, то инкремент |
|
; старшего разряда счетчика SecH. |
||||
goto |
PAUSE |
; Если результат |
инкремента не=0, то переход |
|
; в ПП PAUSE. |
||||
; Если результат |
инкремента =0, то программа |
|||
; исполняется далее. |
||||
;-------------------------------------------------------------------------------- |
||||
; Изменение |
направления ретрансляции. |
|||
;-------------------------------------------------------------------------------- |
||||
incf |
Trigg,F |
; Увеличение на 1 (инкремент)содержимого |
||
; переключателя направления ретрансляции. |
||||
goto |
START |
; Переход на новый цикл сканирования. |
||
;******************************************************************************** end ; Конец программы.
Сравните тексты программ Retr_1.asm и Retr_3.asm
Если Вы хорошо усвоили предыдущую информацию, то текст программы Retr_3.asm , а также и его отличия от текста программы Retr_1.asm, не будут вызывать у Вас затруднений. Если это не так, то вернитесь назад и найдите там ответы на Ваши вопросы.
Программу Retr_3.asm можно использовать как некую "лакмусовую бумажку": пока Вам в ней что-то не понятно, то не стОит переходить к изучению следующих разделов, а лучше разобраться с предыдущими.
В идеале, программа Retr_3.asm должна быть Вам понятна "от и до". Замечания по прерываниям.
Целью "вышележащих разборок" с прерываниями является только формирование общих понятий о них.
Описанное выше устройство не идеально в том смысле, что имеется достаточно большая "зона" запрета прерываний.
Хотя, в данном случае, специфика работы ретранслятора Vertex-7000VXR такова, что допускает наличие такой "зоны", но при создании программ под другие устройства, такой подход может быть неприемлем.
Более детальные "разборки" с прерываниями будут произведены позднее.
Дополнительно
Разберемся с той "мутью", которая подпортила нервы тем, кто ее заметил (5 баллов за внимательность) и выдал сигналы SOS.
Открываем проект Retr_1.
При этом, MPLAB выставит совершенно однозначные настройки по умолчанию. Нас интересует регистр PortB, и в частности, его бит с № 0.
По умолчанию, он установлен в 0 (см. окно SFR).
Пошагово исполняем программу до момента установки единицы в бите №0 регистра TrisB (перевод вывода RB0 на работу "на вход").
После этого смотрим, не изменилось ли состояние нулевого бита регистра PortB? Не изменилось. Как был 0, так он и остался.
Вывод: на выводе порта, настроенном на работу как "на выход", так и "на вход", по умолчанию, MPLAB выставляет 0.
Пошагово исполняем программу далее, обращая внимание только на то, что связано с командами, которые обращаются к содержимому регистра PortB.
158
По ходу исполнения программы, первой такой командой является команда копирования содержимого регистра W в регистр PortB (movwf PortB).
В аккумуляторе (W) находится число .251, и казалось бы, именно оно должно скопироваться в порт В.
Исполняем команду movwf PortB. Смотрим в окно SFR.
А скопировалось-то не .251, а .250.
???
Ради "спортивного интереса", можете поподставлять, вместо .251, другие числовые значения констант и убедиться в том, что все нечетные числа "превращаются" в четные, а с четными числами проблем нет.
О чем это говорит?
Это говорит о том, что в бите №0 регистра PortB, "намертво застолблён" ноль, выставленный MPLAB по умолчанию.
Дело в том, что MPLAB отражает состояния выводов порта.
То есть, если вывод порта настроен на работу "на выход", то по причине того, что в этом случае, выход защелки подключается к выводу порта, состояние вывода порта будет соответствовать состоянию его "персональной" защелки.
Что же тогда мы видим в бите №0?
Мы видим уровень, выставленный MPLAB по умолчанию, для вывода порта работающего "на вход" (0). Вот и весь сказ.
Свидетельствует ли это о какой-то ошибке в работе программы/"железяки"? Нет, не свидетельствует.
Образно выражаясь, откуда MPLABу знать, какой уровень выставит внешнее устройство? Вот он, не мудрствуя лукаво, по умолчанию, и выставляет на тех выводах порта, которые работают "на вход", нулевые уровни.
С помощью функций стимула, на выводе порта, который работает "на вход", можно сымитировать единицу (в MPLAB это можно сделать), но в данном случае, проще узнать "в чем собака порылась" и сделать соответствующие выводы, чем что-то имитировать.
От этого "извилина крепчает" и прибавляется опыт.
"Самоучитель по программированию PIC контроллеров для начинающих" http://ikarab.narod.ru E-mail: karabea@lipetsk.ru
159
12.Организация вычисляемого перехода. Работа с EEPROM памятью данных.
Впредыдущих разделах я стремился объяснить Вам некоторые фундаментальные основы программирования микроконтроллеров (любых).
На данный момент Вы должны отчетливо представлять себе общие принципы составления текста программы, движения рабочей точки программы по командам текста программы, и самое главное, Вы должны понять зачем нужны подпрограммы задержек, их предназначение и основные функции, так как программирование без задержек это все-равно что машина без мотора.
Все циклические подпрограммы "базируются" на задержках и такой термин, как "закольцовка", тоже "из этой же оперы".
Именно задержки составляют основу программы.
И сама программа представляет собой одно большое "кольцо", внутри которого может быть какое-то количество "колец рангом пониже", а в этих "кольцах", в свою очередь, может находиться какое-то количество "колец рангом еще ниже" и т.д.
Движение рабочей точки программы по полному циклу программы можно сравнить со взлетом и посадкой самолета, между которыми он совершает несколько "мертвых петель".
Видеале, программист должен четко и ясно представлять себе функцию каждого кольца, его "конструкцию" и правила его функционирования.
Есть еще и другие, несомненно, важные "вещи", на которые, до конца не разобравшись с "кольцевой природой" программ, "клюют" начинающие программисты, совершая тем самым серьезную, стратегическую ошибку.
Это вполне может привести к трудностям в представлении общей "картины" работы программы, даже если человек неплохо разбирается с ее составными частями. Так что не жалейте времени на "разборки" с задержками ("кольцами").
Этот труд однозначно окупится.
И еще один добрый совет: если Вы хотите разобраться с работой программы, то не пожалейте времени на ее общий анализ и составление, по его результатам, блок-схемы программы. В дальнейшем, это сэкономит много времени и нервов.
А теперь начинаем разбираться с другими важными "вещами".
Организация вычисляемого перехода
Понятие вычисляемого перехода было вкратце сформулировано во 2-м разделе. Теперь, подробнее.
Нам уже известно, что команды ветвления "порождают" 2 сценария работы программы.
А как быть, если нужно "компактно разветвиться", например, на 3, 4, 5 и более сценариев? Это можно сделать при помощи вычисляемого перехода (стандартное название операции). Вычисляемый переход осуществляется при помощи команды addwf PC,F, которая формально описывается так: сложить содержимое регистров W и PC, с сохранением результата сложения в регистре PC (имеется ввиду младший разряд счетчика команд с названием PCL).
Неформально, эта команда описывается так: увеличить (прирастить) текущее значение содержимого счетчика команд PC на величину содержимого регистра W.
То же самое можно сказать и о формальном толковании команды addwf PC,W. Разница только в том, что результат сложения будет сохранен в регистре W. Таким образом, из-за того, что результат операции сохранится в регистре W, будет осуществлено приращение не счетчика команд, а аккумулятора.
По этой причине, команду addwf PC,W нельзя использовать в качестве команды вычисляемого перехода.
Итак, для организации вычисляемого перехода, применяется команда addwf PC,F
Эта команда, в тексте программы, может располагаться где угодно (там, куда ее вставит программист), и соответственно, адрес этой команды, в памяти программ, может быть различным.
Так вот, для вычисляемого перехода, этот адрес является как бы начальной точкой отсчета. Пример: программист составляет программу. Он "дошел до того ее места", где нужно "разветвить" программу, например, на 4 сценария (для того чтобы впоследствии "уйти" на исполнение того или иного из этих 4-х сценариев).
160