Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PIC микроконтроллеры.docx
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
22 Мб
Скачать
☆

Метод вложенных циклов

Этот метод подходит в тех случаях, когда необходимы достаточно большие задержки. Для их реализации используется ВНЕШНИЙ цикл, в теле которого будет выполняться ВНУТРЕННИЙ цикл, формирующий задержку 1 мс. Если повторить его 100 раз, то получим задержку 100 мс

DELAY

MOVLW .Y ; загрузка счетчика 1

MOVWF COUNT1 ; внешнего цикла

BETA

MOVLW .X ; загрузка счетчика 0

MOVWF COUNT0 ; внутреннего цикла

ALFA

NOP ; 1 mkc

DECFSZ COUNT0,f ; декремент COUNT0 и внутренний

GOTO ALFA ; цикл, если COUNT0 не 0

DECFSZ COUNT0,f ; декремент COUNT1 и внешний

GOTO BETA ; цикл, если COUNT1 не 0

RETURN ; возврат

Рис. 9.5. Программа задержки метод (вложенных циклов)

Алгоритм программной реализации задержки представлен на Рис. 9.5. Там же показано время выполнения каждого фрагмента программы в мкс.

Работа подпрограммы складывается из :

  1. COUNT0: 1(MOVLW_0)+1(MOVWF_0)+[1(NOP)+1(DECFSZ_0)+2(GOTO_0)]X–1

1+1+4X-1

1+4X

  1. COUNT1: 1(MOVLW_0)+1(MOVWF_0)+(1+4X)Y+[1(DECFSZ_1)+2(GOTO_1)]Y–1

1+1+(1+4X)Y+3Y–1

1+(1+4X)Y+3Y

  1. 2(CALL)+1(MOVLW_1)+1(MOVWF_1)+ 1+(1+4X)Y+3Y+1(RETURN

Суммарное время машинных циклов в подпрограмме:

Т = 2+1+1+1+ (1+4Х)Y +3Y+ 1

T=6 +(1+4Х)Y+3Y

DELAY

Загрузка Y в COUNT1

2

нет

Загрузка X в COUNT0

нет

COUNT0=0?

X Y

COUNT0=1?

RETURN

1

Рис. 9.6. Алгоритм работы 2-х разрядного вычитающего счетчика

Временная задержка длительностью 1с.

Секунда является очень большим интервалом по сравнению с частотой тактового генератора (4 МГц). Такие задержки сложно реализовать методом вложенных циклов. Поэтому их набирают из точно подстроенных задержек меньшей длительности. Например. задержку в 1с можно реализовать десятикратным вызовом подпрограммы, реализующей задержку 100 мкс.

ONESEC

MOVLW D’10’ ; число вызовов

MOWWF COUNT ; подпрограммы DELAY_100

LOOP

CALL DELAY_100 ; задержка 100 мкс

DECFSZ COUNT,f ; декремент COUNT и цикл,

GOTO LOOP ; если не равно 0

Параметризируемые подпрограммы

Для успешной работы любой подпрограммы необходимо однозначно определить способ передачи в нее исходных данных и способ вывода результата ее работы. Подпрограмма, которой требуется дополнительная информация в виде параметров ее настройки или операндов, называется параметризируемой. Передача параметров в подпрограмму задержки может осуществляется через регистры общего назначения. При передаче входных параметров основная программа обязательно содержит команды загрузки этих регистров, а подпрограмма - команды считывания из этих регистров.

Примером параметризируемой подпрограммы служит подпрограмма задержки Рис. 9.6. Основная программа обеспечивает передачу в подпрограмму загрузку счетчика (MOVLW D’20’), обеспечивая требуемое время задержки. Подпрограмма задержки Рис. 9.6. не возвращает никаких значений в вызывающую программу.

;************************************************

Delay_1ms Подпрограмма формирования задержки 1 мс

;************************************************

COUNT EQU H’20’ ; счетчик цикла

GOTO START ;

;--------------------------------------------------------------------------

;Подпрограмма задержки

;--------------------------------------------------------------------------

DELAY_1ms

MOVWF COUNT ; счетчика цикла

LOOP

NOP ; пустая команда

DECFSZ COUNT,f ; ЕСЛИ содержимое счетчика не0

GOTO LOOP ;ТО цикл

RETURN ;

;---------------------------------------------------------------------------

Основная программа

;----------------------------------------------------------------------------

START

MOVLW D’249’ ; число повторов

CALL DELAY_1ms ; задержка 1 мс

……. …….. ;

Рис. 9.6. Подпрограмма формирования задержки 1 мс

Подпрограмма SVN_SEG при передаче входных параметров загружает рабочий регистр W, а основная программа при выходе считывает его содержимое. Подпрограмма Рис. 9.9. демонстрирует загрузку однобайтного значения в рабочий регистр и используется совместно с семисегментным индикатором.

Системное представление подпрограммы приведено на Рис. 9.7,а. Входным сигналом является 4-х битный двоичный код, находящийся в рабочем регистре: от b’0000’ до b’1001’. Выходным значением, также возвращаемым в рабочий регистр, является соответствующий семисегментный код, необходимый для отображения соответствующей цифры (см. Табл. преобразования).

Рис. 9.7. Семисегментный индикатор

Таблица преобразования 7-сегментного кода приведена на Рис. 9.8. При использовании такой таблицы извлечение k-го элемента таблицы заключается в исполнении N-й команды. При этом константа, находящаяся в команде, будет помещена в W регистр , после чего произойдет возврат в вызывающую программу. В примере k=6, поэтому выполняется 6-я команда RETLW, возвращающая код b’011111000’для символа 6.

Рис. 9.8. Таблица преобразования

Подпрограмма, приведенная ниже, осуществляет выборку элемента таблицы, прибавляя число N, передаваемое через рабочий регистр, к байту счетчика РСL. Поскольку РС уже указывает на 1-ю команду RETLW,то после прибавления N он будет указывать на N-ю команду, что нам и требуется.

SVN_SEG

ADDWF PCL,f ; прибавляем PCL+W получая PC+N

хgfedcba

RETLW b’00111111’ ; цифра 0, возвращается при N=0

RETLW b’00000110’ ; цифра 1, возвращается при N=1

RETLW b’01011011’ ; цифра 2, возвращается при N=2

RETLW b’01001111’ ; цифра 3, возвращается при N=3

RETLW b’01100110’ ; цифра 4, возвращается при N=4

RETLW b’01101101’ ; цифра 5, возвращается при N=5

RETLW b’01111101’ ; цифра 6, возвращается при N=6

RETLW b’00111111’ ; цифра 7, возвращается при N=7

RETLW b’00111111’ ; цифра 8, возвращается при N=8

RETLW b’00111111’ ; цифра 9, возвращается при N=9

Рис. 9.9. Подпрограмма преобразования двоичного кода в семисегментный

Пример: формирование импульсов прямоугольной формы

Программа должна сформировать импульсы прямоугольной формы частотой 5 КГц на одном из выводов (нулевом) порта В. Инициализация PORTВ выполняется аналогично программе SMOTOR-2 рис.4.7.

Далее следует формирование импульса (высокого уровня) на выводе RB0. Применяется бит - ориентированная команда BSF в которой указывается нулевой бит регистра PORTB, который нужно установить: BSF PORTB,0.

Теперь наша задача сделать так, чтобы с момента установки и до момента сброса вывода RB0 прошло ровно Т/2=1/2F=1/2х5х103 Гц = 100мкс.

;****************************************************

; MULTI - Формирование звукового сигнала

;****************************************************

; пьезоизлучатель подключен к RB0-------------------

; Определение рабочего регистра--------------------

COUNT EQU 0CH ; Счетчик времени полупериода.

GOTO START ; Переход на начало программы.

;------------------------------------------------------------------

;Подпрограмма задержки------------------------------

;------------------------------------------------------------------

DELAY

MOVWF COUNT ; копировать из W в регистр Cnt0

PAUZE

DECFSZ COUNT,f; Декремент содержимого регистра Cnt0

GOTO PAUZE ; и цикл пока CNT0 не = 0

RETURN ; CNT0 = 0, вернуться в основную программу

;------------------------------------------------------------------

; Основная программа-----------------------------------

; -----------------------------------------------------------------

START

BSF STATUS,RP0 ; Перейти на 1 page .

MOVLW B'00000000'; Записать константу 0 в аккумулятор (W).

MOVWF TRISB ; Скопировать 0 из W в регистр TrisB.

BCF STATUS,5 ; Вернуться на 0 page

; Формирование импульса на выводе RB0------------------

S_LOOP

BSF PORTB,0 ; Установить RB0

MOVLW .32 ; Записать в регистр W константу .32

CALL DELAY

; Формирование паузы на выводе RB0 ---------------------

BCF PORTB,0 ; Сбросить RB0.

MOVLW .32 ; Записать в регистр W константу .32

CALL DELAY

GOTO S_LOOP ; Переход на новый цикл программы.

; Директива конца программы -----------------------------

END

ОРГАНИЗАЦИЯ ПРОГРАММ

Ниже даны основные рекомендации для написания ассемблерных программ:

  1. Четко представляйте себе задачу, которую должна решить программа.

  2. Сделайте эскиз задачи в общих чертах и спланируйте общую логику программы. Затем спланируйте общую стратегию для инициализации, условного перехода и команды DECFSZ

Приведем основную логику, которую используют многие программисты в таком случае:

инициализация портов и периферийных устройств

вызов подпрограммы цикла

возврат

Подпрограмма цикла может быть спланирована следующим образом:

инициализация регистров значениями адресов

и числа циклов

Метка: пересылка одного байта

увеличение адресов на 1

уменьшение счетчика на 1:

если счетчик не ноль, то идти на метку

если ноль, возврат

  1. Представьте программу в виде логических блоков, следующих друг за другом. Процедуры, не превышающие 25 строк (размер экрана) удобнее для отладки.

  2. Пользуйтесь тестовыми примерами программ. Попытки запомнить все технические детали и программирование сложных программ "из головы" часто приводят к многочисленным ошибкам.

  3. Используйте комментарии для описания того, что должна делать процедура, какие арифметические действия или операции сравнения будут выполняться и что делают редко используемые команды. (Например, команда NOP, не имеющая операндов).

  4. Для кодирования программы используйте заготовку программы, скопированной в файл с новым именем.

ОРГАНИЗАЦИЯ ПРЕРЫВАНИЙ

Ранее рассмотренные подпрограммы можно назвать «предсказуемыми» событиями, поскольку они вызываются в соответствии с логикой программы. Ситуации реального времени далеко не так просты. Очень часто вне ядра ЦП происходят события, требующие немедленной реакции процессора.

Контроллеры способны реагировать на самые разнообразные события такого рода, нарушающие их нормальное функционирование. Они могут исходить как от встроенных периферийных устройств, так и от источника, совершенно не связанного с микроконтроллером. В качестве реакции микроконтроллер должен перейти к специальной подпрограмме, называемой подпрограммой обработки прерываний или обработчиком прерываний.

Микроконтроллер PIC 1684 поддерживает 4 типа различных прерываний от периферийных устройств, в том числе и внешнее прерывание. Несмотря на различные набор периферийных устройств (ЦАП, АЦП, таймеры, последовательный порт), все они реагируют на прерывания одинаково. Этими основными источниками являются:

  • Внешний сигнал, подаваемый на вход INT. Это внешнее прерывание может генерироваться либо по нарастающему , либо по спадающему фронту входного сигнала, что определяется состоянием бита INTEDG регистра OPTION_REG (соответственно бит 1 и бит 0).

  • Изменением состояния любого из старших четырех разрядов порта В.

  • Переполнение счетного регистра таймера/счетчика TMR0 с H’FF’ → H’00’

Программист может запретить или разрешить прерывания от этих источников, а также полностью запретить работу всей системы в целом. Pеакция на прерывание в микроконтроллерах среднего уровня (PIC 1684) показана на Рис. 10.1

Рис. 10.1. Отклик на запрос прерывания

Отклик процессора на запрос прерывания будет выглядит следующим образом:

  1. Завершить выполнение текущей команды.

  2. Автоматически сохранить состояние программного счетчика РС (для возврата из подпрограммы прерываний) и содержимое регистра STATUS.

  3. Перейти к соответствующей процедуре обработки прерываний.

  4. Выполнить требуемые действия.

  5. Восстановить состояние процессора и вернуться к тому месту основной программы, в котором произошло прерывание.

Вход внешнего прерывания использует ту же ножку микроконтроллера, к которой подключена 0-я линия порта В - вывод RB0. Поскольку процесс реакции на прерывание не зависит от его источника, начнем рассматривать внешнее прерывание.

Рис. 10.2. Формат регистра прерываний INTCON

Разрешение/запрещение и распознавание прерываний в PIC16F84A производится через регистр INTCON (Рис. 10.2.). С каждым из четырех источников прерываний связан соответствующий бит флага прерывания.

Чтобы разрешить прерывания по входу INT, придется установить биты 7 и 4 регистра INTCON, т.е. выполнить команды

BSF INTCON,GIE ; разрешение всех прерываний

BSF INTCON,INTE; и по входуRB0/INT

При наличии разрешения

а) запрещается вся система прерываний (чтобы обработать текущее). Это осуществляется сбросом 7-го бита регистра INTCON (GIE);

