Страница в разработке
Таймер-счётчики, например в Atmega8 их три. Два 8-ми битных и один 16-ти битный:
TCn, где n - номер таймера, например:
TC0 - 8-ми битный таймер-счётчик
TC1 - 16-ти битный таймер-счётчик
Биты управления:
TCNTn - 8-ми разрядный счетный регистр таймера n, который увеличивает своё значение с тактовой частотой МК на единицу по кругу от 0 до 255
OCRn - регистр сравнения таймера n, где каждый такт происходит сравнение его с счётным регистром TCNTn. В случае равенства в следующем такте
устанавливается флаг OCF0 в соответствующем регистре флагов и, если разрешено, генерируется прерывание.
Также в этом случае может изменяться состояние вывода OC0 микроконтроллера.
OCRnA и OCRnB для 16-ти разрядных таймеров, т.е. для нулевого 8-ми битного таймера ATmega8: OCR0. Для первого 16-ти битного: OCR1A и OCR1B
OCR1AH хранит старшую часть числа для сравнения, а регистр OCR1AL — младшую, например:
OCR1AH = 0b10000000;
OCR1AL = 0b00000000;
Т.е. в регистр OCR1A записали число 0b1000000000000000, что соответствует десятичному числу 32768. Если микроконтроллер работает на частоте 8 МГц,
то 8000000/32768=244,14 - частота в Гц с которой будет работать таймер 1, что очень быстро, замедлим делителем на 256, т.е. примерно получим 1 Гц:
TCCR1B |= (1<<CS12);//установим делитель на 256 для таймера1
TCCRn (TCCRnA и TCCRnB) - (Timer/Counter Control Register) конфигурационный регистр для управлением таймером, биты:
CS02, CS01, CS00 (Clock Select) - определяют источник тактовой частоты для таймера Т0 и задают коэффициент предделителя:
0 0 0 - таймер выключен
0 0 1 - 1 к 1 (частота МК), например: TCCR0 |=(1<<0); //для Atmega 16 или TCCR0A |=(1<<0); //для Attiny2313
0 1 0 - 1 к 8 (частотам МК поделённая на 8)
0 1 1 - 1 к 64
1 0 0 - 1 к 256
1 0 1 - 1 к 1024
1 1 0 - внешний источник на выводе T0, срабатывание по заднему фронту импульса
1 1 1 - внешний источник на выводе T0, срабатывание по переднему фронту импульса
WGM01, WGM00 (Wave Generator Mode) - биты режима работы таймера-счетчика Т0:
0 0 - нормальный режим (normal)
0 1 - режим широтно-импульсной модуляции Phase Correct PWM
1 0 - сброс таймера при совпадении (CTC): TCCR0 |=(1<<WGM01); //сброс при совпадении
1 1 - режим широтно-импульсной модуляции FastPWM
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению) для Таймера 1
TIMSK (Timer/Counter Interrupt Mask Register) - общий регистр для всех таймеров, он содержит флаги разрешения прерываний. Для каждого таймера два бита
TOIE0 - прерывание по переполнению TCNT0, пример: TIMSK|=(1<<0);
OCIE0 - прерывание по событию (сравнению), пример: TIMSK|=(1<<0);
TIMSK |= (1<<OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
Прерывания будут вызываться, только если установлен бит глобального разрешения прерываний, команда: sei();// Set Interrupt
// Пример, прерывание при переполнении таймер-счётчика0
# define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER_OVF_vect){asm("nop")} // вектор при переполнении таймер-счётчика0
int main(void){
TCCR0 |=(1<<0); //частота 1 к 1
TCCR0 &=~(1<<WGM00);
TCCR0 &=~(1<<WGM01); //режим работы таймер-счётчика: нормальный
TIMSK |= (1<<0); //разрешить прерывание по переполнению для таймера-счётчика0
while(1) {asm("nop")}
}
// Пример, прерывание при совпадении таймер-счётчика0
# define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER_COMP_vect){asm("nop")} // вектор при совпадении таймер-счётчика0
int main(void){
TCCR0 |=(1<<0); //частота 1 к 1
TCCR0 &=~(1<<WGM00);
TCCR0 |=(1<<WGM01);//режим работы таймер-счётчика: сброс при совпадении
TIMSK |= (1<<1); //разрешить прерывание по совпадению для таймера-счётчика0
OCR0=200; //сбрасывать, когда будет = 200
while(1) {asm("nop")}
}// Пример, прерывание при совпадении с таймер-счётчиком1
#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//--------------------------------------------
unsigned char i;
//--------------------------------------------
void segchar (unsigned char seg){
switch(seg) {
case 1: PORTD = 0b11111001; break;
case 2: PORTD = 0b10100100; break;
case 3: PORTD = 0b10110000; break;
case 4: PORTD = 0b10011001; break;
case 5: PORTD = 0b10010010; break;
case 6: PORTD = 0b10000010; break;
case 7: PORTD = 0b11111000; break;
case 8: PORTD = 0b10000000; break;
case 9: PORTD = 0b10010000; break;
case 0: PORTD = 0b11000000; break;
}
}
//--------------------------------------------
void timer_ini(void){
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
TIMSK |= (1<<OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
OCR1AH = 0b01111010; //записываем в регистр число для сравнения
OCR1AL = 0b00010010;
TCCR1B |= (1<<CS12);//установим делитель на 256
}
//--------------------------------------------
ISR (TIMER1_COMPA_vect){
if(i>9) i=0;
segchar(i);
i ;
}
//--------------------------------------------
int main(void){
//unsigned char butcount=0, butstate=0;
timer_ini();
DDRD = 0xFF;
DDRB = 0x00;
PORTD = 0b11111111;
PORTB = 0b00000001;
i=0;
sei();
while(1){
}
}