Ngắt và xử lý ngắt trong 8051

Chào các bạn!

Hôm nay, mình xin giới thiệu đến các bạn cách cấu hình và sử dụng ngắt ngoài với VĐK 8051.

I. Các nguồn ngắt của VĐK 8051.

     

Vi điều khiển 8051 gồm có sáu nguồn ngắt như sau (Reset cũng là một nguồn ngắt).


II. Các thanh ghi điều khiển ngắt của 8051.

1. Thanh ghi cho phép ngắt/cấm ngắt IE (Interrupt enable).

Ngắt và xử lý ngắt trong 8051

Hình 2.1: Thanh ghi cho phép ngắt/cấm ngắt.

Ý nghĩa của các bit trong thanh ghi IE như sau.

EX0: Cho phép (EX0 = 1) hoặc cấm (EX0 = 0) ngắt ngoài 0.

ET0: Cho phép (ET0 = 1) hoặc cấm (ET0 = 0) ngắt timer 0.

EX1: Cho phép (EX1 = 1) hoặc cấm (EX1 = 0) ngắt ngoài 1.

ET1: Cho phép (ET1 = 1) hoặc cấm (ET1 = 0) ngắt timer 1.

ES: Cho phép (ES = 1) hoặc cấm (ES = 0) ngắt cổng nối tiếp.

ET2: Cho phép (ET2 = 1) hoặc cấm (ET2 = 0) ngắt timer 2.

EA: Cho phép (EA = 1) hoặc cấm (EA = 0) ngắt toàn cục. 

2. Thanh ghi TCON.

Thanh ghi TCON là thanh ghi có chứa các bit điều khiển hoạt động timer, các bit cờ báo tràn timer, các bit cấu hình ngắt kích phát mưc/kich phát sườn sử dụng cho ngắt ngoài. 

Ngắt và xử lý ngắt trong 8051

Hình 2.2: Thanh ghi TCON.

Ý nghĩa của các bit trong thanh ghi TCON như sau.

TF1: Cờ báo tràn của timer 1. Được set lên 1 khi timer 1 tràn và được xóa bởi phần cứng khi chương trình nhày vào trình phục vụ ngắt (chương trình ngắt).

TR1: bit điều khiển hoạt động của timer 1. TR1 = 1: timer 1 bắt đầu hoạt động, TR1 = 0: Dừng timer 1.

TF0: Tương tự TF1, nhưng sử dụng cho timer 0.

TR0: Tương tự TR1, nhưng sử dụng cho timer 0.

IE1: Cờ ngắt ngoài 1 kích phát sườn, được set lên 1 khi phát hiện có sườn xuống ngắt ngoài, và được xóa khi ngắt được xử lý.

IT1: Bit điều khiển kiểu ngắt ngoài 1. Có 2 kiểu ngắt ngoài là ngắt kích phát mức và ngắt kích phát sườn. Bit IT1 được sử dụng để chọn 1 trong 2 kiểu ngắt ngoài này cho ngắt ngoài 1. Khi IT1 = 0, ngắt ngoài 1 là ngắt kích phát mức, ngược lại IT1 = 1, ngắt ngoài 1 là ngắt kích phát sườn.

IE0: Tương tự IE1 nhưng sử dụng cho ngắt ngoài 0.

IT0: Tương tự IT1nhưng sử dụng cho ngắt ngoài 0.

III. Cấu hình ngắt ngoài cho 8051 sử dụng Keil C.

Sau đây, mình xin chia sẻ cách cấu hình ngắt ngoài cho 8051 trong Keil C.

Mình sẽ cấu hình sử dụng ngắt ngoài 0, đối với ngắt ngoài 1 các bạn có thể làm tương tự, chỉ khác nhau là thay đổi các bit cấu hình cho ngắt ngoài 0 sang ngắt ngoài 1.

Sơ đồ mô phỏng được cho như sau.

Ngắt và xử lý ngắt trong 8051

Hình 3.1: Sơ đồ mạch mô phỏng.

Đối với mạch điện như trên hình 3.1, mình sẽ viết chương trình sử dụng ngắt ngoài để đếm số trên led 7 thanh tăng giá trị từ 0 -> 9.

Như các bạn thấy nút nhấn được nối vào chân P3.2, do vậy mình sẽ sử dụng ngắt ngoài 0 (EX0=1).

Kiểu ngắt ở đây mình sử dụng ngắt kích phát sườn (IT0 = 1).

Để sử dụng ngắt, chúng ta cần thực hiện 2 công việc. 1 là cấu hình các thanh ghi cho phép sử dụng ngắt, và 2 là viết chương trình thực hiện ngắt.

Cấu hình các thanh ghi cho phép sử dụng ngắt được thực hiện trong chương trình chính. Để cấu hình cho phép sử dụng ngắt ngoài 0, kiểu ngắt kích phát sườn ta thực hiện như sau.

 

