Прерывание по переполнению TMR0

Переполнение таймера 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. Научится определять источник прерывания при одновременном возникновении нескольких прерываний.

Наши рекомендации