б) состояние 13-битного программного счетчика РС заносится в стек;

в) первая команда обработчика прерываний всегда начинается по адресу Н’04’, называемому вектором прерывания;

г) процедура обработки прерывания должна завершиться командой возврата. Однако при завершении прерывания необходимо не только извлечь из стека сохраненное значение РС, но и установить бит GIE регистра INTCON для разрешения последующих прерываний. Для этого используется команда RETFIE;

д) при обработке прерывания жизненно важно сбросить флаг прерывания в процедуре обработки прерывания перед выходом из обработчика, т.е. выполнить команду BCF INTCON,INTF.

Каждый флаг прерывания имеет соответствующий бит разрешения прерывания. Так, флагу INTF соответствует бит INTЕ.

Пример1: Программа подсчета числа посетителей

При пересечении луча лазера покупателем на вход микроконтроллера поступает сигнал запроса в виде прямоугольного импульса. В этот момент микроконтроллер занят выполнение своей основной задачи, например, организацией обмена данными между торговым терминалом и основным компьютером склада.

Рис. 10.3. Контроль числа посетителей магазина

При каждом проходе посетителей инкрементируется регистр COUNT. Проход разделим на два, чтобы получить реальное количество посетителей. Максимальное число посетителей, регистрируемое нашей системой, составит 255. Указанное ограничение можно преодолеть, задействовав дополнительные регистры.

В начале программы размещена команда GOTO START. По адресу 04Н, называемому вектором прерывания. Размещена подпрограмма обработчика прерывания.

В основной программе просто устанавливают биты INTE и GIE для разрешения внешних прерываний, а также обнуляется счетчик COUNT. Расположенный далее бесконечный цикл представляет собой фоновые задачи процессора.

С точки зрения программы прерывания могут возникать произвольно при выполнении любого участка основной программы.

;****************************************

; COUNT - Подсчет числа посетителей

;****************************************

