Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Микроконтроллеры PIC фирмы Microchip для начинающих выпуск №19


РАССЫЛКА Микроконтроллеры PIC фирмы Microchip для начинающих
Ведущий: Алексей (pont_a@mail.ru)


Доброго времени суток, дамы и господа!!

Сегодня продолжаем рассматривать систему прерываний  микроконтроллеров серии PIC18 на базе микроконтроллера PIC18F452! Напишем элементарную программу мигания светодиодом, но уже с использованием системы прерываний!

Как мы помним, в 13-ом выпуске мы уже писали программу мигания светодиодом, только систему прерываний не использовали (флаг прерывания от таймера 1 проверялся в основном цикле).  

Сегодня напишем программу, которая будет работать через прерывания. Чем удобен такой подход? Тем, что основной цикл у нас будет разгружен от постоянной проверки (поллинга) флага прерывания! И мы можем спокойно выполнять в нем другие задачи.
Данные коды Вы можете использовать для собственных разработок, как изначальные! 
Итак, вот исходные коды программы со всеми комментариями:

;===================================================================================
; подключаем стандартный заголовочный файл
#include <P18F452.INC>
; директивой LIST задаем тип микроконтроллера, формат HEX-файла
; и формат констант по-умолчанию - десятичный.
LIST    P=18F452, f=INHX32, R=DEC
; задаем биты конфигурации (как задавать, смотрите шестой выпуск)
CONFIG  OSC=HS                  ; тактирование от кварца частотой 20МГц
CONFIG  OSCS=OFF          ; запретить переключать частоту тактирования микроконтроллера
CONFIG  PWRT=ON                 ; включать задержку на 72мс после включения питания
CONFIG  BOR=ON, BORV=45    ; схему сброса по провалу питания включить. Порог = 4,5В
; старайтесь использовать сторожевой таймер всегда!
CONFIG  WDT=ON, WDTPS=128  ; сторожевой таймер включить, период 2,3 сек
CONFIG  STVR=ON                 ; по переполнению стека давать сброс микроконтроллера
; объявляем константы
ab equ 0 ; признак, что переменная находиться в access bank     
bb equ 1 ; признак, что адрес необходимо считать с использованием регистра BSR
rw equ ab ; rw=0. Результат размещается в регистр-аккумулятор WREG
rf equ bb     ; rf=1.  Результат размещается в регистр FREG
; объявляем переменные
CBLOCK  0x000    ; блок начинается с нулевого адреса банка 0
     timer0h, temp      ; и т.д.
ENDC
; основная программа
; прерывания будем использовать без приоритетов в совмещенном режиме 
ORG  0
     BRA      Main_Init     ; делаем переход на основную программу
;**************************************************************************************
;================= обработчик прерываний ==============================================
;**************************************************************************************
ORG  0x08          ; общий вектор прерываний в совмещенном режиме
; как мы помним, в совмещенном режиме системы прерываний можно использовать аппаратный быстрый стек, поэтому регистры WREG, STATUS, BSR программно не сохраняем
; весь обработчик прерываний заключается в проверке флагов, чтобы выявить источник возникшего прерывания
     BTFSS    INTCON, TMR0IF, ab ; прерывание от таймера 0?
     BRA      Next_Int           ; нет. проверяем следующий флаг
     BCF      INTCON, TMR0IF, ab ; да, сбросили флаг прерывания
     DECFSZ   timer0h, rf, ab         ; вычитаем из старшего байта 1 и проверяем, закончился таймаут или нет?
     BRA      Next_Int           ; таймаут не закончился, ждем нового переполнения таймера 0 
     BTG      LATD, RD0, ab      ; закончился, проинвертировали выход на светодиод (вкл. или выкл.)
     MOVLW    76
     MOVWF    timer0h, ab             ; запускаем новый таймаут
Next_Int:    

; . . .                          ; здесь можно поставить проверку флагов других источников прерываний

     RETFIE   FAST     ; регистры WREG, STATUS, BSR восстанавливаются автоматически, константа FAST объявлена в файле P18F452.INC и равна 1
;**************************************************************************************
;================= основная программа ==================================================
;**************************************************************************************
Main_Init:
; изначально, при инициализации, всегда запрещают все прерывания
     CLRF    INTCON, ab         ; сбросили глобальные флаги прерываний
     BCF     RCON, IPEN, ab     ; запретили приоритетные прерывания, система прерываний в совмещенном режиме
; если пины не используются на схеме, то они должны быть настроены все на вход
; при включении питания все порты ввода/вывода по умочанию настроены на вход
; поэтому мы должны настроить на выход только пин 0 порта D для работы светодиода
; также надо отключить аналоговые входа.
     MOVLW    0x07
     MOVWF    ADCON1, ab         ; отключаем аналоговые входа, все пины цифровые
     CLRF     LATD, ab      ; на выход светодиода пойдет сразу 0 (будет выключен)
     BCF      TRISD, RD0, ab     ; пин 0 порта D настроили, как выход, и на  светодиод пошел 0
; инициализируем таймер 0
     CLRF     T0CON, ab     ; перед тем, как настраивать, отключаем таймер
; флаг прерывания мы уже сбросили, очистив регистр INTCON
; таймаут расчитывается следующим образом: 20МГц/4=5000000 столько импульсов придет на таймер за 1сек
; 5000000/256/256=76,2939453125 - это значение старшего программного байта таймера 0
; где 256 - прескалер и еще 256 - переполнение таймера 0
; берем ближнее значение = 76. На него и будем проверять наш программный старший байт
; Тогда кол-во импульсов равно: 76*256*256=4980736
; а реальный таймаут  получится следующим: 4980736/5000000=0,9961472 сек
     MOVLW    76
     MOVWF    timer0h, ab        ; старший байт таймера 0 реализуем программой
     CLRF     TMR0L, ab      ; очищаем таймер 0
     MOVLW    0x47           ; прескалер=256, 8-ми битный режим, тактирование от Fosc=5МГц=20МГц/4
     MOVWF    T0CON, ab
     BSF      INTCON, TMR0IE, ab ; разрешаем прерывание от таймера 0
; если у нас необходимо использовать модули, прерывания которых описаны в регистрах PIR, PIE, IPR
; то необходимо разрешить и периферийные прерывания
     BSF      INTCON, GIE, ab         ; разрешаем глобальные прерывания    
     BSF      T0CON, TMR0ON, ab   ; старт таймера 0
Main_Loop:
; теперь начинается основной цикл микроконтроллера          
; вот такой он стал, при использовании системы прерываний
     CLRWDT                      ; сброс сторожевого таймера, обязательно, как минимум, раз в 2,3сек
     BRA      Main_Loop
END
;====================================================================================

 В следующем выпуске вернемся к рассмотрению периферийных модулей  микроконтроллера PIC18F452! Начнем рассматривать модуль UART.

Полный архив рассылки Вы можете прочитать на нашем сайте!  При любом опубликовании текстов данной рассылки ссылка на сайт http://www.2aplusa.ru обязательна!

Желаю Вам удачи! До скорой встречи!


С уважением, Алексей pont_a@mail.ru
Cайт разработчиков 2AplusA http://2aplusa.ru


В избранное