Thứ Hai, 28 tháng 3, 2016

Bài 6: Timer/Counter với 8051

 

Chào các bạn!

     Hôm nay, mình xin giới thiệu với các bạn cách cấu hình và sử dụng bộ Timer/Counter với 8051.
     Bộ Timer/Counter trong 8051 có thể được sử dụng trong rất nhiều ứng dụng như đếm sự kiện (Counter)  trên chân T0(P3.4), T1(P3.5), sử dụng tạo hàm delay với độ chính xác cao, sử dụng tạo tín hiệu PWM, sử dụng ngắt timer để quét led 7 thanh...
     Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng timer trong 8051 ở chế độ counter và sử dụng timer để tạo hàm delay. Ứng dụng tạo PWM sử dụng timer mình sẽ đề cập trong một bài viết khác.

I. Các thanh ghi điều khiển bộ Timer/Counter trong 8051.

1. Thanh ghi TMOD.

     Cả hai bộ Timer/Counter(bộ T/C) 0 và 1 của 8051 đều sử dụng chung thanh ghi TMOD để thiết lập các chế độ hoạt động của bộ T/C. Thanh ghi TMOD là thanh ghi 8 bit, có 4 bit thấp dành cho bộ T/C0 và 4 bit cao dành cho bộ T/C1
Hình 1.1: Thanh ghi TMOD.
     Ý nghĩa các bit trong thanh ghi TMOD như sau.
GATE: GATE = 1: Bộ T/C được cho phép hoạt động khi chân INTx ở mức cao và bit TRx trong thanh ghi TCON được set lên 1. (x: 0 hoặc 1).
             GATE = 0: Bộ T/C được cho phép hoạt động khi bit TRx trong thanh ghi TCON được set lên 1.
CT: CT = 1: Chức năng counter được chọn.
       CT = 0: Chức năng timer được chọn.
M1, M0: 2 bit chọn các chế độ hoạt động của T/C.

M1                 M0                    Mode                                           Mô tả

0                      0                         0             Chế độ định thời 13 bit, 8 bit THx, 5 bit TLx

0                      1                         1             Chế độ định thời 16 bit.

1                      0                         2             Chế độ 8 bit tự nạp lại.

1                      1                         3             Chế độ bộ định thời chia tách.

2. Thanh ghi TCON.

Hình 1.1: Thanh ghi TCON.
     Thanh ghi TCON có 4 bit cao chứa các bit điều khiển và các bit cờ báo trạng thái của các bộ T/Cx.
     Ý nghĩa 4 bit cao của thanh ghi TCON như sau.

TF1: Cờ báo tràn bộ T/C1.
TR1: Bit điều khiển khởi động hoặc dừng bộ T/C1.
TF0: Cờ báo tràn bộ T/C0.
TR0: Bit điều khiển khởi động hoặc dừng bộ T/C0.

3. Thanh ghi chứa giá trị THx, TLx.

     Cả hai bộ T/C (T/C0 và T/C1) đều có các thanh ghi chứa giá trị bao gồm 16 bit, nhưng được truy cập theo 2 byte, byte cao THx và byte thấp TLx.
     Đối với bộ T/C0 thì 2 byte của thanh ghi chứa giá trị là TH0 và TL0, tương tự đối với T/C1 là TH1 và TL1.

II. Cấu hình Timer/Counter hoạt động ở chế độ counter.

     Sau đây mình sẽ hướng dẫn các bạn cấu hình bộ timer/counter 0 trong 8051 để thực hiện bài toán đếm xung cạnh xuống (falling edge) trên chân T0 và hiển thị số đếm lên LCD1602.
     Sơ đồ mạch mô phỏng như sau.
Hình 2.1: Sơ đồ mạch mô phỏng.
     Các bước cấu hình cho timer/counter 0 như sau.
1. Ghi vào thanh ghi TMOD để chọn chế độ Counter, chọn mode (8bit hoặc 16bit hoặc 13bit). Ở đây mình sẽ chọn chế độ counter nên sẽ set bit C/T=1, Mode 16 bit: M1 = 0, M0 = 1. ==>Giá trị ghi vào TMOD là 0x05. (Chỉ sử dụng Timer 0).
2. Set bit TR0 (TR0 = 1) để cho phép timer 0 hoạt động.
3. Lấy giá trị trong thanh ghi TL0, TH0 và lưu và trong một biến 16 bit và sau đó hiển thị lên LCD.

     Đoạn code trong chương trình main được viết như sau.

 

 /*Cau hinh Timer0 che do counter*/
 TMOD = 0x05; //CT=1, M1=0, M0=1. Couter, Mode 16bit
 /*Enbale Timer0*/
 TR0 = 1;
 /*Init LCD*/
 lcd1602_init();
 lcd1602_clear();
 lcd1602_gotoxy(0,0);
 lcd1602_puts("COUNTER USE 8051");
 lcd1602_gotoxy(0,1);
 lcd1602_puts("COUNTER=");
 while(1)
 {
  /*Doc gia tri tu TH0 va TL0*/
  low_byte = TL0;
  high_byte = TH0;
  bt_num=(high_byte*256)+low_byte;
  sprintf(lcd_buff,"%d",bt_num);
  lcd1602_gotoxy(9,1);
  lcd1602_puts(lcd_buff);
  
 }
 

     Trong đoạn code trên, các bạn thấy chỉ có 2 dòng lệnh sử dụng cho việc cấu hình Timer 0.