; регистры хранения состояния W и STATUS

_WORK EQU H‘4F’;ячейка для сохранения регистра w

_STATUS EQU H‘4E’;ячейка для сохранения регистра STATUS

COUNT EQU H'10'; счетчик общего числа посетителей

GOTO START

;--------------------------------------------------

; Подпрограмма прерываний

;--------------------------------------------------

;вектор прерывания--------------

ORG 04H

; Сохранение контекста---------------------------

MOVWF _WORK ; сохранение W в памяти данных

SWAPF STATUS,W ; считываем status

MOVWF _STATUS ; сохраняем его в памяти данных

; Основной код--------------------------------------

INCF COUNT ; инкремент счетчика посетителей

BCF INTCON,INTF ; сброс флага прерываний

; Восстановление контекста---------------------

SWAPF _STATUS,w ; восстановление

MOVWF STATUS ; значений status

SWAPF _WORK,f ; и исходное

SWAPF _WORK,w ; состояние w

RETFIE ; выход из прерывания

;--------------------------------------------

; Основная программа

;--------------------------------------------

START

BSF STATUS,RP0 ; page 1

MOVLW b'00000001' ;настроить RB0

MOVWF TRISB ;на вход

MOVLW B'00000000' ; нагрузки к PORTB подключены

MOVWF OPTION_REG ; прерывание по спадающему

; фронту на ножке INT

BCF STATUS,RP0 ; page 0

BSF INTCON,GIE ; разрешение всех прерываний

BSF INTCON,INTE ; разрешение по ножке RB0/INT

CLRF COUNT,f ;обнуляем счетчик посетителей

; Бесконечный цикл основной программы--------------------------

S_LOOP NOP ; выполняем то

NOP ; выполняем это

GOTO S_LOOP

; ------------------------------------------------------------------------------------------------

END ; конец всем командам

Обработчик прерываний в своей программе может использовать регистры и , если перед исполнением подпрограммы обработки прерываний их содержимое не сохранить, то это может привести к непредсказуемым последствиям. Для работы в качестве временного хранилища используют регистры данных, которые больше ни для чего не используются.

Любую процедуру обработки данных условно можно разделить на три части:

  1. Сохранение контекста

Сначала копия рабочего регистра сохраняется в регистре_work. Затем регистр STATUS сохраняется в регистре данных _STATUS (4Fh).Команда SWAPF не изменяет значение флагов, однако меняет местами тетрады байта. Их нормальное положение восстанавливается при восстановлении регистра.

  1. Основной код

Сбрасывается флаг прерывания INTF, чтобы избежать повторного перехода к обработке прерыванияпосле возврата в основную программу. В рабочей секции основного кода просто инкрементируется содержимое регистра COUNT. Это основная задача процедуры обработки прерывания.

  1. Восстановление контекста.

При завершении обработки в рабочий регистр с помощью команды SWAPF заносится содержимое регистра STATUS, которое затем копируется оттуда в STATUS.

Исходное значение W восстанавливается из временной переменной _WORK с использованием двух последовательных команд SWAPF. При этом значение регистра STATUS не изменяется.

И наконец выполняется команда RETFIE.

Пример2:Программа ELECTRONIC_DICE –электронная игральная кость

Программа реализует электронный аналог игральной кости с шестью светодиодами, подключенными с старшим разрядам порта В, как показано на Рис. 10.4. Основная программа будет инкрементировать переменную с максимально возможной скоростью и сбрасывает ее в ноль, когда она становится больше пяти. При нажатии на кнопку, подключенной ко входу , программа будет переходить к обработчику прерывания. Процедура обработки прерывания отобразит одну из шести комбинаций светодиодов.

Рис. 10.4. Коды управления светодиодами электронной игральной кости

;******************************************************

;ELECTRONIC_DICE - Электронная игральная кость

;******************************************************

THROW EQU H'10' ; переменная

GOTO START ; к основной программе

;-----------------------------------------

;Подпрограммы

;-----------------------------------------

;Обработчик прерывания-----------------

ORG 4 ;вектор прерывания

CLRF PORTB ;выключить светодиоды

CALL SVN_SEG ; перекодировка

MOVWF PORTB ; включить светодиоды

BCF INTCON,INTF ; сбросить флаг прерывания

RETFIE ;выход

;перекодировка----------------------------

SVN_SEG

ADDWF PCL,f ; прибавляем PLC+W получая PC+N

RETLW B'01000000' ; сегмент g, возвращается при N=0

RETLW B'00001001' ; сегменты a, d возвращаются при N=1

RETLW B'00101001' ; сегменты a, d, g возвращаются при N=2

RETLW B'00011011' ; сегменты a, b, d, e возвращаются при N=3

RETLW B'01011011' ; сегменты a, b, d. e, g возвращаются при N=4

RETLW B'101111111 ' сегменты a, b, c, d, e, f возвращаются при N=5

;===============================

;Основная программа

;===============================

START

BSF STATUS,5 ; page 1

movlw b'00000001' ; настройка RB0-вход

mOVWF TRISB ;остальные- выход

BSF INTCON,GIE ; разрешение всех прерываний

BSF INTCON,INT ; разрешение внешнего прерывания

clrf option_reg ; 7бит-подтягивающие резисторы вкл, 6бит-срабатывание по срезу

BCF STATUS,5 ; page 0

LOOP

INCF THROW,W ; инкремент регистра THROW

MOVWF H'20' ; сохранить в буфере

SUBLW D'6' ; сравниваем с числом 6

BTFSC STATUS,Z ; ЕСЛИ , THROW=6

GOTO B10 ; ТО перейти к В10

MOVFW H'20' ; ИНАЧЕ вернуть из буфера в W

MOVWF THROW ; копировать в регистр THROW

GOTO LOOP ; цикл

B10

CLRF THROW ; сбросить THROW

GOTO LOOP ; цикл

;-------------------------------------------------------------

END

Основная программа инкрементирует переменную THROW сбрасывает ее в ноль, когда она становится больше пяти. Таким образом, реализуется программный счетчик по модулю шесть, т.е. 0, 1, 2, 3, 4, 5, 0,..

Компилятор PIC Simulator IDE генерирует основную программу. Состоящую из десяти команд, включая команду безусловного перехода и сброса переменной. В результате при тактовой частоте 4 МГц инкрементирование переменной происходит 10 000 раз в секунду. Такая частота обеспечит практически случайный выбор одного из шести значений по нажатию кнопки, подключенной к выводу RB0/INT.

ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ

- Прерывание - это своеобразный переход, в большинстве случаев, по внешнему воздействию, из основной программы, на выполнение подпрограммы прерывания, с последующим из нее возвратом в основную программу.

- По наступлению события прерывания нормальное выполнение программы будет остановлено и программа перейдет на адрес ПЗУ 0x004, который называется вектором прерывания. По этому адресу и должна находиться подпрограмма отработки прерывания. При этом адрес возврата сохраняется в стеке.

У PIC – контроллеров вектор прерывания один для всех источников, поэтому данная подпрограмма должна сама различать события, вызвавшие прерывание, если разрешено более одного прерывания. Определение источника прерывания производится путем опроса соответствующих флагов прерывания, которые устанавливаются по наступлению прерывания. По прерыванию по входу RB0 – флаг INTF (INTCON,1), а по входу RB4 - RB7 – RBIF (INTCON,0).

Главное преимущество работы со всеми типами прерываний - малая инерционность отклика устройства на внешний управляющий сигнал прерывания (активный перепад), что может быть очень полезным в тех конструкторских разработках, к которым предъявляются жесткие требования по инерционности (скорости) срабатывания исполнительных устройств.

