Timer/Counter ATmega8

Timer/Counter ATmega8

1) Giới thiệu các bộ Timer/Counter ATmega 8

Timer/Counter là các module độc lập với CPU, được dùng chủ yếu định thì (tạo khoảng trễ, đếm thời gian…) hoặc đếm sự kiện, ngoài ra còn được dùng băm xung PWM ( Pulse Width Modulation).

Timer/Counter0: là bộ định thời 8 bit với hai chức năng : tạo trễ và đếm sự kiện

Timer/Counter1: là bộ định thời 16 bit các chức năng:

Thiết kế 16 bit phân giải cao

Tạo tín hiệu PWM độc lập trên các chân OC1A( chân 15 ) và OC1B (chân 16)

Máy phát tần số

Bốn ngắt nguồn độc lập (TOV1, OCF1A, OCF1B, và ICF1)

Timer/Counter2: là bộ định thời 8 bit giống với Timer/Counter 0.

2) Cách sử dụng Timer/Counter

  • BOTTOM: Là giá trị thấp nhất mà Timer/Counter có thể đạt được mặc định là 0
  • MAX: Là giá trị lớn nhất mà thanh ghi đếm của Timer/Counter có thể chứa được. Ví dụ thanh ghi 8 bit: 255, thanh ghi 16 bit: 65535.
  • TOP: Là giá trị mà khi Timer/Counter đạt được sẽ thay đổi trạng thái. Giá trị TOP có thể thay đổi bằng cách thay đổi các bit điều khiển hoặc nhập gián tiếp thông qua thanh ghi.

2.1) Timer/Counter0:

  • TCNT0 (Timer/Counter Register): Là thanh ghi cho phép truy cập trực tiếp để đọc ghi giá trị.

1

  • TCCR0 (Timer/Counter Control Register): Điều khiển hoạt động T/C0.

2

  • Ba bit CS02,CS01, CS00: Chọn nguồn clock

3

  • TIMSK (Timer/Counter Interrupt Mask Register): Là thanh ghi mặt nạ ngắt  được dùng chung  cho các T/C trong Atmega 8.

4

  • Overflow: Là hiện tượng xảy ra khi bộ đếm trong thanh ghi đạt giá trị MAX rồi đếm thêm lần nữa.  BIT 0 – TOIE0  là bit cho phép ngắt khi tràn tại T/C0 được set lên 1.
  • TIFR (Timer/Counter Interrupt Flag Register): Là thanh ghi cờ nhớ cho tất cả các bộ Timer/Counter. BIT 0 – TOV0 là cờ nhớ chỉ thị ngắt tràn của Timer/Counter0. Khi có ngắt tràn xảy ra bit này tự động set lên 1.

5

2.1.1) Cách hoạt động T/C0

  • Khi có tín hiệu “ kích ” giá trị TCNT0 tăng lên một đơn vị, khi đạt mức MAX = 255 ( 8 bit) hoặc 65535 ( 16 bit ) tín hiệu kích tiếp theo TCNT0 về 0 và quá trình được lặp lại. Dựa vào tín hiệu kích và ngắt tràn ta tạo ra bộ định thời hoặc đếm sự kiện.Bộ định thời gianB1: Gán giá trị phù hợp TCNT0 để thực hiện phục vụ ngắt trànB2: Chia tần cho xung nhịp của T/C0. Set ba bit CS02, CS01, CS00Ví dụ : Nguồn nuôi Clock = 1Mhz, Prescaler = 1.  Cứ 1us T/C0 được    kích , TCNT0 tăng lên 1. Khoảng thời gian lớn nhất T/C0 = 256 x 1us = 256us < 1ms .Prescaler = 8 sau 8us TCNT0 tăng 1, khoảng thời gian lớn nhất T/C0 = 256 x 8 = 2048us > 1ms.

    Số lần bộ đếm = Thời gian cần định thời (us)/Prescaler => Giá trị set up TCNT0 = 256 – Số lần bộ đếm.

Ví dụ: Chương trình tạo trễ 4ms chớp tắt led tại PB0

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

void khoitao_gpio(void);

void khoitao_timer(void);

void blink_led(void);

int main(void)

