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

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

.pdf
Скачиваний:
25
Добавлен:
23.03.2016
Размер:
2.94 Mб
Скачать

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

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

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