Читайте также:
|
|
У МК Atmega8 два внешних прерывания - INT0 и INT1. Эти прерывания жестко «привязаны» к выводам PD2 и PD3, и переназначить их на другие выводы нельзя.
Для настройки этих прерываний нужно воспользоваться регистрами MCUCR (MCU Control Register - регистр управления) и GICR (General Interrupt Control Register - общий регистр управления прерываниями). Рассмотрим их подробней.
MCUCR
GICR
Также любое прерывание имеет свой флаг прерывания. Этот флаг устанавливается в "1" в момент, когда должно произойти прерывание, даже если прерывания глобально запрещены и соответствующая программа обработки прерывания не вызывается. Можно, например, внутри какого-нибудь обработчика прерывания по этому флагу проверять было ли какое-либо прерывание или нет. Флаги внешних прерываний являются 7-м и 6-м битом регистра GIFR. Флаги прерываний сбрасываются записью в них "1".
GIFR
Вот собственно и все, что нужно знать чтобы настроить внешние прерывания. Рассмотрим на примере, что нужно записать в регистры MCUCR и GICR, чтобы настроить внешние прерывания. Мы хотим настроить вызов обработчика прерывания INT1 при установлении "0" на входе INT1(низкий уровень импульса). Согласно таблице 2 нужно установить в "0" биты ISC11 и ISC10 регистра MCUCR, а по таблице 1 бит INT1 регистра GICR. Таким образом, MCUCR = 0b00000000 и GICR = 0b10000000.
Настроим внешние прерывания в Atmel studio 6.0. Чтобы вызвать обработчик конкретного прерывания, нужно воспользоваться макросом ISR и указать ему в качестве параметра вектор нужного прерывания. Внешнему прерыванию INT1 соответствует вектор INT1_vect. В блоке инициализации устанавливаем регистры MCUCR и GICR, после этого вызываем функцию sei(). Ещё нужно подключить файл avr/interrupt.h.
Код будет выглядеть следующим образом:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
ISR(INT1_vect) //обработка прерывания
{
_delay_ms(50); //антидребезг контактов
//код выполняющийся в прерывании
}
void INTinit() //функция инициализация внешнего прерывания
{
MCUCR = 0b00000000;
GICR = 0b10000000;
}
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF; //настраиваем вывод на вход
DDRD &= ~(1 << PD3); //включаем подтягивающий резистор
PORTD |= (1 << PD3);
INTinit();//вызываем функцию инициализации прерывания
sei();
PORTB = 0b00000000; //устанавливаем бит глобального разрешения прерываний
while(1)
{
//код программы
}
}
ФАКУЛЬТЕТ ВНЕБЮДЖЕТНОЙ ПОДГОТОВКИ
Дата добавления: 2015-01-07; просмотров: 27 | Поможем написать вашу работу | Нарушение авторских прав |