{

       khoitao_gpio();

       khoitao_timer();

       sei();

    while(1)

    {

        //TODO:: Please write your application code

              blink_led();

       }

}

//PORT B – PORT C LA OUTPUT, MUC LOGIC KHI TAO 0

void khoitao_gpio()

{

       DDRB = DDRC = 0xFF;

       PORTB = PORTC = 0x00;

}

//CAI DAT THOI GIAN TRE 1MS

void khoitao_timer()

{

       TCCR0 |= (1<< CS01)|(1 << CS00);

       TCNT0 = 240;

       TIMSK |= 1<< TOIE0;

}

// CHOP TAT PB0

ISR(TIMER0_OVF_vect)

{

       PORTB ^=1;   

       TCNT0 = 240;

}

void blink_led()

{

       PORTC = 0x55;

       _delay_ms(500);

       PORTC = 0xAA;

       _delay_ms(500);     

}

Bộ đếm sự kiện

Cài đặt giá trị trong thanh ghi TCCR0, lựa chọn chế độ

Đếm “ cạnh lên” . TCCR0 = 1<<CS02 | 1<<CS01| 1<<CS00, cạnh xuống . TCCR0 = 1<<CS02 | 1<<CS01| 0<<CS00.

Ví dụ: Đếm số lần nhấn button 1 trên kit hiện thị theo mã BCD tại PORTB. Nhấn button 2 tắt hết led tại PORTB.

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

void khoitao_gpio(void);

void khoitao_timer(void);

void control_led(void);

int main(void)

{

       khoitao_gpio();

       khoitao_timer();

       sei();

    while(1)

    {

        //TODO:: Please write your application code

              control_led();

    }

}

void khoitao_gpio()

{

       DDRD  = 0x00;  // PORTD la input su dung 2 chan ngat.

       PORTD = 0xFF;  // Su dung dien tro keo tai INT1 va INT0

       DDRB  = 0xFF;  // PORTB la output

       DDRC  = 0xFF;  // PORTC la output

       PORTC = 0x00;  // Muc logic khoi tao la 0

}

void khoitao_timer()

{

        TCCR0 |= ( 1<< CS02)|(1<<CS01);

        TCNT0 = 0;

}

void control_led()

{

       if (TCNT0  > 10) TCNT0 = 0;

       PORTB =TCNT0;

       if(bit_is_clear(PIND,7)) TCNT0 = 0;

}

2.2) Timer/Counter 1

2.2.1 Các thanh ghi

Là bộ T/C0 16 bit đa chức năng, độ phân giải cao. Thanh ghi ( 16 bit ) tạo từ hai thanh ghi 8 bit H và L.

TCCR1A và TCCR1B (Timer/Counter Control Register): là 2 thanh ghi điều khiển độc lập hoạt động của T/C1. Các bit trong thanh ghi chọn:  mode, dạng sóng ( WGM ), bit quy định ngõ ra ( Compare Output Match ), bit chia prescaler ( Clock Select ).

6

7

Trong thanh ghi TCCR1B gồm ba bit CS10, CS11, CS12 làm nhiệm vụ chia tần.

8

TCNT1H và TCNT1L (Timer/Counter Register): Là 2 thanh ghi 8 bit tạo thành thanh ghi 16 bits TCNT1 cho phép bạn đọc và ghi giá trị trực tiếp.

9

OCR1A và OCR1B (Ouput Compare Register A và B): Trong lúc T/C hoạt động, giá trị thanh ghi TCNT1 tăng, giá trị này được liên tục so sánh độc lập với các thanh ghi OCR1A và OCR1B việc so sánh này trên AVR gọi là gọi là Ouput Compare. Khi giá trị so sánh bằng nhau thì 1 Match xảy ra tạo ra một ngắt hoặc 1 sự thay đổi trên chân OC1A/OC1B. Do đó ta có thể tạo hai kênh A và B PWM bằng T/C1.

10

ICR1 (InputCapture Register 1): Khi có 1 sự kiện trên chân ICP1 (chân 14 trên Atmega8), thanh ghi ICR1sẽ  cập nhật giá trị của thanh ghi đếm TCNT1. Một ngắt có thể xảy ra trong trường hợp này, vì thế Input Capture có thể được dùng để cập nhật giá trị TOP của T/C1.