TMOD = 0x05;
TR0 = 1;
     Trong vòng lặp while(1), giá trị của thanh ghi TL0, TH0 liên tục được cập nhật và đưa vào biến bt_num, sau đó được hiển thị lên LCD.
     Các bạn có thể download source code và mô phỏng Tại Đây để tham khảo.
     Pass giải nén: dientu79.blogspot.com
     Hãy Like Fanpage để cập nhật thông tin bài viết mới nhất.

III. Cấu hình Timer/Counter hoạt động ở chế độ counter.

     Tiếp theo, mình sẽ hướng dẫn các bạn sử dụng T/C 0 của 8051 để sử dụng chức năng định thời. Mình sẽ dùng bộ T/C0 để viết một chương trình con delay.
     Nguyên tắc hoạt độn của bộ timer/counter ở chế độ timer như sau. 
     Khi bit TR của bộ T/C được set, bộ T/C sẽ được cho phép hoạt động, và cứ mỗi xung nhịp clock thì giá trị của thanh ghi chứa giá trị TH0, TL0 tăng lên 1(bắt đầu từ giá trị được cài đặt, mặc định là 0). Phụ thuộc vào mode hoạt động (8bit, 13bit, hay 16bit) mà giới hạn tràn của thanh ghi chứa giá trị là khác nhau. 
     Với mode 8bit, chỉ có thanh ghi TL được sử dụng để định thời, thanh ghi TH được sử dụng để ghi giá trị khởi tạo, và mỗi khi thanh ghi TL bị tràn (vượt quá 255) thì giá trị trong thanh ghi TH được tự động load vào thanh ghi TL. Vậy nên chế đọ này được gọi là 8 bit tự nạp lại.
     Với mode 16 bit, thì cả 2 thanh ghi TL và TH đều sử dụng chứa giá trị của T/C. Và khi T/C tràn (giá trị TH,TL vượt quá 65535) thì sẽ được reset về 0 và đồng thời cờ báo tràn TF được bật. Vậy nên sau khi tràn, phải khởi tạo lại giá trị cho TH,TL để có được thời gian định thì mong muốn.
     Mode 13 bit tương tự mode 16 bit.
     Các bước cấu hình cho bộ T/C0 hoạt động cở chế độ timer (định thời) như sau.
1. Ghi vào thanh ghi TMOD để chọn chế độ timer, chọn mode: Ví dụ ở đây mình chọn chế độ timer (C/T = 0) và mode 16 bit (M1=0, M0=1), mình sẽ ghi giá trị 0x01 vào TMOD (TMOD = 0x01).
2. Ghi vào thanh ghi TL0, TH0 các giá trị để tạo ra giá trị định thời mong muốn. Ví dụ mình muốn định thời 1ms (với thạch anh 12MHz), mình sẽ ghi vào thanh ghi giá TH, TL giá trị (65536 - 1000 =64536). Vì với thạch anh 12MHz, xung nhịp của 8051 là 1/12 của tần số thạch anh là 1MHz. Tương ứng với một xung nhịp là 1us, do vậy để có thời gian 1ms = 1000us, mình cần cho bộ T/C đếm 1000 lần. Mình gán giá trị 64536 bởi vì sau 1000 lần tăng giá trị thì T/C sẽ tràn và khi đó cờ TF sẽ bật lên 1. Chỉ cần kiểm tra cờ TF là mình biết đã đủ 1ms hay chưa. 

3. Set thanh ghi TR để cho phép bộ T/C hoạt động.
4. Kiểm tra cờ TF để biết bộ T/C đã tràn hay chưa.
5. Khởi tạo lại giá trị cho các thanh ghi TH,TL để chuẩn bị cho lần chạy tiếp theo.

Chương trình con delay_1ms được viết như sau.
 

 /*Ham delay su dung timer*/
 void delay_1ms(void)
 {
  TMOD = 0x01;   //Timer 0, mode 16 bit
  /*Gan gia tri 64536 cho thanh ghi TH0, TL0*/
  TL0 = 0x18;    //byte thap cua gia tri 64536
  TH0 = 0xFC;    //byte cao cua gia tri 64536
  TF0 = 0;       //xóa co bao tran TF0
  TR0 = 1;       //Cho phep timer 0 hoat dong
  while(TF0 == 0); //Cho cho bo timer tran
  TR0 = 0;   //Ngung timer 0
 }
 

     Đoạn chương trình trên khá đơn giản, Sau khi khởi tạo chọn chế độ cho thanh ghi TMOD. Giá trị 64536 được gán vào TL0 và TH0. 64536 là một số 16bit nên chúng ta cần tách ra 2 byte thấp và cao để đưa vào các thanh ghi TL0, TH0 tương ứng. Sau đó xóa cờ báo tràn và cho phép timer chạy bằng lệnh TR0 = 1; Câu lệnh while(TF0 == 0); sẽ chờ cho đến khi timer tràn (65536). Như vậy từ 65534 đến 65536 bộ timer đã tăng 1000 giá trị, mỗi lần tăng một giá trị là 1 xung nhịp clock (chu kỳ 1us). Như vậy khi gọi chương trình trên, mất 1ms=1000us thì mới thoát khỏi được chương trình.
     Trong các bài tiếp theo mình sẽ trình bày ngắt timer để quét led 7 thanh và sử dụng timer để tạo PWM điều khiển động cơ.
     Hãy Like Fanpage để cập nhật thông tin bài viết mới nhất.
Website được thực hiện bởi: cửa hàng linh kiện điện tử Đức Long https://muabanlinhkien.net/

Không có nhận xét nào:
Write nhận xét