AVR Timer/Counter Trên Atmega16, Code Demo - P2

TIMER là gì?

- Là một module độc lập với CPU.
- Chức năng: Đếm thời gian, đếm sự kiện, tạp xung PWM.

  1. TIMER0: 8bit
  2. TIMER1:16bit
  3. TIMER2: 8bit

Demo với TIMER0

Thanh ghi TCCR0: Thanh ghi điều khiển hoạt động của Timer/Counter0.

Thanh ghi TCNT0: Thanh ghi lưu giá trị đếm

  • x = Delta_T * F_CPU/Clock
  • TCNT0 = 255 - x;
Delta_T: Khoảng thời gian định thì, F_CPU: Tần số thạch anh, Clock: Bộ chia (prescaler)

Ví dụ: Giả sử ở đây mình dùng thạch anh là 8MHz Các bạn muốn định thời trong 1ms.
  • x = 0.001(1ms)  *  8000000 / clock(8/64/256/1024)
Các bạn hãy thử chia cho clock bằng 8 or 64 or 256 or 1024 nếu x < số bit( ở đây là 8bit = 255) và x là là số nguyên thì sẽ chính xác hơn. Mình sẽ thử chia cho 64.
  • x= 0.001 * 8000000 / 64 = 125 (125 < 255 => OK)
  • TCNT0  = 255 - 125 = 130

Thanh ghi TIMSK: thanh ghi mặt nạ ngắt dùng cho tất cả các Timer/Counter.

    - Nếu sử dụng mode Normal thì các bạn sử dụng bit TOIE0
    - Nếu sử dụng mode CTC thì các bạn sử dụng bit OICE0

Các bước khai báo

  • Bước 1: Xét mode hoạt động TCCR0
  • Bước 2: Lưu giá trị đếm TCNT0
  • Bước 3: Khai báo cờ ngắt (thanh khi TIMSK)
  • Bước 4: Gọi hàm #asm("sei") để cho phép ngắt toàn cục

Code

#include <mega16.h>
volatile unsigned long dem;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    TCNT0 = 130; // lưu giá trị đếm
    dem++;
}
void main(void)
{
    DDRA = (1<<DDA0);
    PORTA = (1<<PORTA0);
    TCCR0 = (1<<CS01)|(1<<CS00); //prescaler = 64
    TCNT0 = 130; // x= 0.001 * 8000000 / 64 = 125
                 // TCNT0  = 255 - 125 = 130 
    TIMSK |= (1<<TOIE0); // mode Normal, cho phép ngắt
    #asm("sei")
    while (1)
      {   
        if(dem==1000)// 1s
        {
            PORTA.0 = ~PORTA.0;
            dem=0; 
        }
      }
}

Demo

Nhận xét

Mới hơn Cũ hơn