11

TIMSK (Timer/Counter Interrupt Mask Register): TIMSK cũng được dùng để quy định ngắt cho T/C1, chú ý các bit từ 2 đến 5 của TIMS. Có tất cả 4 loại ngắt trên T/C1  trong khi T/C0 chỉ có 1 loại ngắt tràn (TIMER0 OVF).

12

Bit 2 – TOIE1: Bit quy định ngắt tràn cho thanh T/C1( TIMER1 OVF), phải được set lên 1.

Bit 3-OCIE1B là bit cho phép ngắt khi có 1 match xảy ra ( TIMER1 COMPB ) trong việc so sánh TCNT1 với OCR1B.

Bit 4-OCIE1A là bit cho phép ngắt khi có 1 match xảy ra ( TIMER1 COMPBA) trong việc so sánh TCNT1 với OCR1A.

Bit 5-TICIE1 là bit cho phép ngắt trong trường hợp Input Capture được dùng (TIMER1 CAPT).

TIFR (Timer/Counter Interrupt Flag Register): là thanh ghi cờ nhớ cho tất cả các bộ T/C. Các bit từ 2 đến 5 trong thanh ghi này là các cờ trạng thái của T/C1.

13

2.2.2 Các mode Timer/Counter 1

Normal mode

          Thanh ghi đếm TCNT1 được tăng giá trị từ 0 (BOTTOM) đến 65535 hay 0xFFFF (TOP) và quay về 0. Set các bit Clock Select (CS12, SC11, CS10) trong thanh ghi TCCR1B.

Ví dụ: Viết chương trình chớp tắt led tại PORT C chu kỳ 500 ms và chớp tắt led tại PORB.0 chu kỳ 4s.

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

volatile uint8_t temp;

void khoitao_gpio(void);

void khoitao_timer(void);

int main(void)

{

       khoitao_gpio();

       khoitao_timer();

    while(1)

    {

        //TODO:: Please write your application code

              PORTC ^= 0xFF;

              _delay_ms(500);

    }

}

void khoitao_gpio()

{

       DDRB = DDRC = 0xFF;

       PORTB = PORTC = 0;

}

//KHOI TAO TIMER PRESCALER = 8 , CLOCK = 8MHz

//CHOP TAT LED CHU KY 4S

void khoitao_timer()

{

       TCCR1B |= 1<<CS11;

       TCNT1 = 0;

       TIMSK |= 1<<TOIE1;

       sei();

       temp = 0;

}

ISR(TIMER1_OVF_vect)

{

       temp ++;

       if (temp >= 61)

       {

              PORTB ^= 1<<0;

              temp = 0;

       }

}

Clear Timer on Compare Match

Là chế độ xóa timer nếu xảy ra bằng trong sánh, gồm 2 mode 4 và mode 12. Nếu dùng để đếm sự kiện trên chân T1.

Mode 4: Giá trị TOP – OCR1A, TCCR1 =  (1<<WGM12)| (1<<CS12)|(1<<CS11). Dao động Clock ngoại , falling on T1. Vector ngắt TIMER1_COMPA_vect

Mode 12: Giá  trị TOP – ICR1, TCCR1 = (1<<WGM13)|(1<<WGM12 )|(1<<CS12)|(1<<CS11) . Dao động Clock ngoại , falling on T1. Vector ngắt TIMER1_CAPT_vect

14

15

16

CTC MODE 4: Chương trình đếm sự kiện nhấn button 2 lần sáng led tại PORTB.

 

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

volatile uint8_t temp;

void khoitao_gpio(void);

void khoitao_timer(void);

int main(void)

{

       khoitao_gpio();

       khoitao_timer();

    while(1)

    {

        //TODO:: Please write your application code

              PORTC ^= 0xFF;

              _delay_ms(500);

    }

}

//PORT B = PORT C- OUTPUT, PORT D – INPUT( DUNG CHAN T1- PD5)

void khoitao_gpio()

{

       DDRB = DDRC = 0xFF;

       DDRD = 0x00;

       PORTB = PORTC = 0;

       PORTD = 0xFF;

}