- Метки для команд условного перехода и DECFSZ должны лежать в границах 0 до 256 байт.

- При использовании команды DECFSZ, инициализируйте регистр CNT положительным числом. Команда DECFSZ контролирует только нулевое значение, при отрицательном программа будет продолжать циклиться.

- Если некоторая команда устанавливает флаг, то данный флаг сохраняет это значение, пока другая команда его не изменит. Например, если за арифметической командой, которая устанавливает флаги, следуют команды MOV, то они не изменят флаги. Однако, для минимизации числа возможных ошибок, следует кодировать команды условного перехода непосредственно после команд, устанавливающих проверяемые флаги.

- Команда вызова процедуры CALL работает совместно с командой RETURN. При этом при исполнении команды CАLL В10 МК выполняет два действия:

  • в программный счетчик РС заносится адрес процедуры В10 и исполнение программы продолжается по указанному адресу;

  • в стек STACK заносится адрес возврата в основную программу – адрес следующей за CАLL В10 команды.

  • вызываемая процедура может, в свою очередь, вызвать другую процедуру, и если следовать существующим соглашениям, то команда RETURN всегда будет выбирать из стека правильный адрес возврата

По команде RETURN содержимое стека загружается в программный счетчик РС и работа основной программы продолжается.

- Используйте команды сдвига для удваивания значений и для деления пополам.

ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ

1.Каким образом может программа начать выполнение процедуры?

2.В программе процедура A10 вызывает B10, B10 вызывает C10, а C10 вызывает D10. Сколько адресов возврата содержит стек?

3.Напишите программу формирования 10-ти периодов звукового сигнала частотой 1 кГц.

4.Напишите программу формирования двухтонального звукового сигнала: импульсы частотой 5кГц и скважностью два заполнены частотой 500 Гц.

INT_RB4_7 : Прерывания от изменения уровня на ножках порта RB<7:4>.

Прерывания от изменения уровня на ножках порта RB4...RB7 являются одной из разновидностей прерываний. В отличие от прерываний по выводу INT, где нужно предварительно определить активные фронты прерываний (бит INTEDG регистра Option), для прерываний по изменению уровней сигналов на выводах RB4...RB7, этого делать не требуется, так как уход в эти прерывания происходит и при смене 0 на 1, и при смене 1 на 0 на любом из выводов RB4...RB7.

Если сравнить прерывания по выводу INT и прерывания от изменения сигналов на любом из выводов RB4...RB7, то, за исключением указанного выше и того, что перед выходом из прерывания нужно сбросить другой флаг (RBIF), их механизм одинаков. Так что, если речь идет только об одном внешнем устройстве, которое является источником прерываний, и нужно уйти в прерывания не по какому-то конкретному перепаду, а по любому перепаду внешнего управления, то это внешнее устройство можно подключить к любому из 4-х выводов RB4...RB7.

Естественно, при задействовании под прерывания выводов RB4...RB7, они должны быть предварительно настроены на вход. Вопрос о подключении или отключении подтягивающих резисторов решается в каждом конкретном случае (зависит от схемотехники внешнего источника прерываний).

К четырем выводам RB4...RB7 можно подключить четыре источника прерываний и получить 16 комбинаций (24) подпрограмм прерываний, причем, как бы "нейтральной" комбинацией является только 0000, а переход от нее к любой из оставшихся 15 комбинаций связан со срабатыванием одного или нескольких источников прерываний.

К этим 15-ти сценариям можно "привязать" до 15-ти отдельных внешних исполнительных устройств (если выводов портов для этого достаточно) или меньшее количество внешних исполнительных устройств, но работающих в комплексе и обеспечивающих до 15 комбинаций их срабатываний.

Для "слабосильных" PICов типа PIC16F84A, последний вариант наиболее приемлем (просто деваться некуда, так как выводов его портов для 1-го варианта не достаточно).

После ухода в прерывание, "привязка" к конкретным сценариям осуществляется в подпрограмме прерывания. Для этого организуется многосценарный вычисляемый табличный переход с тем количеством сценариев, которое нужно. Естественно, перед его осуществлением, необходимо составить соответствующее количество исполнительных подпрограмм и адресно привязать все сценарии к соответствующим комбинациям 4-х источников прерывания.

;*************************************************************************

; INT_RB4_7 Прерывания от изменения сигналов на ножках порта RB<7:4>.

;**************************************************************************

; Функции выводов:

; RB4...RB7 – входы, RB4 - младший разряд, RB7 - старший разряд

; RB0...RB3 - выходы, подключается светодиодная панель.

; (RB0 - младший разряд, RB3 - старший разряд).

; - RA0 выход, подключается осциллограф.

; Определение регистров общего назначения--------------------

W_TEMP EQU 0EH ; Регистр хранения содержимого W.

STAT_TEMP EQU 0FH ; Регистр хранения содержимого STATUS.

CNT0 EQU 1CH ; Регистр периода.

CNT_0 EQU 1DH ; Регистр повторов периода.

GOTO START ;

; Подпрограмма прерывания-----------------------------------------

ORG 4 ; Назначение вектора прерывания.

; Сохранение содержимого регистров STATUS и W----------

MOVWF W_TEMP ; Копирование W в регистр W_TEMP.

SWAPF STATUS,W ; Смена полубайтов регистра STATUS

MOVWF STAT_TEMP ; Копирование W в регистр STAT_TEMP.

; Переход в 0-й банк --------------------------------------------------

BCF STATUS,RP0 ; Установка 0-го банка.

; Опрос порта В и перестановка полубайтов--------------------

MOVF PORTB,W ; Опрос состояния порта B.

ANDLW B'11110000' ; Блокировка младшего полубайта.

MOVWF CNT0 ; Смена местами полубайтов с

SWAPF CNT0,W ; сохранением результата в W.

; Табличный вычисляемый переход-------------------------------

ADDWF PCL,F ; Сам переход.

GOTO EXIT ; "Пустышка" - обход всех "рабочих" сценариев.

GOTO S_0001 ; Сценарий №1.

GOTO S_0010 ; ---"--- №2.

GOTO S_0011 ; ---"--- №3.

GOTO S_0100 ; ---"--- №4.

GOTO S_0101 ; ---"--- №5.

GOTO S_0110 ; ---"--- №6.

GOTO S_0111 ; ---"--- №7.

GOTO S_1000 ; ---"--- №8.

GOTO S_1001 ; ---"--- №9.

GOTO S_1010 ; ---"--- №10.

GOTO S_1011 ; ---"--- №11.

GOTO S_1100 ; ---"--- №12.

GOTO S_1101 ; ---"--- №13.

GOTO S_1110 ; ---"--- №14.

GOTO S_1111 ; ---"--- №15.

; ППсценария №1--------------------------

S_0001 MOVLW 01H ; Записьчисла 00000001

MOVWF PORTB ; вPortB.

GOTO EXIT ; ВыходизППпрерывания

; ПП сценария №2----------------------------

S_0010 MOVLW 02H ; То же самое для

MOVWF PORTB ; числа 00000010.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №3---------------------------

S_0011 MOVLW 03H ; То же самое для

MOVWF PORTB ; числа 00000011.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №4--------------------------

S_0100 MOVLW 04H ; То же самое для

MOVWF PORTB ; числа 00000100.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №5----------------------------

S_0101 MOVLW 05H ; То же самое для

MOVWF PORTB ; числа 00000101.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №6----------------------------

S_0110 MOVLW 06H ; То же самое для

MOVWF PORTB ; числа 00000110.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №7---------------------------

S_0111 MOVLW 07H ; То же самое для

MOVWF PORTB ; числа 00000111.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №8--------------------------

S_1000 MOVLW 08H ; То же самое для

