Файл: Самоучитель по программированию 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