Работа прерывания по таймеру микроконтроллера Atmega8.

Сегодня мы рассмотрим работу прерывания которое будет срабатывать по счетчику. В качестве примера возьмем 16 битный счетчик ( 8 битные на много проще и на них мы не сможем реализовать длительные паузы между прерываниями).

Параметры счетчика:

Регистр TCCR1A служит для задания режимов работы таймера/счётчика 1:

COM1A1, COM1A0,  COM1B1, COM1B0 — настраивают поведение выводов OC1A и OC1B.

FOC1A, FOC1B — принудительное изменение состояния выходов OC1A и OC1B.

WGM11, WGM10 — настраивают TC1 для работы в режиме ШИМ.

Регистр TCCR1B служит для задания режимов работы таймера/счётчика 1:

CS10, CS11, CS12 — выбор частоты тактирования TC1.

WGM13 и WGM12 — служат для настройки ШИМ.

Биты WGM13 (4) , WGM12 (3) регистра TCCR1B и биты WGM11 (1) , WGM10 (0) регистра TCCR1A устанавливают режим работы таймера/счетчика T1:

  • 0000 — обычный режим
  • 0001 — коррекция фазы PWM, 8-бит
  • 0010 — коррекция фазы PWM, 9-бит
  • 0011 — коррекция фазы PWM, 10-бит
  • 0100 — режим счета импульсов (OCR1A) (сброс при совпадении)
  • 0101 — PWM, 8-бит
  • 0110 — PWM, 9-бит
  • 0111 — PWM, 10-бит
  • 1000 — коррекция фазы и частоты PWM (ICR1)
  • 1001 — коррекция фазы и частоты PWM (OCR1A)
  • 1010 — коррекция фазы PWM (ICR1)
  • 1011 — коррекция фазы и частоты PWM (OCR1A)
  • 1100 — режим счета импульсов (ICR1) (сброс при совпадении)
  • 1101 — резерв
  • 1110 — PWM (ICR1)
  • 1111 — PWM (OCR1A)
ICNC1 — задерживает определение события, происходящего на входе ISP1 на 4 машинных цикла.
ICES1 — настраивается фронт срабатывания прерывания по захвату. При установки в 1 — нарастающий фронт, 0 -спадающий фронт.
 
TIMSKрегистр маски прерываний таймеров 
OCIE2 — прерывание в случаи совпадения TC2
 TOIE2 — прерывание в случае переполненияTC2
TICIE1 — прерывания в случае захвата TC1
OCIE1A -прерывание в случаи совпадения A TC1
OCIE1B -прерывание в случаи совпадения B TC1
TOIE1 — прерывание в случае переполненияTC1
OCIE0 — не используется
TOIE0 — прерывание в случае переполненияTC0
 
TIFRрегистр флагов прерывания таймеров/счетчиков. 

OCF2 —  флаг прерывания по событию «совпадение» таймера Т2
TOV2 — флаг прерывания по переполнению таймера Т2
ICF1 -флаг прерывания по событию «захват» таймера Т1.
OCF1A —  флаг прерывания по событию «совпадение А» таймера Т1
OCF1B — флаг прерывания по событию «совпадение В» таймера Т1
TOV0 — флаг прерывания по переполнению таймера Т0
 

TCNTxH и TCNTxL — старший и младший счетный байт.

Необходимо учитывать, что записывать данные в счетный байт необходимо с старшего разряда, а потом младший. Менять последовательность нельзя.

В нашей программе, при переполнении счетчика будет отрабатывать прерывание, как следствие будут переключаться светодиоды на ножках D0 и D1.

И прежде чем приступить к написанию программы необходимо указать тип прерывания которое мы будем использовать, хи много, мы пока укажем то которое нам в данный момент нужно:TIMER1_COMPA_vect — прерывание по совпадению.

Программа:

#include <avr/io.h> 
#include <avr/interrupt.h>
#define HL1_on PORTD|=(1<<PD0)
#define HL1_off PORTD&=~(1<<PD0)
#define HL2_on PORTD|=(1<<PD1)
#define HL2_off PORTD&=~(1<<PD1)
unsigned char i =0;
unsigned char n =0;
ISR (TIMER1_COMPA_vect){// прерывание по таймеру
i++;
if(i==1){
n=0;
}else{
n=1;
i=0;
}
}
int main(void) { /* Replace with your application code */
DDRD =0b0000011; //ножки D0-D1 выход
PORTD =0b1111100;// ножки D0-D1 – настроены на 0
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
TIMSK |= (1<<OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
//62500
OCR1AH = 0b11110100; //записываем в регистр число для сравнения
OCR1AL = 0b00100100;
TCCR1B |= (1<<CS11)|(1<<CS10);//установим делитель. 80000000/64=125000кГц
//1/125000=8*10-7с * 62500 = 0,5с
sei();
while (1) {
if (n==0){HL1_on;HL2_off;}
if (n==1){HL2_on;HL1_off;}
}
}