Содержимое файла «Blinks.Asm»
;-------------------------------;
Blinks: ; функция мерцания светодиодов
B2: call Dellay_1s ; задержка на 1с
B3: call Leds_Off ; потушить все светодиоды
B4: call Dellay_4s ; задержка на 4с
return ; команда возврата
;-------------------------------;
Содержимое файла «Lab_10.asm»
; Lab_10
;-------------------------------
#include<p17С756А.inc> ; подключение заголовочного файла
; для МК 1886ВЕ2У 16F877
#include”Dellay_1s.asm” ;
#include”Dellay_4s.asm” ;
#include”Blinks.asm” ;
;-------------------------------
_250mcs EQU 0x20 ;
_250mls EQU 0x21 ;
cntr_1s EQU 0x22 ;
cntr_4s EQU 0x23 ;
;-------------------------------
org 0x00 ; начало памяти программ (ПП)!
goto main ; произвести переход на метку 'main',
; с которой начнётся выполнение
; основной программы
org 0x05 ; адрес начала размещения кода в ПП
;-------------------------------; фунция расчёта 1-го уравнения
;------ Функции программы ------;
;-------------------------------;
Init_PORTB: ; настройка PORTB
IB2: bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
IB3: clrf PORTB ; иниицализация защёлки PORTB
IB4:
BANKSEL TRISB ; выбрать банк для TRISB
movlw B'00000011' ; значение для инициалищации
; направления каналов
movwf TRISB ; установка битов PORTB:
; бит: 0,1 - на вход
; бит: 2,3,4,5,6,7 - на выход
return ; команда возврата
;-------------------------------;
Init_PORTC: ; настройка PORTC
IC2: bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
IC3: clrf PORTC ; иниицализация защёлки PORTC
IC4:
BANKSEL TRISC ; выбрать банк для TRISC
movlw B'11111100' ; значение для инициалищации
; направления каналов
movwf TRISC ; установка битов PORTC:
; бит: 0,1 - на выход
; бит: 2,3,4,5,6,7 - на вход
return ; команда возврата
;-------------------------------;
Port_Status: ; функция проверки состояния:
; портов - B,C
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
P2: btfss PORTB,0 ; кнопка 1 нажата ?
goto P3 ; нет - проверяем кнопку 2
goto P4 ; да - проверяем кнопку 2
P3: btfss PORTB,1 ; кнопка 1 = 0; кнопка 2 - нажата ?
goto P7 ; нет - погасить оба
goto P6 ; да - зажечь светодиод 2
P4: btfss PORTB,1 ; кнопка 1 = 1; кнопка 2 - нажата ?
goto P5 ; нет - зажечь светодиод 1, 2 = 0
goto P7 ; да - погасить оба светодиода
P5: call Led_1_On ; зажечь светодиод 1, 2 - погасить
call Blinks ; начать мигание
goto P2 ; вернуться для проверки
P6: call Led_2_On ; зажечь светодиод 2, 1 - погасить
call Blinks ; начать мигание
goto P2 ; вернуться для проверки
P7: call Leds_Off ; погасить светодиоды
goto P2 ; вернуться для проверки
return ; команда возврата
;-------------------------------;
Led_1_On: ; функция зажигает светодиод 1
; и гасит светодиод 2
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
LA2: bsf PORTC,0 ; зажечь светодиод 1
bcf PORTC,1 ; погасить светодиод 2
return ; команда возврата
;-------------------------------;
Led_2_On: ; функция зажигает светодиод 2
; и гасит светодиод 1
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
LB2: bsf PORTC,1 ; зажечь светодиод 2
bcf PORTC,0 ; погасить светодиод 1
return ; команда возврата
;-------------------------------;
Leds_Off: ; функция гашения светодиодов
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
LO2: bcf PORTC,0 ; погасить светодиод 1
bcf PORTC,1 ; погасить светодиод 2
return ; команда возврата
;-------------------------------;
main: ; начало основной программы
A2: call Init_PORTB ; настройка порта B
A3: call Init_PORTC ; настройка порта C
A4: call Port_Status ; проверка состояния портов
goto main ; перейти на main
END
Контрольные вопросы!
1. Что такое порты ввода / вывода? Для чего они необходимы?
2. Назовите порты ввода / вывода, которые есть у данного МК? Что в них особенного?
3. Какие регистры отвечают за контроль и управление PORTA? Сколько битов в нём используется? Чем PORTA отличается от остальных? Приведите схему канала порта?
4. Назовите основные особенности PORTB? Как настроить необходимые биты PORTB на вход или выход? Опишите несколько возможных случаев применения PORTB на практике? Приведите схему канала порта?
5. Расскажите, что собой представляет двунаправленный порт ввода / вывода PORTC? Приведите схему канала порта?
6. Расскажите, что собой представляет двунаправленный порт ввода / вывода PORTD? Приведите схему канала порта?
7. Что собой представляет PORTE? Как на практике можно применить имеющиеся у него свойства? Для чего это нужно? Приведите схему канала порта?
8. *Объясните, чем характерна ситуация «чтение – модификация – запись» при использовании портов ввода / вывода. Почему так происходит? Как решить данную проблему несколькими способами? Ответы должны быть подкреплены соответствующими схемами.
9. *Расскажите о портах PORTF, PORTG, GPIO?
10. *Порты могут быть однонаправленными? *Для чего это нужно?
11. **Можно ли передать в МК требуемую информацию без применения портов ввода / вывода?
12. Что такое программная задержка? Как она влияет на работу МК?
13. Перечислите основные преимущества и недостатки организации временных задержек программным способом?
14. Назовите несколько примеров ситуаций, когда временная задержка необходима?
15. Зависит ли временная задержка от мощности процессора? Почему? Подкрепите ответ, обоснованными утверждениями!
16. Может ли одна и та же задержка во времени, организованная программно, одинаково длиться на процессорах с разной архитектурой? Ответ обоснуйте!
17. Можно ли организовать временную задержку аппаратным способом? Если да, то как? Назовите преимущества такого подхода?
Лабораторная работа № 11
Тема: Организация задержек во времени программно – аппаратным
способом. Обработка прерываний.
Цель: Научиться организовывать временные задержки в программе
аппаратным способом, и освоить механизм прерываний.
Задание:Реализовать две программно – аппаратные задержки, выполненные с помощью таймера и обработчика прерываний. Временные периоды использовать из лабораторной работы № 9. Продемонстрировать работоспособность программного обеспечения в симуляторе.
Время:Одно занятие.
Содержание отчёта:
· Тема, цель, задание;
· Расчёт временных задержек;
· Описание команд МК, необходимых для написания программы;
· Алгоритм (нумерованный);
· Описание к алгоритму, с подробным пояснением работы;
· Программ с метками соответствующими номерам блоков алгоритма;
· Код программы;
· Описание особенностей программы;
· «Копии экрана» симулятора, демонстрирующие правильную работу программно - аппаратных задержек;
· Вывод;
Теоретические сведения
Выполнив лабораторную работу – вы узнаете:
· Что такое таймер, и какими свойствами он обладает;
· Что такое прерывания и для чего они необходимы;
Небольшие устройства, которые способны производить контроль и управление, относятся к микроконтроллерам. В задачи, которые ставятся для таких устройств, очень часто необходимо - организовывать, контролировать, а также производить – временные задержки. Лабораторные работы 9, 10 показали один из вариантов организации задержек во времени, который не является самым лучшим, а скорее наоборот – привносит массу негативных моментов в вашу программу, что в корне снижает её эффективность.
Одним из вариантов решения всех проблем по организации необходимых по длительности задержек во времени, является, использование периферийного модуля, и называемого – таймер. Прелесть таймер в том, что – это аппаратное устройство, которое способно работать параллельно с самим МК. Изучаемая модель обладает тремя таймерами: TMR0, TMR1, TMR2.
TMR0 и TMR2 – это 8 разрядные таймеры / счётчики, каждый из которых обладает предделителем частоты, а также некоторыми особенностями, присущими, каждому из них. Максимальное значение, которое можно записать в 8 бит равно 255, что не очень много, поэтому останавливаться на их рассмотрении мы не станем. Вы всегда можете обратиться к документации и получить самостоятельно, нужную информацию.
TMR1 – это 16 разрядный таймер / счётчик, обладающий предделителем, а также двумя регистрами по 8 бит - TMR1H и TMR1L, в которые возможно записать число, равное 65535, что достаточно удобно, для организации требуемой аппаратной задержки. Его рассмотрение заслуживает внимания, поэтому мы им и займёмся.
Контролировать любой из таймеров можно самостоятельно, постоянно считывая значение информационных регистров, что не очень удобно. Наиболее удачным подходом, является, изучить механизм прерываний, чтобы использовать их для контроля таймера.
Таймер TMR1
TMR1 – 16 разрядный таймер / счётчик, который имеет память, представленную двумя регистрами по 8 разрядов – TMR1H и TMR1L, способных вместить значение равное 65 535. Можно использовать только младший регистр, то есть TMR1L, тогда таймер TMR1, ничем не будет отличаться от TMR0 и TMR2, которые являются 8 разрядными. Отсчёт всегда выполняется обязательно в двух регистрах TMR1H и TMR1L, которые являются спаренными. Любой из таймеров работает только на увеличение. Если в регистры счётчика, предварительно не было записано требуемое значение, и предделитель не был настроен должным образом, то по умолчанию, после запуска, счёт начинается с 0x00, увеличиваясь на каждом такте на ‘1’, до максимального значения – 0xFFFF (65 535). При нарушении границ максимального значении 0xFFFF (65 535) – происходит переполнение, и тогда счёт начинается с ‘0’. При переполнении счётчиков, флаг прерываний от таймера - TMR1IF - устанавливается в ‘1’.
Каждый из трёх таймеров обладает предделителем частоты. Такт таймера соответствует значению в 1 мкс. TMR0 и TMR2 – имеют разрядность 8 бит, что позволяет отсчитать на увеличение 255 мкс, после чего произойдёт сброс счётчика и счёт начнётся с ‘0’. TMR1– имеет разрядность 16 бит, что позволит отсчитать на увеличение 65 535 млс. Предделитель частоты, которым обладает каждый таймер, способен работать в 1 из 4 положений:
1) 00 = 1:1 – приращение происходит от каждого тактового сигнала;
2) 01 = 1:2 – приращение происходит от каждого 2 – го сигнала, то есть 1 пропускается;
3) 10 = 1:4 – приращение происходит на каждый 3 сигнал;
4) 11 = 1:8 – приращение происходит на каждый 4 сигнал;
Если взять значение TMR1, равное 50 млс, для простоты, и рассмотреть относительно коэффициентов, представленных выше, то получим следующую картину:
1) 00 = 50 * 1 = 50 млс;
2) 01 = 50 * 2 = 100 млс;
3) 10 = 50 * 4 = 200 млс;
4) 11 = 50 * 8 = 400 млс;
На рис.11.1 показана структурная схема TMR1 для ознакомления.
Рис.11.1 – структурная схема таймера TMR1
TMR1 может работать в 1 из двух режимов:
· Режим таймера;
· Режим счётчика;
В режиме таймера приращение происходит от внутреннего сигнала FOSC / 4, когда бит TMR1CS сброшен в ‘0’. В этом режиме бит синхронизации T1SYNC игнорируется, потому что внутренний тактовый сигнал всегда синхронизирован.
В режиме счётчика таймер может работать синхронно и асинхронно, в зависимости от состояния бита TMR1CS. Когда TMR1 использует внешний тактовый сигнал, приращение происходит по переднему фронту сигнала на выводе T1OSI (если T1OSCEN = ‘1’) или T1OSO / T1CKI (если T1OSCEN = ‘0’). Подробнее о режимах работы в синхронном и асинхронном режиме можно узнать из документации на МК. Схема приращения таймера при T1OSCEN = ‘1’ и T1OSCEN = ‘0’ представлена на рис.11.2.
Рис.11.2 – схема приращение таймера TMR1
Регистр настройки и управления таймером T1CON, представлен на рис.11.3.
Пример функции инициализации TMR1, представлен ниже:
; инициализация таймера TMR1 с внутренним тактовым сигналом
;-----------------------;
Init_TMR1:
clrf T1CON ; выключить TMR1, внутренний тактовый сигнал,
; генератор выключен, предделитель 1:1
clrf TMR1H ; очистить старший байт регистра TMR1
clrf TMR1H ; очистить младший байт регистра TMR1
clrf INTCON ; выключить прерывания
BANKSEL PIE1 ; выбрать банк для PIE
clrf PIE1 ; выключить периферийные прерывания
BANKSEL PIR1 ; очистить флаги периферийных прерываний
bcf T1CKPS1 ; установка предделителя в 1:1
bcf T1CKPS0 ;
return ; команда возврата
;-----------------------;
Рис.11.3 – регистр T1CON
Перед тем, как перейти к изучение механизма прерываний, обратите внимание на рис.11.4, где показаны регистры, связанные с работой таймера TMR1.
Рис.11.4 – регистры, связанные с работой таймера TMR1
Прерывания
Прерывание – это процесс, при котором, вновь поступившая информация, имеющая более высокий приоритет, должна быть немедленно обработана. Источниками прерываний могут быть:
· Внешний источник прерываний INT;
· Переполнение таймера TMR0;
· Изменение уровня сигнала на входах PORTB, выводы RB7:RB4;
· Изменение входного уровня компаратора;
· Прерывание от ведомого параллельного порта;
· Прерывания от USART;
· Прерывание от приёмника;
· Прерывание от передатчика;
· Завершение преобразования АЦП;
· Прерывания от LCD;
· Завершение цикла записи в EEPROM память данных;
· Переполнение таймера TMR1;
· Переполнение таймера TMR2;
· Прерывания от модуля CCP;
· Прерывания от модуля SSP;
Перед тем, как ознакомиться с регистрами управления прерываний, следует обратиться к лабораторной работе № 2 и рассмотреть рис.2.8. Также обратитесь к описанию того, по какому адресу следует размещать код в памяти программ. В лабораторной работе № 2, на рис.2.8 показано, что вектор прерываний размещён по адресу 0х04. С учётом того, во всех программах, имеющие в своей основе обработку прерываний, необходимо переписать участок разметки региона границ в памяти программ, следующим образом:
;-------------------------------;
org 0x00 ; начало памяти программ (ПП)!
goto main ; произвести переход на метку 'main',
; с которой начнётся выполнение
; основной программы
org 0x05 ; адрес начала размещения кода в ПП
org 0x04 ; адрес вектора прерываний
goto Int_TMR1 ; обработка прерывания от TMR1
;-------------------------------;
Когда возникает прерывание, происходит сброс указателя счётчика памяти программ, после чего он возвращается в исходное состояние, на адрес 0х00, откуда вновь начинается выполнение кода программы, после чего он доходит до адреса 0х04, означающего вектор прерываний. Если имеется обработчик прерываний, командой goto производится перехода на соответствующую метку, где начинается выполнение функции обработчика прерывания.
При помощи такого подхода, возможно, обработать прерывание от любого объекта, являющегося инициатором его вызова. Чтобы это сделать, достаточно знать бит, отвечающий за регистрацию прерывания. После чего при помощи команды btfsc или btfss произвести анализ, и перейти на соответствующую функцию, обработчика прерывания.
Допустим, необходимо, обрабатывать прерывания от 3-х таймеров, каждый из которых запускается в определённом случае, в соответствии алгоритма программы. Рисунки регистров управления прерываниями будут приведены чуть ниже, а пока, чтобы рассмотреть пример, отметьте для себя, что за переполнение TMR0 – отвечает бит T0IF, регистра INTCON. За переполнение TMR1 – отвечает бит TMR1IE, регистра PIE1, а за TMR2 – бит TMR2IE, того же регистра PIE1. Разметка региона области, размещения кода в памяти программ, с учётом обработчика, приобретёт иной вид:
;-------------------------------;
org 0x00 ; начало памяти программ (ПП)!
goto main ; произвести переход на метку 'main',
; с которой начнётся выполнение
; основной программы
org 0x05 ; адрес начала размещения кода в ПП
org 0x04 ; адрес вектора прерываний
IT2: btfsc INTCON,T0IF ; прерывание от TMR0 ?
goto Int_TMR0 ; да - обработка прерывания от TMR0
goto IT3 ; нет – проверить остальные
IT3: btfsc PIE1,TMR1IE ; прерывание от TMR1 ?
goto Int_TMR1 ; да – обработка прерывания от TMR1
goto IT4 ; нет – проверить остальные
IT4: btfcs PIE1,TMR2IE ; прерывание от TMR2 ?
goto Int_TMR2 ; да – обработка прерывания от TMR2
goto main ; нет – вернуться в начало программы
;-------------------------------;
Регистр INTCON является управляющим, содержит биты разрешений и флаги установки / запрета прерываний глобально. Флаги прерываний могут быть запрещены, но их регистрация будет всё равно происходить, вне зависимости от бита глобального разрешения. Подробное описание, в словесной форме, каждого регистра, отвечающего за контроль прерываний, приведено не будет. Рисунки, расположенные ниже, являются самодостаточным источником необходимой информации.
На рис.11.5 показана структурная схема логики прерываний. На рис.11.6 приведено описание регистра INTCON. На рис.11.7, 11.8 – описание регистра PIE1, PIE2, соответственно. На рис.11.9, 11.10 – описание регистров PIR1, PIR2, соответственно.
Рис.11.5 – структурная схема логики прерываний
Рис.11.6 – регистр INTCON
Рис.11.7 – регистр PIE1
Рис.11.8 – регистр PIE2
Рис.11.9 – регистр PIR1
Рис.11.10 – регистр PIR2
Следует учитывать несколько важных правил, относящихся к регистрам прерываний:
· Бит GIE, регистра INTCON при возникновении прерывания, автоматически сбрасывается в ‘0’.
· Для выхода из прерываний следует использовать команду – retfie, которая производит установку бита GIE в состояние ‘1’.
· Регистры PIE1, PIE2 – являются управляющими, а PIR1, PIR2 – регистрами контроля, каждый бит которых, играет роль флага. Это означает что, разрешить прерывание, можно, путём установки соответствующего бита в PIE1, PIE2, а контролировать его следует, проверкой требуемых битов в PIR1, PIR2. После прерывания от периферийного устройства, соответствующий флаг установится в состояние ‘1’. Необходимо самостоятельно сбросить флаг в состояние ‘0’, иначе, программа никогда не выйдет из обработчика прерываний.