Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекция 2. Прерывания

.pdf
Скачиваний:
37
Добавлен:
23.03.2016
Размер:
3 Мб
Скачать
☆

Предделитель частоты

Пример. Прерывание по переполнению

#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)Сделать старт/стоп процесса моргания по кнопке