Переполнение таймера TMR0 (FFh → 00h) устанавливает флаг T0IF (INTCON<2>) в '1'. Прерывание от TMR0 можно разрешить/запретить установкой/сбросом бита T0IE(INTCON<5>).
Рассмотренный в Лабораторной работе № 7 пример организации временной задержки с использованием TMR0 не является программно независимым как таковым. В нём хотя и ведётся программно-независимый подсчёт числа внутренних машинных циклов, в отличие от многократного вычитания содержимого регистра, но при общем запрете на прерывание ведётся анализ флага переполнения программным же способом. Задача получения программно независимых временных задержек решается только обработкой прерываний по переполнению таймера, в нашем случае TMR0.
Рассмотрим пример, когда основная программа прерывает свой естественный ход каждые 20ms, отвлекаясь на выполнение какой-либо задачи, например изменение состояния PORTB с частотой 25Гц.
#include P16F877.inc
;**************************************************************************
; Программа вызывает изменение состояния порта PORTB каждые 20ms.
; Формирование временной задержки (20ms) формируется прерыванием по
; переполнению таймера TMR0.
;**************************************************************************
TMP equ 20h; определение адреса какой-то переменной TMP
; основной программы
;**************************************************************************
; Запись MACROSa
;**************************************************************************
BANK0 macro; Установка Банка - 0
bcf STATUS, RP0
bcf STATUS, RP1
endm
BANK1 macro; Установка Банка - 1
bsf STATUS, RP0
bcf STATUS, RP1
endm
BANK2 macro; Установка Банка - 2
bcf STATUS, RP0
bsf STATUS, RP1
endm; конец записи MACROSa
;**************************************************************************
org 0x00; адрес начала программы
goto START; переход на метку START
; (начало основной программы)
org 0x04; адрес размещения программы обработки прерывания
;**************************************************************************
;* П/П обслуживания прерывания по TMR0(каждые 20mc)
;**************************************************************************
BANK0; Банк 0
bcf INTCON, T0IF;снять флаг прерывания TMR0
bcf INTCON, T0IE;запретить прерывания от TMR0
movlw 64h; загрузить TMR0 = 64h(100)
movf TMR0;
BANK1; Банк 1
movlw 00000110b; TMR0 от внутреннего сигнала
movf OPTION_REG; предделитель 1:128
BANK0; Банк 0
comf PORTB; PORTB = not (PORTB)
bsf INTCON, T0IE; запуск таймера TMR0
retfie; возврат из прерывания с разрешением прерывания
; GIE = 1
org 0x50; адрес размещения основной программы
;***************************************************************************
;* О С Н О В Н А Я П Р О Г Р А М М А
;***************************************************************************
START: BANK0; Банк 0
clrf PORTB; PORTB = 00h
bcf INTCON, T0IF; снять флаг прерывания
movlw 64h; загрузить TMR0 = 64h(100)
movf TMR0;
BANK1; Банк 1
movlw b'00000000'; настройка выводов порта В
movwf TRISB; на вывод информации
movlw 00000110b; TMR0 от внутреннего сигнала
movf OPTION_REG; предделитель 1:128
bsf INTCON, T0IE; запуск TMR0
bsf INTCON, GIE;РАЗРЕШЕНИЕ ВСЕХ ПРЕРЫВАНИЙ
nop; бесконечный цикл
goto $-1; имитация выполнения основной программы
end
3.8.2.2 Внешнее прерывание с входа RB0/INT
Внешнее прерывание с входа RB0/INT происходит: по переднему фронту сигнала, если бит INTEDG (OPTION_REG<6>) установлен в '1'; по заднему фронту сигнала, если бит INTEDG сброшен в '0'. Когда активный фронт сигнала появляется на входе RB0/INT бит INTF (INTCON<1>) устанавливается в '1'. Прерывание может быть запрещено сбросом бита INTE (INTCON<4>) в '0'. Флаг прерывания INTF должен быть сброшен программно в подпрограмме обработки прерываний.
3.8.2.3 Прерывание по изменению уровня сигнала на входах RB7:RB4
Изменение уровня сигнала на входах RB7÷RB4 вызывает установку флага RBIF(INTCON<0>). Прерывание можно разрешить или запретить установкой или сбросом бита RBIE(INTCON<4>). Описание работы PORTB смотрите в разделе 1.8.2.
Рассмотрим пример, когда в основной основная программа прерывает свой естественный ход либо каждые 20ms, изменяя состояния PORTB с частотой 25Гц, либо по замыканию входа RB0/INT на общий провод, либо по изменению уровня сигнала на входах RB7:RB4.
#include P16F877.inc
;**************************************************************************
; Программа вызывает изменение:
; – состояния порта PORTB каждые 20ms;
; – состояния порта PORTC при замыкании на «землю»RB0/INT;
; – состояния порта PORTD при изменении уровня сигнала на входах RB7:RB4
;**************************************************************************
; Запись MACROSa
;**************************************************************************
BANK0 macro; Установка Банка - 0
bcf STATUS, RP0
bcf STATUS, RP1
endm
BANK1 macro; Установка Банка - 1
bsf STATUS, RP0
bcf STATUS, RP1
endm
BANK2 macro; Установка Банка - 2
bcf STATUS, RP0
bsf STATUS, RP1
endm; конец записи MACROSa
;**************************************************************************
org 0x00; адрес начала программы
goto START; переход на метку START
; (начало основной программы)
org 0x04; адрес размещения программы обработки прерывания
;**************************************************************************
; П/П обслуживания прерывания:
; по TMR0(каждые 20mc) / по INT / по RB7:RB4.
;**************************************************************************
; Определение источника прерывания
;**************************************************************************
btfsc INTCON, INTF; прерывания от INT?
goto METKA1; Да
btfss INTCON, RBIF;Нет, прерывания от RB7:RB4?
goto METKA2; Да
btfss INTCON, T0IF; Нет, прерывания от TMR0?
goto RETR; Нет, источник прерывания неизвестен
;**************************************************************************
; П/П обслуживания прерывания от таймера TMR0
;**************************************************************************
BANK0; Банк 0
bcf INTCON, T0IF; снять флаг прерывания TMR0
bcf INTCON, T0IE; запретить прерывания от TMR0
movlw 64h; загрузить TMR0 = 64h(100)
movf TMR0;
BANK1; Банк 1
movlw 00000110b; TMR0 от внутреннего сигнала
movf OPTION_REG; предделитель 1:128/RB0/INT-по «срезу»
BANK0; Банк 0
comf PORTB; PORTB = not (PORTB)
bsf INTCON, T0IE; запуск таймера TMR0
goto RETR
;**************************************************************************
; П/П обслуживания прерывания при замыкании на «землю»RB0/INT
;**************************************************************************
METKA1: BANK0; Банк 0
bcf INTCON, INTF; снять флаг прерывания INT
bcf INTCON, INTE; запретить прерывания от INT
comf PORTC; PORTC = not (PORTC)
bsf INTCON, INTE; разрешить прерывания от INT
goto RETR
;**************************************************************************
; П/П обслуживания прерывания при изменении уровня сигнала на входах RB7:RB4
;**************************************************************************
METKA2: BANK0; Банк 0
bcf INTCON, RBIF; снять флаг прерывания RB7:RB4
bcf INTCON, RBIE; запретить прерывания от RB7:RB4
comf PORTD; PORTD = not (PORTD)
bsf INTCON, RBIE; разрешить прерывания от RB7:RB4
RETR: retfie; возврат из прерывания с разрешением прерывания
; GIE = 1
org 0x50; адрес размещения основной программы
;***************************************************************************
;* О С Н О В Н А Я П Р О Г Р А М М А
;***************************************************************************
START: BANK0; Банк 0
bcf INTCON, T0IF; снять флаг прерывания TMR0
bcf INTCON, INTF; снять флаг прерывания INT
bcf INTCON, RBIF; снять флаг прерывания по входам RB7:RB4
movlw 64h; загрузить TMR0 = 64h(100)
movf TMR0;
clrf PORTB; PORTB = 00h
clrf PORTC; PORTB = 00h
clrf PORTD; PORTB = 00h
BANK1; Банк 1
movlw b'00000000'; настройка выводов порта В, С, D
movwf TRISB; на вывод информации
movwf TRISC
movwf TRISD
movwf TRISE; PORTD конфигурируется как цифровой
; сбросом PSPMODE(TRISE<4>)
movlw 00000110b; TMR0 от внутреннего сигнала
movf OPTION_REG; предделитель 1:128/RB0/INT-по «срезу»
BANK0; Банк 0
bsf INTCON, T0IE; запуск TMR0
bsf INTCON, INTE; разрешено прерывание по INT
bsf INTCON, RBIE; разрешено прерывание по INT
bsf INTCON, GIE;РАЗРЕШЕНИЕ ВСЕХ ПРЕРЫВАНИЙ
nop; бесконечный цикл
goto $-1; имитация выполнения основной программы
end
Содержание лабораторной работы
1. Изучить способы обработки прерываний от внешнего входа RB0/INT, переполнения TMR0 и изменения уровня сигнала на входах RB7:RB4.
2. Научится определять источник прерывания при одновременном возникновении нескольких прерываний.