Lập Trình Timer Với Vi điều Khiển - Univ.Tech Hơn Cả Thực Hành

1.  Lập trình timer/counter trong 8051

1.1.      Mục tiêu

Tìm hiểu và lập trình chế độ Timer/Counter trong 8051.

1.2.      Giới thiệu timer/counter

1.2.1.          Khái niệm

Trong vi điều khiển 8051 có 2 bộ Timer/Counter (T/C) có chức năng đếm xung.

Chế độ timer:

  • Đếm xung nội lấy từ mạch dao động bên trong vi điều khiển có chu kỳ ổn định.
  • Ứng dụng: thường dùng để xác định thời gian chính xác để điều khiển các thiết bị theo thời gian.

Chế độ counter:

  • Đếm xung nhận từ bên ngoài đưa đến ngõ vào T0 với T/C0 và ngõ T1 đối với T/C1.

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig1

Hình 1: AT89C52 trong Proteus

  • Ứng dụng: có thể sử dụng vi điều kiển để làm các mạch đếm sản phẩm.

Chú ý:

  • Tại mỗi thời điểm, ta chỉ sử dụng được 1 trong 2 hoặc là timer hoặc là counter.
  • Số lượng xung mà timer/counter có thể đếm được nhiều nhất từ 0 đến 65535 đếm theo giá trị thập phân, 0000H đến FFFFH đếm theo số thập lục phân.
  • Khi đến giá trị cực đại FFFFH và nếu có thêm 1 xung nữa thì bộ đếm sẽ bị tràn và giá trị đếm sẽ tự động nhảy về 0000H.

1.2.2.          Các thanh ghi trong timer/counter

Thanh ghi TH0, TL0, TH1, TL1:

  • Dùng để lưu trữ các giá trị đếm được của bộ timer/counter.
  • TH0, TL0: lưu giá trị timer/counter 0.
  • TH1, TL1: lưu giá trị timer/counter 1.
  • Độ rộng mỗi thanh ghi là 8 bit.

Thanh ghi TMOD:

  • Thiết lập chế độ hoạt động cho chân T0 và T1.
  • Gồm 2 nhóm 4 bit:
    • 4 bit thấp: thiết lập chế độ hoạt động cho T0.
    • 4 bit cao: thiết lập chế độ hoạt động cho T1.

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig2

Hình 2: 4 bit thấp và 4 bit cao trong thanh ghi TMOD

Chức năng của các bit trong thanh ghi TMOD được thể hiện qua hình sau:

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig3

Hình 3: Chức năng của từng bit trong TMOD

Trong đó, 2 bit M0 và M1 tạo ra 4 trạng thái tương ứng với 4 kiểu làm việc khác nhau của T0 và T1.

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig4

Hình 4: Các trạng thái làm việc của T0 và T1

MODE 0: Mode timer 13 bit

  • Sử dụng 8 bit cao của thanh ghi TH0 (TH1) và 5 bit thấp của thanh ghi TL0 (TL1) để lưu trữ các giá trị đếm của bộ timer/counter.
  • Như vậy ta có thể đếm từ 0 đến 213 = 8192 giá trị xung ở chế độ MODE 0.

MODE 1: Mode timer 16 bit

  • Sử dụng 2 thanh ghi 8bit TH0 (TH1) và TL0 (TL1) để lưu trữ các giá trị đếm.
  • Ở chế độ này, ta có thể đếm từ 0 đến 216 = 65536 giá trị.

MODE 2: Mode timer tự động nạp 8 bit

  • 8 bit của thanh ghi TL0 (TL1) dùng để đếm giá tri của bộ timer/counter.
  • 8 bit của thanh ghi TH0 (TH1) dùng để lưu giá trị nạp lại vào thanh ghi TL0 (TL1).

Ví dụ:

  • Khi thanh ghi TL0 = FFh.
  • Thanh ghi TH0 = 89h.
  • Khi đếm tiếp 1 lần giá trị nữa thì TL0 sẽ đếm bắt đầu từ 89h thay vì đếm lại từ 00h.

 MODE 3: Mode tách timer

  • Chỉ làm việc ở Timer 0.
  • 2 thanh ghi 8 bit TL0 và TH0 hoạt động riêng lẻ và quay trở về giá trị 00h khi bị tràn.
  • Sử dụng TF0 và TF1 làm các bit cờ tràn tương ứng.

Thanh ghi TCON:

  • Chứa các bit trạng thái và điều khiển cho T0 và T1.
  • Gồm 8 bit có chức năng như hình sau:

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig5

Hình 5: 8 bit của thanh ghi TCON

  • Bit TF1 (TF0): cờ tràn Timer 1 (0).
    • TF1 = 1 khi bộ đếm timer 1 (0) bị tràn.
  • Bit TR1 (TR0): điều khiển Timer 1 (0) đếm hoặc ngừng.
    • TR1 (TR0) = 1: cho phép Timer 1 (0) đếm xung.
    • TR1 (TR0) = 0: cho phép Timer 1 (0) ngừng đếm xung.
  • Bit IE1 (IE0): Cờ báo ngắt INT1 (INT0).
    • IE1 (IE0) = 1 khi có xảy ra ngắt xảy ra ở ngõ vào INT1 (INT0).
  • Bit IT1 (IT0): Bit điều khiển cho phép ngắt IT1 (IT0) tác động bằng mức hay cạnh.
    • IT1 (IT0) = 1 ngắt tác động bằng cạnh xuống.
    • IT1 (IT0) = 0 ngắt tác động bằng mức.

