Бывает так, что нужно прервать выполнение программы на некоторое время (например по переполнению таймера, по нажатию кнопки и т.д.). Ниже приведена картинка, позволяющая очень хорошо ориентироваться в прерываниях: • GIE — бит включения прерываний • PEIE — бит включения прерываний от периферии • T0IE — прерывание по переполнению TMR0 • INTE — прерывание по изменению состояния пина В0 • RBIE — прерывание по изменению состояния пинов потра В0 • T0IF — флаг переполнения таймера TMR0 • INTF — флаг изменения состояния В0 • RBIF - флаг изменения хотя бы одного из пинов порта В
Периферию описывать не буду, все понятно из картинки.
Есть такое правило: Каждая переменная, которая используется в main() и в процедуре прерываний должна быть объявлена как «volatile»
Дело в том, что компилятор создает временную копию в регистре, во время прерывания переменная меняет свое значение в ОЗУ, но в регистре остается старое значение. Объявив переменную volatile, все будет происходить как задумано.
В этом примере я это использовать не буду, а просто выдам на порт В5 импульсы с частотой 500 Гц, используя прерывания переполнения таймера TMR0. #include #define _XTAL_FREQ 4000000 #define tmr0presc 0x02 #define period 125 __CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS & HS); void main() { __delay_us(500); TRISB = 0b00001111; PORTB = 0; OPTION &= 0b11000000; OPTION |= tmr0presc; T0IE = 1; GIE = 1; TMR0 = 255 - period + 1; for (;;) { } } interrupt isr() { if (T0IF) { TMR0 = 255 - period + 1; RB5 = !RB5; T0IF = 0; } } Осциллограма с мк, одно деление — 0.5 мс.
Источник: http://diymicro.ru/?p=65 |