/*Cau hinh ngat ngoai 0*/
EX0 = 1; //cho phep ngat ngoai 0
IT0 = 1; //ngat kich phat suon
EA = 1;  //cho phep ngat toan cuc.
 

     

Trong chương trình ngắt, chúng ta sẽ thực hiện công việc tăng giá trị của biến đếm và kiểm tra biến đếm có bị tràn (lớn hơn 9) hay không. Chương trình ngắt được viết như sau

 

/*Chuong trinh phuc vu ngat ngoai 0*/
void ISR_EX0 (void) interrupt 0
{
 bt_num ++;
 if(bt_num > 9)
  bt_num = 0;
}
 
     

Công việc còn lại trong chương trình chính là xuất giá trị tương ứng với biến đếm bt_num ra led 7 thanh.

 

while(1)
 {
  /*Xuat gia tri ra led 7 thanh*/
  LED_PORT =  code_7_seg[bt_num];
 }
 
     

Các bạn có thể download source code và chương trình mô phỏng Tại Đây.
     Chúc các bạn thành công.

Bài 7: Lập trình ngắt vi điều khiển 8051
Đăng bởi: Vũ Văn Thái - Thời gian: 03-11-2013, 12:15
Chuyên mục: Học lập trình 8051 - Lượt xem: 22.987

Chào các bạn, do một thời gian bận làm mấy cái project lên hôm nay mình mới có thời gian viết bài, mong mọi người thông cảm.

Hôm nay chúng ta sẽ tìm hiểu về ngắt vi điều khiển, thực ra trên club đã có tài liệu rồi nhưng một số bạn vẫn còn bỡ ngỡ về viết code ntn thì hôm nay m sẽ hướng dẫn code và tìm hiểu xem ngắt là cái quái gì mà nó lại quan trọng vậy :)

Đầu tiên các bạn sẽ thắc mắc ngắt là gì.... nếu mà cứ theo cái định nghĩa của nó chắc chẳng ai hình dung rõ lên m sẽ chuẩn bị một ví dụ để minh họa cho cái định nghĩa thô cứng đó:

VD như bạn đang vặt rau sauđó rửa rau rùi cho vào luộc, công việc có vẻ rất trôi chảy nhưng trong lúc đang vặt rau bỗng nhiên mama gọi "Con ơi đi ra ngoài tạp hóa mua cho mẹ gói bột nêm" Thế là ngay lập tức bạn dừng công việc vặt rau lại cất gọn vào một chỗ nào đó rồi chạy ngay ra cửa hàng để mua đồ cho mẹ, khi bạn mua xong gói bột nêm về thì bạn lại quay lại công việc đang dang dở đó là vặt rau và cứ như vậy.......... =>> Đó chính là ngắt

Trong vi điều khiển cũng vậy, chương trình dc chạy từ trên xuống dưới trong hàm main() - Hàm ctr chính. Bình thường (đang vặt rau) thì như vậy nhưng khi có ngắt xảy ra (mẹ sai đi mua bột nêm), tức sẽ có ngoại lệ, sẽ ra lệnh cho VDK biết là đang có một ngắt xuất hiệu và yêu cầu VDK phải xử lý nó, thế là VDK bảo “Biết rồi khổ lắm nói mãi” rồi thực hiện xong nốt câu lệnh đang chạy dở =>> Cất dữ liệu địa chỉ của câu lệnh tiếp theo vào một chỗ nào đó gọi là ngăn xếp (ô nhớ trên RAM)  xong quay sang phục vụ chương trình ngắt (Chính là việc chạy đi mua bột nêm đó)  khi phục vụ xong rồi thì nó lại vào ngăn xếp lấy cái địa chỉ của ô nhớ tiếp theo cần được xử lý. Công việc của VDK là như vậy khi có ngắt xảy ra.

Bình thường thì vi điều khiển chỉ xử lý dc một lệnh duy nhất, thực hiện xong thì nhảy đến lệnh kế tiếp, ko có khái niệm 3 đầu 6 tay đâu nha chỉ làm dc duy nhất một việc trong 1 khoảng thời gian, đó chính là chu kì máy dc định bởi bộ dao động, thường thấy là thạch anh(như quả tim vậy nó mà ngừng đập là VDK sẽ chết), VDK sẽ chia 12 lần xung nhịp thạch anh để ra chu kì máy VD sd thạch anh 12Mhz thì ta có chu kỳ máy là 1us  (1/1.000.000 giây). Thế là đã hiểu sơ sơ rồi, thế là đủ cho ngôn ngữ C ko cần lắm quá nhiều về cấu trúc VDK lên việc học lập trình rất nhanh, tôi đảm bảo với bạn sẽ dễ hơn với ASM vì ASM là hợp ngữ còn C là ngôn ngữ bậc cao gần với con ng hơn.