MOVWF PORTB ; числа 00001000.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №9--------------------------

S_1001 MOVLW 09H ; То же самое для

MOVWF PORTB ; числа 00001001.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №10--------------------------

S_1010 MOVLW 0AH ; То же самое для

MOVWF PORTB ; числа 00001010.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №11--------------------------

S_1011 MOVLW 0BH ; То же самое для

MOVWF PORTB ; числа 00001011.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №12--------------------------

S_1100 MOVLW 0CH ; То же самое для

MOVWF PORTB ; числа 00001100.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №13--------------------------

S_1101 MOVLW 0DH ; То же самое для

MOVWF PORTB ; числа 00001101.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №14---------------------------

S_1110 MOVLW 0EH ; То же самое для

MOVWF PORTB ; числа 00001110.

GOTO EXIT ; Выход из ПП прерывания

; ПП сценария №15----------------------------

S_1111 MOVLW 0FH ; То же самое для

MOVWF PORTB ; числа 00001111.

; Процедура выхода из прерывания-------

EXIT

BCF INTCON,RBIF ; Сброс флага прерывания по изменению уровней

; сигналов на входах RB4...7.

; Восстановление содержимого регистров Status и W------------

SWAPF STAT_TEMP,W ; Обменп/байтами. Результат сохраняется в W.

MOVWF STATUS ; Копирование содержимого W в регистр Status.

SWAPF W_TEMP,F ; Обмен п/байтами.

SWAPFW_TEMP,W ; Обмен п/байтами. Результат сохраняется в W.

RETFIE ; Возврат из прерывания.

; Oсновная программa----------------------------------------

;--------------------------------------------------------------------

START

MOVLW B'10001000' ; Разрешены прерывания по изменению

MOVWF INTCON ; уровней на выводах RB4...7.

BSF STATUS,RP0 ; Установка 1-го банка.

BSF OPTION_REG,7 ; Подтягивающие резисторы отключены.

MOVLW B'11110000' ; RB4...7 работают на вход,

MOVWF TRISB ; RB0...3 работают на выход.

CLRF TRISA ; Все выводы порта А работают на выход.

BCF STATUS,RP0 ; Установка 0-го банка.

GOTO START ; Переход на начало START.

; Конец текста программы----------------------------------

END

Рис. 11.4. Прерывания от изменения уровня на ножках порта RB<7:4>

Программа INTRB4_7 отображает номер комбинации источников прерывания в двоичном коде с помощью светодиодов, подключенных к выводам порта В (RB0...RB3). Всего комбинаций 15. "Нейтральная" комбинация 0000 соответствует "пустышке" (все светодиоды погашены и ничего не происходит).

Формирование исходных данных для работы процедуры вычисляемого перехода происходит при считатывании состояния выводов RB4...RB7 порта В и его копирования в регистр W. Перед копированием блокируется младший полубайт (ANDLW B'11110000') и полубайты меняются местами SWAPF. Теперь младший полубайт несет информацию о номере комбинации источников прерывания, что и используется для организации вычисляемого перехода, а в старший будет выводиться двоичный код любой из 15-ти комбинаций.

Для того чтобы его сменить, нужно установить новую комбинацию источников прерывания ит.д.

Можно ввел в программу "ограничитель высвечивания": в простейшем случае, это подпрограмма задержки, посложнее – программа звукового генератора с ограниченным временем работы.

Звуковой сигнал будет указывать о нахождении программы в подпрограмме прерывания.. при любой комбинации источников прерывания он будет оповещать о времени исполнения текущего сценария, а после его окончания вывод на индикацию прекращается и все светодиоды будут находиться в погашенном состоянии вплоть до следующей комбинации источников прерывания.

Принципиальная схема устройства приведена на рис.

R1

+5В

RA0 Vss

RA1PICVdd

RA2 16F84A RB0

RA3 RB1

RA4 RB2

Mclr RB3

RB4

RB5 X1

RB6

RB7 X2

Vdd

R3 VD1 BQ1

R2

R4 VD2

R5 VD3

R6 VD4

ZQ1

C1 C2

Рис.11.5.

ПРЕРЫВАНИЯ ОТ ПЕРЕПОЛНЕНИЯ СЧЕТЧИКА/ТАЙМЕРА TMR0

В состав P16C84А входят периферийные модули: сторожевой таймер WDT и счетчик/таймер TMR0. Для инициализации последнего используется регистр OPTION.

Сторожевой таймер WDT

В случае зависания программы по какой-либо причине, WDT может вывести ее из этого состояния, переведя программу в положение START. Он представляет ждущий RC-мультивибратор с перезапуском, формирующий импульс длительностью примерно 18мс. Если работа WDT разрешена (а она может быть и запрещена), то после старта программы, он запускается, и, если его в течение 18мс не перезапустить, то он окончит формирование импульса и по его заднему фронту сформируется сигнал сброса программы на начало.

OPTION_REG

PS2 PS1 PS0

CLRWDT

PSA

&

7 0 7 0

Counter

PRESCALER

RC oscillator

МК

W DTE

Рис.11.6

Именно поэтому таймер WDT и назван сторожевым. Для обеспечения этого сторожевого режима, необходимо в ходе выполнения программы, периодически (через время не более 18мс) сбрасывать WDT (CLRWDT). Если после WDT поставить предделитель (PRESCALER), то период сброса WDT можно увеличить.

Счетчик/таймер TMR0

Счетчик/таймер - восьми разрядный счетчик с Ксч = 256, но с возможностью предустановки и синхронизации. Предустановка -это запись числа, начиная с которого происходит его счет. Обычно, такого рода загрузку производят для задания некой начальной точки отсчета. Если счетчик/таймер TMR0 работает без предустановки, его коэффициент счета всегда равен 256 и не меняется.

В большинстве же случаев, перед TMR0 включается предделитель с заданным Ксч и, обычно, этого бывает вполне достаточным для решения поставленных задач.

OPTION_REG

PSA PS2 PS1 PS0

TOCS TOSE

RA4/TOCKI

&

&

&

1

7 0 7 0

TMR0

PRESCALER

1

O

C LKOUT

Рис.11.7

Основная функция счетчика/таймера TMR0 - подсчет количества импульсов за определенное программой время.

Через каждые 256 импульсов (при переходе из FFН в 00Н) происходит так называемое переполнение таймера, количество которых (при необходимости подсчета количества импульсов большего чем 256) подсчитывается. Например: за 1сек. произошло 10 переполнений, значит TMR0 посчитал 2560 импульсов. Если приплюсовать к этому количеству содержимое TMR0 на момент окончания счета, то мы получим точное количество импульсов, поступивших на вход TMR0 за 1сек.

Если перед TMR0 включен предделитель, то в итог подсчета вносятся соответствующие коррективы, определяемые заданным коэффициентом счета предделителя и числом, "лежащим" в предделителе на момент окончания счета. На такого рода подсчете и основывается принцип работы устройств, производящих подсчет импульсов за заданный интервал времени.

Каждая разновидность прерываний имеет свою специфику. Для прерывания от переполнения TMR0, она заключается в том, что уход в прерывание происходит не по каждому активному управляющему перепаду на входе RA4/TOCKI, а только по тому из них, который приводит к смене .255 на .0.

Если производить отсчет от состояния .0, то уход в прерывание произойдет на 256-м активном перепаде (импульсе), но можно производить отсчет и не от .0, предварительно выполнив предустановку в TMR0 того числа, которое требуется. В этом случае, уход в прерывание будет происходить на (256 – N) импульсе, где N - число предустановки TMR0. В случае использования предделителя и предустановки TMR0, уход в прерывание будет происходить на (256 - N) х Ксч. предделителя импульсе. В простейшем случае, имеет место быть нулевая предустановка TMR0 (CLRF TMR0).

