Лекция 2. Прерывания
.pdfПредделитель частоты
Пример. Прерывание по переполнению
#include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h>
/* ISR = Interrupt Service Routine */ ISR(TIMER0_OVF_vect) {
PORTB ^= (1<<PB5);
}
int main(void) {
volatile uint8_t a = 0;
TIMSK0 = (1<<TOIE0); /* прерывание по переполнению счётчика */ TCCR0A = 0;
TCCR0B = (1<<CS02)|(1<<CS00); /* Предделитель 1:1024 */ TCNT0 = 0; /* Сбрасываем счётный регистр */
DDRB = (1<<DDB5); PORTB = 0;
sei(); /* разрешаем прерывания */ while (1) { a++; }
return 0;
}
Пример. Прерывание по сравнению
ISR(TIMER0_COMPA_vect) { PORTB ^= (1<<PB5);
}
int main(void) {
volatile uint8_t a = 0;
TIMSK0 = (1<<OCIE0A); /* включаем прерывания по сравнению */ TCCR0A = (1<<WGM01); /* Включаем режим CTC */
TCCR0B = (1<<CS02)|(1<<CS00);
OCR0A = 127; /* TOP Value, по достижении которого будет прерывание */
TCNT0 = 0;
DDRB = (1<<DDB5); PORTB = 0;
sei();
while (1) { a++; } return 0;
}
Внешние прерывания от линии
●Позволяют мгновенно реагировать на изменение уровня на линии порта МК, могут использоваться вместо явного опроса нажатых кнопок, если таковых не много
●От линии могут быть следующие прерывания:
–По высокому/низкому уровню
–По нарастанию
–По спаду
–По изменению уровня
Прерывания INT0, INT1
Прерывания по изменению уровня
●Одно прерывание и один обработчик используется сразу для 8 линий, обозначенных как PCINTn
PCIE0 – линии PCINT[7:0]
PCIE1 – линии PCINT[15:8]
PCIE2 – линии PCINT[23:16]
Какой ноге соответствует какой PCINT? – смотри цоколевку в Datasheet на Мегу 328p
PCMSKn
●Это маски, включающие/выключающие отдельную линию по каждому прерыванию PCINTn (n=0,1,2)
Пример.
/* header-ы те же */ ISR(PCINT1_vect) {
/* Будем реагировать только по фронту */ if (PINC & (1<<PC0)) {
PORTB ^= (1<<PB5);
}
}
int main(void) {
DDRB = (1<<DDB5); DDRC = 0;
/* включим прерывание PCINT8 по изменению уровня на PC0 */ PCMSK1 = (1<<PCINT8);
PCICR = (1<<PCIE1);
PORTB = (1<<PB5); /* Set active */ sei();
while (1) {
__asm__ ("nop");
}
return 0;
}
Задания
1)Моргать светодиодом по переполнению таймера
2)Самостоятельно разобраться и запустить 16-битный TIMER1, повторить на нём задание из предыдущего занятия (800,2*400, 4*200мс)
3)Сделать старт/стоп процесса моргания по кнопке