AFON // радиотехник affonya@mail.ru
← Проекты на PIC

Проект 20. Прерывание по переполнению TMR0

Таймер сам дёргает программу по готовности: светодиод мигает в обработчике прерывания, пока основной цикл занят своей задачей. Так строятся все многозадачные прошивки.

Задача

Мигать одним светодиодом из обработчика прерывания, вторым — из основного цикла.

Микроконтроллер: PIC16F84A, кварц 4 МГц. Среда: MPLAB X + MPASM (или любой совместимый ассемблер). Как настроить среду и прошить контроллер — в статье программирование PIC.

Что понадобится

  • PIC16F84A
  • кварц 4 МГц + 2×22 пФ
  • два светодиода + 2×330 Ом
  • резистор 10 кОм

Схема подключения

ВыводПодключение
RB0светодиод, управляемый прерыванием
RB1светодиод фоновой задачи
MCLRчерез 10 кОм на +5 В

Алгоритм

  1. Разместить обработчик по адресу 0x004 — это вектор прерывания.
  2. В начале сохранить W и STATUS, в конце восстановить и выйти по retfie.
  3. Разрешить прерывание битами T0IE и GIE.
  4. В обработчике сбросить флаг T0IF и выполнить действие.

Листинг на ассемблере

Код проверен ассемблером и собирается без ошибок. Скачать: p20.asm · p20.hex (готовая прошивка).

;=======================================================
; Проект 20. Прерывание по переполнению TMR0
; PIC16F84A, 4 МГц. Светодиод RB0 мигает в обработчике,
; основная программа свободна (мигает вторым светодиодом RB1)
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

        cblock  0x0C
        w_temp, s_temp          ; сохранение контекста
        ovf, d1, d2
        endc

        ORG     0x000
        goto    Start

;--- вектор прерывания ---
        ORG     0x004
        movwf   w_temp          ; сохраняем W
        swapf   STATUS,w
        movwf   s_temp          ; сохраняем STATUS

        btfss   INTCON,T0IF     ; наше ли прерывание?
        goto    IsrEnd
        bcf     INTCON,T0IF
        decfsz  ovf,f
        goto    IsrEnd
        movlw   .8
        movwf   ovf             ; перезаряжаем счётчик
        movlw   b'00000001'
        xorwf   PORTB,f         ; мигаем светодиодом RB0
IsrEnd
        swapf   s_temp,w        ; восстанавливаем STATUS
        movwf   STATUS
        swapf   w_temp,f
        swapf   w_temp,w        ; восстанавливаем W
        retfie

Start
        bsf     STATUS,RP0
        clrf    TRISB
        movlw   b'00000111'     ; предделитель 1:256 на TMR0
        movwf   OPTION_REG
        bcf     STATUS,RP0
        clrf    PORTB
        movlw   .8
        movwf   ovf

        bcf     INTCON,T0IF
        bsf     INTCON,T0IE     ; разрешаем прерывание от TMR0
        bsf     INTCON,GIE      ; общее разрешение прерываний

Main                            ; фоновая задача идёт своим темпом
        movlw   b'00000010'
        xorwf   PORTB,f
        call    Delay
        goto    Main

Delay
        movlw   .200
        movwf   d1
DL1     movlw   .250
        movwf   d2
DL2     nop
        decfsz  d2,f
        goto    DL2
        decfsz  d1,f
        goto    DL1
        return

        END

Пояснения

  • Сохранение контекста обязательно: прерывание может прийти в любой момент, и испорченные W или STATUS сломают основную программу.
  • STATUS сохраняют через swapf, потому что эта команда не меняет флаг нуля, в отличие от movf.
  • Флаг T0IF аппаратно не сбрасывается — забыв про bcf INTCON,T0IF, получите бесконечный вход в обработчик.

Что дальше

Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры PIC.