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