1.3.      Lập trình timer

Tạo hàm delay_ms bằng chế độ Timer.

1.3.1.          Code trên Keil C

Cách 1: Sử dụng giá trị thanh TL0 và TH0 bắt đầu từ 0000h.

#include"REGX52.h" //////////////////////////////////////////////////////////////// // Function: Delay_ms // Operation: Dùng lệnh while để đếm 1000 lệnh trong 1 ms // Parameters: t // Return: Không // Note: Sử dụng thạch anh 12Mhz để vi điều khiển thực hiện được 106 // lệnh trong 1 s (1000 lệnh trong 1 ms). // void Delay_ms1_timer0(unsigned int t) { unsigned int cnt = 0; while(t != 0) { TL0 = 0; TH0 = 0; TR0 = 1; // bat dau dem xung while(cnt <= 1000) { cnt = TH0; cnt <<= 8; cnt |= TL0; } TR0 = 0; t--; } //////////////////////////////////////////////////////////////// // Function: Cài đặt MOD 1 chi timer 0 // Operation: Dùng toán tử “ & ” và “ | ” để cài đặt // Parameters: Không // Return: Không // Note: Không // // Void Set_timer0_MOD1() { TMOD & = 0xF0; // xoa cac bit dieu khien cua TMOD T TMOD | = 0x01; // chon MOD 1 cho timer0 } } void main() { Set_timer0_MOD1(); while(1) { P2_0 = !P2_0; Delay_ms1_timer0(1000); } }

Cách 2: Sử dụng giá trị 2 thanh ghi TH0 và TL0 đếm 1000 lệnh từ FC18h đến 0000h. Và thiết lập thanh ghi cờ TF0 = 1.

#include"REGX52.h" //////////////////////////////////////////////////////////////// // Function: Delay_ms // Operation: Khi TF0 = 1 thì không đếm nữa // Parameters: t // Return: Không // Note: Sử dụng thạch anh 12Mhz để vi điều khiển thực hiện được 106 // lệnh trong 1 s (1000 lệnh trong 1 ms). // void Delay_ms2_timer0(unsigned int t) { while(t != 0) { TL0 = 0x18; // xoa cac bit luu tru trong TL0 vaf TH0 TH0 = 0xfc; TR0 = 1; // bat dau dem xung while(TF0 == 0); TR0 = 0; TF0 = 0; t--; } } //////////////////////////////////////////////////////////////// // Function: Cài đặt MOD 1 chi timer 0 // Operation: Dùng toán tử “ & ” và “ | ” để cài đặt // Parameters: Không // Return: Không // Note: Không // // void Set_timer0_MOD1() { TMOD &= 0xF0; // xoa cac bit dieu khien cua TMOD T) TMOD |= 0x01; // chon MOD 1 cho timer0 } void main() { Set_timer0_MOD1(); while(1) { P2_0 = !P2_0; Delay_ms2_timer0(1000); } }

1.4.      Lập trình counter

Đếm xung đưa vào ngõ T0 và hiển thị giá trị lên LED 7 thanh.

1.4.1.          Mô phỏng trên Proteus

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig6

Hình 6: Mô phỏng đếm xung trên Proteus

 

1.4.2.          Code trên Keil C

#include<REGX52.h> #include"lib\delay.h" unsigned char code7seg[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //////////////////////////////////////////////////////////////// // Function: Display // Operation: Hiện thị 4 LED 7 thanh để đếm xung // Parameters: n // Return: Không // Note: Không // void Display( unsigned int n) { unsigned char ngan, tram, chuc, donvi; ngan = n/1000; n %= 1000; tram = n/100; n% = 100; chuc = n/10; donvi = n%10; P2= ~code7seg[ngan]; P3_0 = 0; delay_ms(10); P3_0 = 1; P2= ~code7seg[tram]; P3_1 = 0; delay_ms(10); P3_1 = 1; P2= ~code7seg[chuc]; P3_2 = 0; delay_ms(10); P3_2 = 1; P2 = ~code7seg[donvi]; P3_3 = 0; delay_ms(10); P3_3 = 1; } //////////////////////////////////////////////////////////////// // Function: Cài đặt counter0 và bắt đầu đếm xung // Operation: Dùng thanh ghi điều khiển TMOD để cài đặt // Parameters: Không // Return: Không // Note: Không // void counter0() { TMOD& = 0xF0; TMOD| = 0x05; TR0 = 1; } void main() { unsigned int cnt; counter0(); while(1) { cnt = TH0; cnt <<= 8; cnt |= TL0; Display(cnt); } }

Kết quả mô phỏng:

[20161212] TÀI LIỆU LẬP TRÌNH - LẬP TRÌNH TIMER-COUNTER _v2_Fig7

Hình 7: Kết quả mô phỏng trên Proteus

Share this:

  • X
  • Facebook
Like Loading...

Related

Từ khóa » đếm Xung 8051