
- •Введение.
- •1.1. Основные характеристики.
- •1.2. Структурная схема микроконтроллера.
- •1.3. Блоки памяти.
- •1.4. Регистры состояния и управления.
- •1.5. Порты ввода-вывода.
- •2.0.Функциональные модули микроконтроллера pic16f873.
- •2.1. Таймеры.
- •2.1.2. Модуль таймера tmr1.
- •2.1.3. Модуль таймера tmr2.
- •2.2. Модуль сср.
- •2.2.2. Режим сравнения.
- •2.2.3. Режим широтно-импульсного преобразователя (шим).
- •2.3. Модуль ацп.
- •2.3.1.Работа модуля осуществляется в следующей последовательности:
- •2.3.2.Временные требования к работе модуля ацп.
- •2.3.4. Последовательность преобразования аналогового сигнала.
- •2.3.5. Выравнивание результата преобразования.
- •2.3.6. Работа модуля ацп в sleep режиме.
- •2.3.7. Пример программирования модуля ацп.
- •2.4.Универсальный синхронно – асинхронный приемопередатчик (usart).
- •2.4.1.Режим асинхронного полного дуплекса.
- •2.4.1.1. Асинхронный передатчик usart.
- •2.4.1.2. Асинхронный приемник модуля usart.
- •2.5.Модуль ведущего синхронного последовательного порта (mssp).
- •2.5.1. Режим ведомого i2c.
- •2.5.1.1.Прием данных.
- •2.5.1.2. Передача данных.
- •2.5.1.3.Поддержка общего вызова.
- •2.5.1.4.Работа в sleep режиме.
- •2.5.2. Режим ведущего i2c.
- •2.5.3. Подключение абонентов к шине i2c.
- •2.6. Прерывания.
- •2.7. Сторожевой таймер.
- •2.8. Система команд микроконтроллера.
- •Incf Прибавить 1 к содержимому регистра f.
- •Incfsz Прибавить 1 к регистру f, пропустить, если 0.
- •Iorlw Побитное «или» регистра w и константы k.
- •Iorwf Побитное “или» регистров w, f.
- •Xorlw Побитное «Исключающее или» константы и регистра w.
- •Xorwf Побитное «исключающее или» регистров w,f.
2.6. Прерывания.
В микроконтроллерах PIC16F873 (PIC16F876) реализованы 14 источников прерывания. Источниками прерываний могут быть как внутренние устройства (память, функциональные блоки), так и внешние устройства, формирующие сигналы прерывания в виде сигнала INT на входе RB0 или в виде перепада уровня сигналов на входах RB4…RB7. Структурная схема системы прерываний приведена на рис.26 Как видно из схемы, прерывания от всех источников возникают после установки соответствующего флага (сигналы флагов оканчиваются символом F). Установка флага в каждом устройстве производится после готовности устройства к обслуживанию его процессором. Все прерывания могут быть замаскированы (отменены) путем установки в 0 соответствующего сигнала (сигналы маски оканчиваются символом E). Все без исключения прерывания могут быть замаскированы сигналом GIE (установкой его в 0), кроме того прерывания от функциональных модулей могут быть замаскированы сигналом PEIE.
Флаги и маски прерываний хранятся в регистрах INTCON, PIE1, PIR1, PIE2, PIR2. При разработке подпрограмм обслуживания прерываний необходимо помнить, что при переходе на подпрограмму в стеке сохраняется только адрес возврата, поэтому, при необходимости, надо позаботиться о сохранении содержимого некоторых ключевых регистров, например, рабочего регистра W и регистра состояния процессора STATUS.
Пример программы с использованием прерывания.
Принципиальная схема примера показана на рис.26
Распределение сигналов по выводам микроконтроллера для основной программы:
Таблица 28
Обозначение сигнала |
Р1 |
Р2 |
Р3 |
Р4 |
Р5 |
Кп |
Наименование вывода МК |
RB0 |
RB1 |
RB2 |
RB3 |
RB4 |
RC0 |
Распределение выводов микроконтроллера для фоновой программы:
Таблица 29
Обозначение сигнала |
HL1 |
HL2 |
HL3 |
HL4 |
HL5 |
HL6 |
HL7 |
Наименование вывода МК |
RD0 |
RD1 |
RD2 |
RD3 |
RD4 |
RD5 |
RD6 |
Определение загрузочных данных таймера TMR1.
Общее время интервала составляет 2 сек, или 2 000 000 мксек. Максимальный интервал таймера TMR1 при F osc = 4 мггц составляет 65536 мксек, при включенном предделителе 1:8 интевал будет равен 65536* 8 = 524 288 мксек. Поэтому для получения требуемой задержки понадобится четыре цикла срабатывания таймера, что обеспечит задержку на 524 288*4= 2 097 152 мксек, т.е таймер совместно с предделителем должен компенсировать:
2 097 152 – 2 000 000 = 97 152 / 4 = 24288 мксек, или после предделителя:
24 288 / 8 =3036 мксек. После перевода в 16-ричную систему получим 0ADC.
Рис. 26. Принципиальная схема примера.
Краткое описание эксперимента.
В основной части программы работы устройства контролируется включение электромагнитного пускателя Кп путем решения булевых уравнений (см. раздел работы портов микроконтроллера).
В фоновой части программы, работающей в режиме обслуживания прерывания от таймера TMR1, осуществляется включение индикаторов HL1...HL7 в соответствии с таблицей 30. Индикаторы подключены к выводам порта D микроконтроллера PIC16F887.
Таблица 30
Номер варианта |
Состояние HL1 |
Состояние HL2 |
Состояние HL3 |
Состояние HL4 |
Состояние HL5 |
Состоян. HL6 |
Сост. HL7 |
1 |
+ |
- |
- |
- |
- |
- |
- |
2 |
|
+ |
- |
- |
- |
- |
- |
3 |
+ |
+ |
- |
- |
- |
- |
- |
... |
... |
... |
... |
... |
... |
... |
... |
127 |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
128 |
- |
- |
- |
- |
- |
- |
- |
Примечание 1. Знак «+» означает, что индикатор включен, знак « - « выключен.
2. Интервал между переключением вариантов – 2 сек.
Текст программы.
#define XTAL_FREQ 4MHZ
#define byte unsigned char
#define word unsigned int
#include <pic.h>
#include <stdio.h>
__CONFIG(HS & WDTDIS & PWRTEN & LVPDIS & DUNPROTECT & PWRTEN);
char schet; // счетчик циклов срабатывания таймера
unsigned nchar girl; // счетчик вариантов переключений индикаторов
interrupt isr(void);
main()
{
ANSELH = 0; // настройка порта B в цифровой режим
TRISB = 0xFF; // настройка порта В вход
TRISC = 0xFE; //настройка вывода RC0 порта С на выход
OPTION = 0x00; // подключение подтягивающих резисторов,
TRISD = 0x00; // настройка порта D на выход
T1CON = 0x31; //включение TMR1, предделитель 1:8
schet =0x04; // первичная установка счетчика циклов таймера
girl = 0x00; //первичный сброс счетчика вариантов
TMR1IF =0; // сброс флага таймера
TMR1H = 0x0A; //запись в счетчик старших разрядов таймера
TMR1L = DC; //запись в счетчик младших разрядов таймера
TMR1IE=1; //разрешение прерывания от таймера TMR1
PEIE=1; // разрешение прерывания от функциональных модулей
GIE=1; // разрешение глобального прерывания
// основная программа
for(;;) { // цикл всей программы
RC0 = (RB0&&RB1&&RB2&&RB4) || (RB0&&RB2&&!RB3&&RB4);
}
} // конец main
interrupt isr(void)
{
schet --;
if (!schet)
{ schet = 4; girl ++; PORTD = girl; }
TMR1H = 0x0A;
TMR1L = 0xDC;
TMR1IF = 0;
} //выход из прерывания