//DAO DONG THANH ANH BEN NGOAI, CHE DO DEM CANH XUONG CHAN T1

//SAU KHI NHAN BUTTON 2 LAN TAI T1 SE THONG BAO SANG LED PORTB

void khoitao_timer()

{

       TCCR1B |=(1<<CS12) | (1<<CS11) | (1<<WGM12);

       OCR1A = 1;

       TIMSK |= 1<<OCIE1A;

       sei();

       temp = 0;

}

//GIOI HAN PORT B HIEN THI 0->10

ISR(TIMER1_COMPA_vect)

{

       temp ++;

       if (temp >= 11)

       temp = 0;

       PORTB = temp;

}

CTC MODE 12: Chương trình đếm sự kiện nhấn button 2 lần sáng led tại PORTB.

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

volatile uint8_t temp;

void khoitao_gpio(void);

void khoitao_timer(void);

int main(void)

{

       khoitao_gpio();

       khoitao_timer();

    while(1)

    {

        //TODO:: Please write your application code

              PORTC ^= 0xAA;

              _delay_ms(500);

              PORTC ^= 0x55;

              _delay_ms(500);

    }

}

//PORT B = PORT C- OUTPUT, PORT D – INPUT( DUNG CHAN T1- PD5)

void khoitao_gpio()

{

       DDRB = DDRC = 0xFF;

       DDRD = 0;

       PORTB = PORTC = 0;

       PORTD = 0xFF;

}

//DAO DONG THANH ANH BEN NGOAI, CHE DO DEM CANH XUONG CHAN T1

//SAU KHI NHAN BUTTON 2 LAN TAI T1 SE THONG BAO SANG LED PORTB

//CTC MODE 12

void khoitao_timer()

{

       TCCR1B |=(1<<WGM12) | (1<<WGM13) |(1<<CS11) |(1<<CS12);

       ICR1 = 1;

       TIMSK |= 1<< TICIE1;

       sei();

       temp = 0;

}

//GIOI HAN PORT B HIEN THI 0->10

ISR(TIMER1_CAPT_vect)

{

       temp ++;

       if (temp >= 11)

       temp = 0;

       PORTB = temp;

}

Fast PWM

PWM ( Pulse Width Modulation ) : Điều rộng xung , chu kỳ cố định duty cycle thay đổi được.

5

Một chu kỳ trong 1 lần đếm từ BOTTOM lên TOP (single-slope), có 5 mode Fast PWM tương ứng với cách chọn TOP khác nhau phụ thuộc vào setup 4 bit WGM và các bit chọn dạng xung ngõ ra Compare Output Mode trong thanh ghi TCCR1A.

7

Độ phân giải được điều chỉnh bởi hai thanh ghi ICR1 hoặc OCR1 theo công thức sau :

6

Ví dụ: Chương trình băm PWM tại PB0. Độ rộng xung chu kỳ 200ms.

#include <avr/io.h>

#include <util/delay.h>

void setup()

{

       //PWM cai dat

       TCCR1A =  (1<< COM1A1) | (1 << WGM10); // fast PWM mode 8-bit on OC1A

       TCCR1B =  (1<<WGM12 )  | (1<<CS11); // prescaling by 8

       //Initial value;

       OCR1A = 0x00;

       DDRB = 0xFF; // set port B for output

}

void pwmSet(int k)

{

 for ( int i = 0 ; i< k; i++)

 {

        OCR1A = i;

        _delay_ms(100);

 }

 for ( int i = k ; i>=0; i–)

 {

        OCR1A = i;

        _delay_ms(100);

 }

}

int main(void)

{

    setup();

       while(1)

       {

              pwmSet(200);

       }

}

Mô phỏng trên Proteus:

8

 

 

Đ/C: Ngách 30/18 Tạ Quang Bửu, Bách Khoa, Hai Bà Trưng, Hà Nội.

Điện Thoại: 043 2151 690 hoặc 0985 11 7969.

Website: linhkien360.vn

SupportTeam: linhkien360hotro@gmail.com

Linh kiện 360 luôn cam kết bán hàng tốt nhất !
Tags: , , , ,