Примечание: когда ко входу TMR0 подключен предделитель, любая операция с содержимым TMR0 (например, CLRF TMR0 или запись в TMR0 константы предустановки) приводит к сбросу содержимого предделителя (специальной команды сброса содержимого предделителя нет) аппаратными средствами PICа.

Вот Вам и исходные данные для ответа на вопрос: "На каком, начиная с момента предустановки TMR0 и с учетом Ксчпредделителя, импульсе произойдет уход в прерывание"?

Например, предустановка - .0, Ксч.предделителя = 8. Уход в прерывание по переполнению TMR0 произойдет на 256 х 8 = 2048 импульсе. Если предустановка, например, .100, Ксч.предделителя = 8, то уход в прерывание по переполнению TMR0 произойдет на (256 - 100) х 8 = 1248 импульсе. Если предустановка, например, .250, а предделитель к TMR0 не подключен, то уход в прерывание по переполнению TMR0 произойдет на 256 - 250 = 6 импульсе и т.д.

В связи с этим, прерывания по переполнению TMR0 используются в том случае, когда нужно задать некую "границу дозволенного", при превышении которой устройство очень быстро (с малой инерционностью) реагирует на ее превышение.

Пример: из каждых 10000 операций допускается 10 операций, результат которых выходит за рамки нормы (пределов дозволенного). Допустим, что этих "ненормальных" операций стало 11. На 11-й операции устройство быстренько срабатывает, и либо вообще блокирует весь процесс, либо вносит поправку, уменьшающую количество этих "ненормальных" операций (либо еще какое-то "полезное" действие). Это "полезное" действие (действия) производится в подпрограмме прерываний. Если питание устройства не выключается, то возможны 2 варианта:

- после совершения "полезного" действия и выхода из прерывания, исполнение программы продолжается с того места основной программы, на котором был обнаружен "дефект".

- программа уходит в подпрогррамму прерываний в "вечное кольцо" и продолжение работы в основной программе не возможно (блокировка).

В качестве внутреннего тактового сигнала используется сигнал с частотой опорного генератора PICа, деленной на 4, т.е. TMR0 будет считать каждый машинный цикл (1мкс при применении кварца на 4мГц). Это - для случая работы TMR0 без предделителя. При применении предделителя, TMR0 будет, естественно, считать медленнее.

CNTMR0 Программа прерывания от переполнения счетчикаTMR0

Само название "прерывания от переполнения TMR0" указывает на то, что уход в прерывания происходит после того, как содержимое TMR0 изменится с .255 на 0. Естественно, для того чтобы это имело место быть, TMR0 нужно "запустить в работу", что, в самом распространенном случае (TMR0 считает внешний такт), предполагает:

- настройку вывода RA4/TOCKI на работу "на вход";

- выбор внешнего такта с вывода RA4/TOCKI – TOCS (Option<5>);

- выбор активного перепада, производящего приращение содержимого TMR0 – TOSE (Option<4>). В большинстве случаев, выбор активного перепада не имеет особого, практического значения и обычно в бите TOSE регистра Option выставляется 0 (активный перепад - от 0 к 1);

- выбор способа включения предделителя. Если предделитель не нужен, то он подключается на выход WDT - бит PSA (Option<3>) устанавливается. В этом случае, речь идет о "чистом" TMR0 с коэффициентом счета Ксч.=256. Если требуется больший чем 256 коэффициент счета, то перед TMR0 нужно включить предделитель с заданным Ксч. бит PSAcбрасывается. КонкретныйКсч. предделителя выставляется в битах PS0, PS1, PS2 (Option<2…0>) и зависит от задумки программы.

- в начале исполнения программы нужно разрешить прерывания по переполнению TMR0: установить биты GIE (Option<7>) и TOCS (Option<5>).

Указанное выше есть не что иное, как подготовительные операции основной программы, которые должны выполняться первыми (по метке START).

T MR +5В

RA0 Vdd

RA1 PIC Vss

RA2 16F84A RB0

RA3 RB1

RA4 RB2

Mclr RB3

RB4

RB5

X1 RB6

X2 RB7

Vdd

BQ1 R1

R2

VD1 R3

Signal

Generator

ZQ1

C1 C2

Рис. 7.10. Принципиальная схема устройства c использованием прерываний от таймера

Программа CNTMR0 позволяет показать механизм работы прерываний: факт возвращения рабочей точки программы (после обработки прерывания) именно в то место основной программы, с которого она ушла в текущее прерывание по переполнению TMR0.

После включения питания программа, через проверку состояния кнопки "TMR" (BTFSC PORTA,1), закольцовывается (GOTO START) и будет там пока не произойдет нажатие кнопки "TMR”.

;*******************************************************

; CNT_TMR0 - Прерыввания от переполнения счетчика TMR0

;*******************************************************

; пьезоизлучатель подключен к RА2

; регистры хранения W и STATUS----------

W_TEMP EQU 4FH

STAT_TEMP EQU 4EH

CNT0 EQU 0CH ; Счетчик времени полупериода

CNT1 EQU 0BH ; Счетчик периодов импульсного сигнала

;---------------------------------------------------------

GOTO START

;-------------------------------------------------

;ПОДПРОГРАММЫ

;-------------------------------------------------

;подпрограмма обработки прерывания------

ORG 0x0004

;сохранение значений W и STATUS----------

MOVWF W_TEMP ; Копирование W в регистр W_TEMP.

SWAPF STATUS,W ; Смена полубайтов регистра STATUS

MOVWF STAT_TEMP ; Копирование W в регистр STAT_TEMP.

BCFPORTA,3 ; выключить светодиод

; число периодов импульсного сигнала------

MOVLW .10

MOVWFCNT1

; Формирование импульса на выводе RA2----

LOOP

BSF PORTA,2 ; Установить RA2.

CALL DELAY

; Формирование паузы на выводе RA2 ------

BCF PORTA,2 ; сбросить RA2.

CALL DELAY

; Переход на новый цикл программы.

DECFSZCNT1,F ; формирование сигнала закончено?

GOTOLOOP ; нет, продолжить

RETURN ; да, завершить

; сброс флага прерываний-----------------------

BCFINTCON,T0IF

; восстановление значений W и STATUS---

SWAPFSTAT_TEMP,W ; Обмен полубайтами. Результат сохраняется в W.

MOVWF STATUS ; Копирование содержимого W в регистр Status.

SWAPF W_TEMP,F ; Обмен полубайтами.

SWAPFW_TEMP,W ; Обмен полубайтами. Результат сохраняется в W.

RETFIE

;Подпрограмма задержки-----------------------

DELAY

MOVLW .24

MOVWF CNT0 ; копировать .24 из W в регистр CNT0

PAUZE

NOP

DECFSZ CNT0,F ; Декремент содержимого регистра CNT0

GOTO PAUZE ; и цикл пока CNT0 не = 0

RETURN ; CNT0 = 0, вернуться в подпрограмму

;================================

; ОСНОВНАЯ ПРОГРАММА-

;================================

START

; инициализация порта В------------------

BSFSTATUS,RP0

CLRF TRISB

MOVLW B’10011’

MOVWF TRISA

; настройкатаймера------------------------

; прерывания от внешнего генератора

BSF OPTION_REG,T0CS

; предделитель отключен------------------

BSFOPTION_REG,PSA

BCFSTATUS,RP0

; oжидание нажатия кнопки-------------

L00K: BTFSSPORTA,1

GOTOL00K

; разрешение прерываний от переполнения счетчика

BSFINTCON.T0IE;

