|
Использование таймера
Использование таймера TMR0, TMR1 и TMR2. Использование прерываний, объявление новых функций
(Example №1)
В данном примере показано практическое использование различных таймеров и прерывания. Таймер TMR0 используется с предварительным делителем (коэффициент деления показан в примере). Прерывание происходит каждый раз в результате переполнения регистра таймера. При каждом прерывании автоматически увеличивается переменная cnt на 1. Когда значение cnt достигает 400, порт B увеличивается на 1. Вся процедура осуществляется независимо от основной программы, что позволяет микроконтроллеру выполнять иные процедуры.
/*Header******************************************************/
unsigned cnt; // Определение переменной cnt
void interrupt() {
cnt++; // В случае прерывания увеличить cnt на
TMR0 = 96; // Возврат TMR0 в начальное состояние
INTCON = 0x20; // Бит T0IE установлен, bit T0IF очищен
}
void main() {
OPTION_REG = 0x84; // Назначение предделителя для TMR0
ANSEL = 0; // Порты I/O настроены как цифровые
ANSELH = 0;
TRISB = 0; // Все входы порта B настроены на вывод
PORTB = 0x0; // Сброс порта B
TMR0 = 96; // TMR0 считает от 96 до 255
INTCON = 0xA0; // Разрешить прерывания по TMR0
cnt = 0; // Установить переменную cnt в ноль
do { // Бесконечный цикл
if (cnt == 400) { // После 400 прерываний…
PORTB = PORTB++; // Увеличить число в порте B на единицу
cnt = 0; // Сбросить переменную cnt
}
} while(1);
}
|
В этом примере прерывание разрешено после переполнения таймера TMR1 (TMR1H, TMR1L).
/*Header******************************************************/
unsigned short cnt; // Определение переменной cnt
void interrupt() {
cnt++ ; // В случае прерывания cnt увеличить на 1
PIR1.TMR1IF = 0; // Сброс бита TMR1IF
TMR1H = 0x80; // TMR1H и TMR1L возвращены
TMR1L = 0x00; // в их начальное состояние
}
void main() {
ANSEL = 0; // Порты I/O настроены как цифровые
ANSELH = 0;
PORTB = 0xF0; // Начальное состояние порта B
TRISB = 0; // Все входы порта B настроены на вывод
T1CON = 1; // Установка TMR1
PIR1.TMR1IF = 0; // Сброс бита TMR1IF
TMR1H = 0x80; // Установить начальное состояние для TMR1
TMR1L = 0x00;
PIE1.TMR1IE = 1; // Разрешить прерывания по переполнению
cnt = 0; // Сброс переменной cnt
INTCON = 0xC0; // Разрешить прерывания (биты GIE and PEIE)
do { // Бесконечный цикл
if (cnt == 76) { // Изменить состояние порта B после 76 прерыванийs
PORTB = ~PORTB; // Число в порте B инвертировать
cnt = 0; // Сброс переменной cnt
}
} while (1);
}
|
В этом примере прерывание разрешено после переполнения таймера TMR2. Показано каким образом можно создать новую функцию.
/*Header******************************************************/
unsigned short cnt; // Определение переменной cnt
void Replace() {
PORTB = ~PORTB; // Определение новой функции ‘Replace’
} // Функция инвертирует состояние порта B
void interrupt() {
if (PIR1.TMR2IF) { // Если TMR2IF = 1,
cnt++ ; // Увеличить cnt на 1
PIR1.TMR2IF = 0;// Сброс бита и
TMR2 = 0; // Сброс регистра TMR2
}
}
// main
void main() {
cnt = 0; // Сброс переменной cnt
ANSEL = 0; // Порты I/O настроены как цифровые
ANSELH = 0;
PORTB = 0b10101010; // Логические состояния линий порта B
TRISB = 0; // Все входы порта B настроены на вывод
T2CON = 0xFF; // Установить таймер T2
TMR2 = 0; // Начальное состояние регистра TMR2
PIE1.TMR2IE = 1; // Разрешить прерывания
INTCON = 0xC0; // Установить биты GIE и PEIE
while (1) { // Бесконечный цикл
if (cnt > 30) { // Изменить состояние порта И после 30 прерываний
Replace(); // Выполнение функции ‘Replace’
cnt = 0; // Сброс переменной cnt
}
}
}
|
|
|
|