Файл: Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 16.06.2025
Просмотров: 3609
Скачиваний: 3
При отсутствии команды сброса флага прерывания, рабочая точка программы, после ухода в первое прерывания, начнет неконтролируемо "метаться" между ПП прерывания и "основным телом" программы (программа "уходит в глюк").
Проще говоря, если флаг прерывания "принудительно" (программно) не сброшен, то это "воспринимается" ПИКом как управляющий сигнал "ухода" в ПП прерывания.
Вывод: на момент возврата из ПП прерывания, флаг (флаги) прерывания должен
быть программно сброшен (установлен в 0).
Специалисты Микрочипа рекомендуют, в начале ПП прерывания, сохранить содержимое регистров STATUS и W в специально созданных, под это дело, регистрах общего назначения (стандартные названия: Stat_Temp и W_Temp, но они могут быть и другими), а в конце ПП прерывания, восстановить их содержимое.
Дело в том, что по ходу исполнения ПП прерывания, содержимое регистров STATUS и W может измениться, и после возврата из ПП прерывания, это содержимое может негативным образом повлиять на исполнение программы в "основном теле" программы.
В части касающейся заданного (прерывания по входу RB0/INT), для организации работы с прерываниями, необходимо:
-в "шапке" программы, назначить вектор прерывания,
-назначить источник прерывания (INTCON),
-определить активный фронт прерывания (OPTION),
-создать "зону" разрешения прерываний,
-в начале ПП прерывания, сохранить, а в конце ПП прерывания, восстановить содержимое регистров STATUS и W,
-перед осуществлением возврата из ПП прерывания, сбросить флаг прерывания выбранного источника прерываний,
-в самом конце ПП прерывания, исполнить команду retfie.
Итак, уходим в прерывание.
Сразу возникает вопрос: "Что там будем делать"?
Исходя из того, что рабочая точка программы должна находиться в ПП прерывания все время, пока приемник фиксирует наличие несущей (управляющий сигнал "несущая есть"), вывод напрашивается сам по себе: в ПП прерывания, нужно "закольцевать" рабочую точку программы в "вечном кольце", то есть, сделать то, чем мы уже занимались раньше.
При этом, нужно организовать проверку типа "несущая есть/нет?" (опрос клавиатуры), с уходом рабочей точки программы в циклическую ПП задержки (при наличии несущей), основой которой является многоразрядный счетчик, и выходом из нее при "пропадании" несущей.
Ранее мы рассматривали работу вычитающего счетчика.
Теперь же, в обучающих целях, а заодно и для разнообразия, сделаю этот счетчик комбинированным, то есть, вычитающе - суммирующим (забегаю вперед: счетчик - двухразрядный).
В "основном теле" программы, сначала, нужно произвести подготовительные операции (ПП
START).
Необходимо чем-то переключать направления ретрансляции, следовательно, нужно создать нечто типа "триггера", который управлял бы сменой "раскладок" частот.
Состояние этого "триггера" должно периодически опрашиваться, и в зависимости от этого, должен быть осуществлен переход на ту или иную раскладку частот.
Пусть опрос состояния "триггера" будет производиться сразу после ПП START, а изменение его состояния - в конце цикла "основного тела" программы (а можно и наоборот).
Между этим опросом и этим изменением, в простейшем случае (без учета специфики управляемого устройства), нужно сформировать "сплошную зону" разрешения прерываний, но этого делать нельзя по следующей причине.
"Раскладки" частот переключаются в синтезаторе частот ретранслятора Vertex-7000VXR, который, также как и любой синтезатор частот, является инерционным устройством.
То есть, переход с одной раскладки частот на другую, занимает некоторое время, и в это время возникают переходные помехи, наличие которых обусловлено переходными процессами в кольце фазовой автоподстройки частоты синтезатора частот.
137
Эти помехи могут "трансформироваться" в "паразитный" сигнал управления "несущая есть", что может привести к уходу в прерывания без фактического наличия несущей.
Для того чтобы избавиться от этой неприятности, нужно "переждать", пока не закончатся переходные процессы в кольце фазовой автоподстройки частоты синтезатора частот. Таким образом, речь идет о том, что после выбора направления ретрансляции (переключения "раскладок" частот), необходимо, на некоторое время, "закольцевать" рабочую точку программы в ПП задержки.
То есть, сначала нужно сформировать некий защитный интервал времени, а только после этого формировать "зону" разрешения прерываний.
В целях обеспечения приемлемой инерционности обнаружения несущей, "зона" разрешения прерываний также должна иметь некоторую протяженность во времени.
Следовательно, в этой "зоне" должна располагаться ПП задержки с калиброванным временем задержки.
Если в течение этого времени на выводе RB0/INT возникнет активный перепад (несущая есть), то процесс сканирования прекратится, так как рабочая точка программы "улетит" в ПП прерывания и будет "крутиться" там в "вечном кольце" до тех пор, пока не "пропадет" несущая.
Если это случится, то произойдет возврат из прерывания, и сканирование возобновится. Теперь можно составлять блок - схему программы:
И принципиальную схему устройства тоже можно составить. Определяемся с выводами портов.
138
Порт А не задействуем, порт В задействуем.
Входом внешнего прерывания INT является вывод RB0, следовательно, вывод RB0/INT необходимо настроить на работу "на вход".
Примечание: никакой другой вывод порта (любого) нельзя назначить входом внешнего прерывания INT, так как этот вид прерываний "жестко привязан" именно к выводу RB0. Так как управляющий сигнал "несущая есть/нет" поступает на вывод RB0/INT с выхода
каскада с открытым коллектором, то необходимо включить подтягивающие резисторы порта В.
В этом случае, подтягивающий резистор вывода RB0/INT будет являться коллекторной нагрузкой каскада с открытым коллектором.
Экспериментально проверяю состояние каскада с открытым коллектором: при отсутствии несущей транзистор закрыт, а при ее наличии, открыт, что с учетом подтягивающего резистора вывода RB0/INT, соответствует единичному уровню, если несущей нет, и нулевому уровню, если она есть.
Берем на заметку. При составлении программы, это потребуется.
Выходом управления переключением направлений ретрансляций (раскладки частот) можно назначить любой из оставшихся выводов порта В.
Пусть им будет, например, вывод RB2.
Этот вывод нужно настроить на работу "на выход".
Остальная часть принципиальной схемы практически такая же, как у устройства формирования тонального вызова с частотой 1450 Гц.
Пояснение: в ретрансляторе Vertex-7000VXR, для дистанционного переключения пар частот (одна частота - приемная, другая - передающая), на разъем выведено 4 цепи (переключение пар частот производится в инвертированном, весовом, параллельном коде).
Таким образом, можно осуществить переключения между 16-ю парами частот, но нам необходимо переключаться только между двумя парами частот, следовательно, под это дело, можно задействовать только один младший разряд (он и подключен к выводу RB2), а остальные 3 разряда запараллелить и "подать" на них единицу, то есть, подключить их к 4-му выводу PIC16F84A.
Вэтом случае, переключения будут производиться между 1-м и 2-м каналами (1-й и 2-й парами частот).
1-му каналу соответствует единица на выводе RB2, а 2-му каналу, ноль на выводе RB2.
Впринципиальной схеме, c целью упрощения ее восприятия, я не показал описанных выше соединений (но они должны быть).
Просто имейте это ввиду.
Принципиальную схему устройства вообще можно предельно упростить, если запитаться от цепи +5v ретранслятора.
139
Вэтом случае, стабилизатор на 142ЕН5 можно убрать, но придется "лезть" в ретранслятор и делать отвод от +5v.
А теперь можно прикинуть стоимость этого устройства (25-штырьковый разъем - компьютерный).
В250 руб. уложился (по ценам на комплектующие, которые имели место быть на момент
"ваяния этой железяки").
Файл текста программы под это устройство называется Retr_1.asm (находится в папке
"Тексты программ").
Программа выглядит так:
;********************************************************************************
; |
Retr_1.asm |
ВАРИАНТ С ПРЕРЫВАНИЯМИ |
; |
Сканер для ретранслятора VERTEX-7000VXR. |
; |
Автор: Корабельников Евгений Александрович г.Липецк декабрь 2004г. |
|
; |
E-mail: karabea@lipetsk.ru |
http://ikarab.narod.ru |
;********************************************************************************
;Позволяет перевести VERTEX-7000VXR и другие подобные ретрансляторы из режима
;односторонней ретрансляции в режим двухсторонней ретрансляции без потери
;качества работы.
;********************************************************************************
;Используется микроконтроллер 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 |
; Переключатель направления ретрансляции. |
W_Temp |
equ |
0Eh |
; Регистр сохранения содержимого W в |
; прерываниях. |
|||
Stat_Temp |
equ |
0Fh |
; Регистр сохранения содержимого STATUS в |
; прерываниях. |
|||
SecH |
equ |
1Eh |
; Старший байт счетчика времени сканирования. |
SecL |
equ |
1Fh |
; Младший байт счетчика времени сканирования. |
SecH_1 |
equ |
1Ch |
; Старший байт счетчика защитного интервала |
; времени. |
|||
SecL_1 |
equ |
1Dh |
; Младший байт счетчика защитного интервала |
; времени. |
|||
SecH_2 |
equ |
1Ah |
; Старший байт счетчика задержки рабочей точки |
; программы в прерывании. |
|||
SecL_2 |
equ |
1Bh |
; Младший байт счетчика задержки рабочей точки |
; программы в прерывании. |
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W |
equ |
0 |
; |
Результат |
направить |
в |
аккумулятор. |
F |
equ |
1 |
; |
Результат |
направить |
в |
регистр. |
;================================================================================
; Определение положения флагов и бита выбора банка в регистре STATUS.
;================================================================================
RP0 equ 5 ; Бит выбора банка.
;================================================================================
; Точка входа в программу.
;================================================================================
140
org |
0 |
; |
Начать |
выполнение программы с нулевого |
goto |
START |
; |
адреса |
PC. |
;================================================================================
; Точка входа в прерывание.
;================================================================================ org 4 ; Назначение вектора прерывания (назначается,
; если в программе используются прерывания).
;================================================================================ ; Объем программы: 63 слова в памяти программ.
;********************************************************************************
;******************************************************************************** ; НАЧАЛО ПРЕРЫВАНИЯ.
;================================================================================
; Сохранение |
содержимого регистров STATUS и W в ОЗУ. |
||
;-------------------------------------------------------------------------------- |
|||
INT |
movwf |
W_Temp |
; Скопировать содержимое регистра W |
; в регистр W_Temp. |
|||
movf |
Status,W |
; Скопировать содержимое регистра Status |
|
; в регистр W. |
|||
movwf |
Stat_Temp |
; Скопировать содержимое регистра W |
|
; в регистр Stat_Temp. |
|||
;-------------------------------------------------------------------------------- |
|||
; Проверка наличия несущей (опрос клавиатуры). |
|||
;-------------------------------------------------------------------------------- |
|||
CYCLE |
btfsc |
PortB,0 |
; Проверка состояния нулевого бита |
; регистра PortB. |
|||
goto |
EndInt |
; Если он =1 (несущей нет), то уход |
|
; в ПП выхода из прерывания. |
|||
; Если он =0 (несущая есть), то программа |
|||
; исполняется далее. |
|||
;-------------------------------------------------------------------------------- |
|||
; Формирование времени |
одного цикла задержки рабочей точки программы в прерывании |
|||
;-------------------------------------------------------------------------------- |
||||
movlw |
.250 |
; Закладка константы .250 в |
регистр W. |
|
movwf |
SecH_2 |
; Копирование .250 из регистра W |
||
; в регистр SecH_2. |
||||
movlw |
.120 |
; Закладка константы .120 в |
регистр W. |
|
movwf |
SecL_2 |
; Копирование .120 из регистра W |
||
; в регистр SecL_2. |
||||
PAUSE_2 |
clrwdt |
; Сброс WDT. |
||
decfsz |
SecL_2,F |
; Декремент содержимого младшего разряда |
||
; счетчика SecL_2. |
||||
goto |
PAUSE_2 |
; Если результат декремента |
не =0, то переход |
|
; в ПП PAUSE_2. |
||||
incfsz |
SecH_2,F |
; Если результат декремента |
=0, то инкремент |
|
; старшего разряда счетчика |
SecH_2. |
|||
goto |
PAUSE_2 |
; Если результат инкремента |
не=0, то переход |
|
; в ПП PAUSE_2. |
||||
goto |
CYCLE |
; Если результат инкремента |
=0, то переход на |
|
; следующий цикл задержки рабочей точки |
||||
; программы в прерывании. |
||||
;================================================================================
;Восстановление содержимого регистров STATUS и W с последующим выходом
;из прерывания.
;-------------------------------------------------------------------------------- |
|||
EndInt |
bcf |
IntCon,1 |
; Сброс флага прерывания по INT. |
movf |
Stat_Temp,W ; Скопировать содержимое регистра Stat_Temp |
||
; в регистр W. |
|||
movwf |
Status |
; Скопировать содержимое регистра W |
|
; в регистр Status. |
|||
swapf |
W_Temp,F |
; Поменять местами старший и младший полубайты |
|
; регистра W_Temp с сохранением результата |
|||
; операции в нем же. |
|||
swapf |
W_Temp,W |
; Поменять местами старший и младший полубайты |
|
; регистра W_Temp с сохранением результата |
|||
141