BSFINTCON.GIE

BSFPORTA,3 ; включить светодиод

GOTOSTART

; конец всем командам---------------------

END

Шапка программы

ПП прерываний

Загрузка числа повторов времени звука CNT_0

Основная программа

Настройка портов

Формирование импульса

Настройка таймера

ПП Delay

Формирование паузы

TMR0 нажата?

ПП Delay

Разрешение прерываний

нет

CNT_0=0?

Включить светодиод

кнопка отжата

TMR0=1?

Выход из прерывания

Рис. 7.11. Алгоритм программы прерывания от переполнения TMR0

На вход RA4/TOCKI подаются импульсы с выхода генератора сигналов (Tools>Signal Generator) частотой 400 Гц. После нажатия на кнопку "TMR" счетчик TMR0 начинает считать импульсы Signal Generator, что видно в основном окне PIC Simulator IDE по зажиганию светодиода, подключенного к RА1. Свечение светодиода будет продолжаться до тех пор, пока не произойдет переполнение TMR0 и ухода в прерывание. В качестве программы обработки прерывания используется программа зукового генератора Multi. Действие программы видно на экране осциллографа, подключенного к выводу RА2, количеством периодов = 10 (время "горения" равно времени "гашения" - по 0,2 сек.).

Таким образом, по осциллографу можно визуально проконтролировать время исполнения подпрограммы прерывания.

В момент ухода в прерывание программа вышла из основной программы, и после обработки прерывания, вернется по стеку в то место основной программы, из которого она ушла в прерывание. Работа в основной программе продолжится далее, после чего программа зациклится командой GOTO START и будет там "крутиться" в ожидании следующего прерывания, при пассивности моргалки".

Прерывания от переполнения таймераTMR0

Есть еще одна разновидность работы TMR0: на его вход (или предделителя, если он подключен ко входу TMR0) подаются импульсы внутреннего тактового генератора CLKOUT (бит TOCS регистра OPTION сброшен). В этом случае, если предделитель не подключен, приращение содержимого TMR0 будет происходить в каждом машинном цикле, а если подключен, то реже (зависит от выставленного коэффициента счета предделителя).

Этот режим используется для формирования калиброванных временных отрезков в электронных часах, календарях, будильниках, и т.п. Для получения задержки 1 сек при тактовой частоте 4 МГц (время выполнения команды 4Т=1 мкс) необходимо обеспечить с помощью трех делителей коэффициент деления 64х125х125=1 000 000.

ПРОГРАММА: ПРЕРЫВАНИЯ ОТ ПЕРЕПОЛНЕНИЯ ТАЙМЕРА TMR0

В основной программе выполняется настройка порта В на выход (CLRFTRISB) и запуск таймера от внутреннего генератора (BCF OPTION_REG,T0CS). Предделитель не подключаенко входу таймера (BSF OPTION_REG,PSA). После инициализации МК и таймера разрешаются прерывания (), в порту В устанавливается константа .255 и программа входит в зону прерываний.

;=============================================

; TIMER0 - Прерывания от переполнения таймера TMR0

;-=============================================

; регистры хранения W и STATUS----------

W_TEMP EQU 4FH

STAT_TEMP EQU 4EH

;---------------------------------------------------------

GOTO START

; вектор прерываний------------------------------

ORG 0x0004

;сохранение значений W и STATUS----------

MOVWF W_TEMP ; Копирование W в регистр W_TEMP.

SWAPF STATUS,W ; Смена полубайтов регистра STATUS

MOVWF STAT_TEMP ; Копирование W в регистр STAT_TEMP.

;подпрограмма обработки прерываний------

MOVLW 01

SUBWFPORTB,W

MOVWFPORTB;

RETURN

; сброс флага прерываний-----------------------

BCFINTCON,T0IF

; восстановление значений W и STATUS---

SWAPFSTAT_TEMP,W ; Обмен полубайтами. Результат сохраняется в W.

MOVWF STATUS ; Копирование содержимого W в регистр Status.

SWAPF W_TEMP,F ; Обмен полубайтами.

SWAPFW_TEMP,W ; Обмен полубайтами. Результат сохраняется в W.

RETFIE

; Основная программа---------------------

START

; инициализация порта В------------------

BSFSTATUS,RP0

CLRFTRISB

; настройка таймера-----------------

; прерывания от внутреннего генератора

BCF OPTION_REG,T0CS

; предделитель отключен-----------

BSF OPTION_REG,PSA

; разрешение прерываний по переполнению таймера

BSF INTCON.T0IE;

BSF INTCON.GIE

BCFSTATUS,RP0

; установка 255 в порт В-------------

MOVLW 0FFH

MOVWF PORTB

; зона прерываний--------------------

L00K:

NOP

GOTOL00K

; конец всем командам

END

EEPROM ДАННЫХ

В состав МК РIС16F84А входит ПЗУ EEPROM данных — электрически программируемое ПЗУ, которое имеет восьмиразрядную организацию и предназначено для хранения значений переменных программы при выключенном питании. Обычно числа из EEPROM после старта программы переносят в обычные ячейкам памяти данных. Управляет процессом записи/считывания регистры EECON1 и EECON2.

Pис.7.12

Чтение информации

Сделать это довольно просто: достаточно занести адрес нужной ячейки EEPROM в регистр EEADR, затем установить разряд RD регистра EECON1 и прочитать хранящийся код из регистра EEDATA.

Строго говоря, перед обращением к EEPROM следует проверить содержимое peгистpaEECON1, и убедится, что успешно закончены предыдущие операции чтения (RD=0) и записи (WR=0). Нулевые значения в этих разрядах устанавливают аппаратно, их принудительная запись не имеет смысла. Между установкой RD и чтением регистра EEDATA разряд RD должен успеть вернуться в исходное (нулевое) состояние. Обычно это не проверяют, так как чтение из EEPROM занимает всего один машинный цикл, для него достаточно времени, затрачиваемого на переключение банков регистров командой BCF.

MOVLWADDR ; Адрес ячейки EEPROM

MOVWFEEADR ; заносим в EEADR

BSF STATUS,RP0 ; EECON1 вбанке 1

BSF EECON1,RD ; Командачтения

BCF STATUS,RP0 ; EEDATA вбанке 0

MOVFWEEDATA ; W = EEDATA

ПРОГРАММА: ЧТЕНИЕ ИНФОРМАЦИИ ИЗ EEPROM ДАННЫХ

Приведена программа чтения из EEPROM данных с последующим копированием в ОЗУ микроконтроллера, начиная с адреса 10Н. размер адресного поля определен константой 3FH.

;=======================================

;RD_EEPROM - Чтение данных из EEPROM

;=======================================

;определение переменных-------------------------------

ADDR1 EQU 10H

GOTO BEGIN ; к началу

; Подпрограмма чтения------------------------------------

READ_EE

BSF STATUS,RP0 ; банк 1

BSF EECON1,RD ; инициализация чтения

BCF STATUS,RP0 ; банк 0

RETURN ; возврат

; Основная программа-----------------------------------

BEGIN

MOVLW ADDR1 ; начало адресного

MOVWF FSR ; поля

CLRF EEADR ;

METKA

CALL READ_EE ; прочитать

MOVFW EEDATA ; копировать в W

MOVWF INDF ; и переслать в начало адр. поля

INCF FSR,F ; увеличить адрес

INCF EEADR,F ; в EEADR

MOVFW EEADR ; все

XORLW 3FH ; переменные

BTFSS STATUS,Z ; прочитаны?

GOTO METKA ; нет, продолжить

GOTO $ ; да, зациклиться навсегда

; конец всем командам ------------------------

END

Запись информации