Trước khi đi vào phần code ta sẽ tìm hiểu xem con VDK của ta có những gì để sài: Họ 8051 có tất cả 5 ngắt và 1 ngắt Reset và 2 bộ định thời Timer0 và Timer1, riêng chíp 8052 là có thêm Timer 2. Để lắm rõ hơn bạn vui lòng tải tài liệu về bộ định thời về ở trên club

Ngắt reset là ngắt phần cứng khi ta kích mức cao vào chân Reset, còn 5 ngắt kia gồm: Ngắt Timer0, Timer 1, Ngắt ngoài 0, Ngắt ngoài 1, Ngắt UART ta sẽ xét từng ngắt một:

-Ngắt timer: Cơ bản timer0 và timer1 như nhau chỉ khác khai báo lên nhóm chung vào một mục

Ta xét thanh ghi hoạt động của timer: Thanh ghi 8bit TMOD:

 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |

 Bôi đỏ là của Timer1 và còn lại là của Timer0, nhưng ta chỉ quan tâm tới bit M0 và M1 – đây là bit set chế độ hoạt động cho timer

M1 M0 Chế độ
0 0 Định thời 13bit
0 1 Định thời 16bit
1 0 Định thời 8bit tự nạp lại
1 1 Định thời chia sẻ

Nhưng để cho nhanh ta có thể khai báo tắt như sau:

TMOD=0x01; Tương đương TMOD=0000 0001 là chọn timer0 và chế độ 16bit

TMOD=0x10; Tương đương TMOD=0001 0000 là chọn timer1 và chế độ 16bit

TMOD=0x21; Tương đương TMOD=0010 0001 là chọn timer0 chế độ 16bit và timer1 chế độ 8bit nạp lại tự động

.v.v..

Thanh ghi TH0, TL0(timer0), TH1,TL1(timer1) nạp giá trị ban đầu để đếm, bộ định thời sẽ đếm lên 1 với mỗi chu kì máy, như vậy ta phải tính toán giá trị nạp vì khi bộ định thời tràn tức đã đếm đủ 8bit, 16bit thì ngắt mới xảy ra

Chú ý thanh ghi TH0, TH1 có tác dụng khi ở chế độ 16bit vì nó lưu 8bit cao 

Thanh ghi IE(thanh ghi khai báo ngắt) có 2 bit ET0 và ET1 tương ứng ngắt timer0 và ngắt timer1

Bảng vector ngắt:

0 - Ngắt ngoài 0

1 - Ngắt timer 0

2 - Ngắt ngoài 1

3 - Ngắt timer 1

4 - Ngắt UART truyền thông nối tiếp, sẽ nói ở bài sau

Khai báo ctr phục vụ ngắt trong C: void ten_ctr() interrupt "vector_ngắt" { //code ctr }

CODE mẫu ngắt timer:

sbit led=P3^0; //Khai bao chan gan led
void INT_Timer1()interrupt 3 {
          //ctr phuc vu ngat
          led=!led; //Dao bit
}
void main(){//ctr chinh
          TMOD=0x20;//Sd Timer1 che do 8bit tu nap lai (ngat timer)
          TH1=TL1=0x00;//Nap gia tri bat dau 8bit
          TR1=1;//Khoi dong timer1
          ET1=1;//Ngat timer1
          EA=1;//Cho phep ngat
          while(1){//vong lap vo tan
                    //code ctr
          }
}

Với timer0 tương tự nhưng phải khai báo lại TMOD, TH0, TL0, TR0, ET0

- Ngắt ngoài: Khác với ngắt timer, ngắt ngoài cho phép tác động từ bên ngoài cho lên ta sẽ có thêm một bit điều khiển đó là bit IT, IT0(chỉ ngắt ngoài 0) và IT1(chỉ ngắt ngoài 1)

+Khi IT0=1 ngắt sườn lên (logic 0 lên logic 1)

+Khi IT0=0 ngắt sườn xuống ( logic 1 xuống logic 0)

+IT1 tương tự

Thanh ghi ngắt IE có 2 bit EX0 và EX1 tương ứng với chọn ngắt ngoài 0 hay ngắt ngoài 1

Để sử dụng ngắt ngoài ta cần phải kết nối vào 2 chân cho phép ngăt là P3.2(INT0) và P3.3(INT1)

Code mẫu cho ngắt ngoài:

sbit led=P3^0; //Khai bao chan gan led
void INT0() interrupt 0 {
          //ctr phuc vu ngat ngoai 0, nhan nut de bat led
          led=1; //bat led
}
void main(){//ctr chinh
          led=0;//tat led
          EX0=1;//ngat ngoai 0
          EA=1;//Cho phep ngat
          while(1){//vong lap vo tan
                    //code ctr
          }
}

 Nếu bạn chưa hiểu về các thanh ghi trên thì vui lòng tải tài liệu về bộ định thời về để hiểu rõ hơn

http://sangtaoclub.net/tai-lieu.html

Chúc bạn học tốt!!!!!


Bài viết sửa lúc 13-08-2014, 11:53 bởi Vũ Văn Thái