Предварительного стирания содержимого ячейки EEPROM перед записью в нее не требуется, но процедура записи умышленно усложнена. Это сделано для того, чтобы при сбоях предотвратить случайное искажение хранящихся данных. Занеся в регистр EEADR адрес ячейки, а в EEDATA — предназначенный для записи в нее код, следует выполнить следующие операции:

BSFSTATUS,RP0 ; Включаем банк 1

BCFINTCON,GIE ;Запрещаем все прерывания

BSFEECON1,WREN ; Разрешаем запись

MOVLWН'55’

MOVWF EECON2

MOVLW H'AA'

MOVWF EECON2

BSFEECON1,WR ; Команда начала записи

BSFINTCON,GIE ;Разрешаемпрерывания

Команды, выделенные полужирным шрифтом, обязательны перед записью в каждую ячейку EEROM. Запрет прерываний необходим, если они были разрешены. После начала записи прерывания можно разрешить вновь. Установить WREN допустимо один раз перед началом цикла записи в несколько ячеек. Если же запись в EEPROM не предвидится, лучше сбросить этот разряд .

Собственно запись занимает довольно много времени (до 10 мс на ячейку). Выполняется она без участия процессорного ядра МК, которое может в это время заниматься другими делами. Об окончании записи свидетельствует аппаратное обнуление разряда WR регистра EECON1 и установка в его же разряде EEIF — флаге запроса прерывания.сбрасывать флаг следует программно.

Запись в EEPROM, несмотря на все принятые меры, остается одной из самых опасных операций. Случайное выключение питания, подача сигнала сброса или срабатывание сторожевого таймера во время ее выполнения приводят к досрочному прекращению начатого процесса, содержимое записываемой ячейки остается неопределенным. Об ошибке сигнализирует (к сожалению, не всегда) установка WRERR в регистре EECON1, который в этом случае следует принудительно обнулить и повторить запись. Более надежно контрольное считывание записанного значения и сравнение его с заданным.

ПРОГРАММА: ЗАПИСЬ ИНФОРМАЦИИ В EEPROM ДАННЫХ

Для данных и адресов, по которым происходит их запись, используются регистры DATA и ADDR, информация сначала устанавливается там, а затем копируется в регистрах EEPROM данных: ЕЕDATA и EEADR.

Окончание записи в ячейку выполнено командой BTFSC EECON1,WR, которая при сбросе разряда WR выводит программу из цикла ожидания.

;============================================

;WR_EEPROM - Запись данных в EEPROM

;===================================

;определение адресов переменных-----------------

ADDREQU 0Ch ; регистр адреса

DATAEQU 0Dh ; регистрданных

GOTOSTART

; increment ADR EEPROM c 0 to F (15)-----------

START

CLRF ADDR ; установка адреса 00H

LOOK

MOVFW ADDR ; адресв W

SUBLW 0FH ; уменьшаем на 1 с 15

BTFSS STATUS,C ;пока не достигнет 0 (тогда с=0)

GOTO EXIT ; тогда закончить

; уменьшаем данные записи: 254 – ADDR-------

MOVF ADDR,W ; адрес в W

SUBLW .254 ; 254 - adr

MOVWF DATA ; результат в DATA

; установить ADR и DATA перед записью --------

MOVFW ADDR

MOVWF EEADR ;

MOVFW DATA ;

MOVWF EEDATA ;

BSF STATUS,RP0 ;банк1

BSFEECON1,WREN ;разрешениезаписи

MOVLW 55H ; стандартная

MOVWFEECON2 ; процедура

MOVLW 0AAH ; перед

MOVWFEECON2 ; записью

BSF EECON1,WR ;инициализация записи

WAIT

BTFSC EECON1,WR ;ожидание окончания

GOTO WAIT ;записи (4 мс)

BCF EECON1,WREN ;запрет записи

BCF EECON1,EEIF ;сброс флага

BCF STATUS,RP0 ;возврат в банк 0

; Установка следующего адреса-----------------

INCF ADDR,F ; увеличиваем адрес до

BTFSC STATUS,C ; 0FH

GOTO LOOK ;

EXIT

GOTO $ ; конец записи

;----------------------------------------------------------

END

ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ

- Прерывание - это своеобразный переход, в большинстве случаев, по внешнему воздействию, из основной программы, на выполнение подпрограммы прерывания, с последующим из нее возвратом в основную программу.

- По наступлению события прерывания нормальное выполнение программы будет остановлено и программа перейдет на адрес ПЗУ 0x004, который называется вектором прерывания. По этому адресу и должна находиться подпрограмма отработки прерывания. При этом адрес возврата сохраняется в стеке.

У PIC – контроллеров вектор прерывания один для всех источников, поэтому данная подпрограмма должна сама различать события, вызвавшие прерывание, если разрешено более одного прерывания. Определение источника прерывания производится путем опроса соответствующих флагов прерывания, которые устанавливаются по наступлению прерывания. По прерыванию по входу RB0 – флаг INTF (INTCON,1), а по входу RB4 - RB7 – RBIF (INTCON,0).

Для ухода в прерывания необходимо:

1. в "шапке" программы определить вектор прерывания;

2. определить активный фронт прерываний (OPTION), в "основном теле"программы;

3. назначить источник (INTCON) и "зону" действия прерываний;

4. в начале подпрограммы прерывания сохранить, а в конце подпрограмм прерывания (до команды RETFIE) - восстановить содержимое регистров STATUS и W;

5. сбросить флаг прерывания по выбранному источнику прерываний;

6. в самом конце подпрограммы прерываний записать команду RETFIE.

Прерывания по изменению уровней сигналов на выводах RB4...RB7 являются одной из разновидностей прерываний. В отличие от прерываний по выводу INT, где нужно предварительно определить активные фронты прерываний (бит INTEDG регистра Option), для прерываний по измененнию уровней сигналов на выводах RB4...RB7, этого делать не требуется, так как уход в эти прерывания происходит и при смене 0 на 1, и при смене 1 на 0 на любом из выводов RB4...RB7.

Если сравнить прерывания по выводу INT и прерывания по изменению уровней сигналов на любом из выводов RB4...RB7, то, за исключением указанного выше и того, что перед выходом из прерывания нужно сбросить другой флаг (RBIF), их механизм одинаков. Так что, если речь идет только об одном внешнем устройстве, которое является источником прерываний, и нужно уйти в прерывания не по какому-то конкретному перепаду, а по любому перепаду внешнего управления, то это внешнее устройство можно подключить к любому из 4-х выводов RB4...RB7.

Главное преимущество работы со всеми типами прерываний - малая инерционность отклика устройства на внешний управляющий сигнал прерывания (активный перепад), что может быть очень полезным в тех конструкторских разработках, к которым предъявляются жесткие требования по инерционности (скорости) срабатывания исполнительных устройств.

При уходе в прерывание команда CALL существует (стек задействован), но она как бы "виртуальная" (в явном виде не выражена и в тексте программы не указывается). Она опознается и исполняется внутри PICа его аппаратными средствами. Команда же возврата из прерывания (по стеку) вполне реальная (RETFIE). Она применяется только при выходе из прерывания и нигде более. Сказанное выше ("виртуальный" CALL и RETFIE) относится ко всем типам прерываний, и это есть их "глобальный" механизм.

ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ

7.1. Какое максимальное количество байт могут обойти команды коpоткий JMP, LOOP и относительный переход? Какой машинный код операнда при этом генерируется?

7.3. Напишите программу вычисления 12 чисел Фибоначчи: 1, 1, 2, 3, 5, 8, 13,... (каждое число в последовательности представляет собой сумму двух предыдущих чисел). Для организации цикла используйте команду LOOP.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]