NGẮT VÀ CÁC MỨC ƯU TIÊN NGẮT

<INTERRUPT AND INTERRUPT PRIORITY>

----------€-♫-€----------

        P89LPC922 dùng 4 mức ưu tiên ngắt, và có đến 12 nguồn ngắt khác nhau, điều này rất tiện lợi cho việc ta dùng chúng trong nhiều mục đích khác nhau.<bạn tham khảo các loại ngắt để lập trình trong thư viện Help của C51, File C51.chm>

            Mỗi nguồn ngắt có thể được cho phép/không cho phép bởi từng bit ngắt<với điều kiện ngắt chung-bit EA đã được chọn>

            Mỗi nguồn ngắt có thể được lập trình 1 trong 4 mức ưu tiên ngắt bằng cách định giá trị cho thanh ghi IP0-IP0H, IP1-IP1H <IP: Interrupt priority>, bảng dưới đây sẽ cho ta rõ hơn về điều đó: 

Bit ưu tiên ngắt

Mức ưu tiên ngắt

IPxH

IPx

0

0

Ưu tiên mức thấp nhất

0

1

Mức 1

1

0

Mức 2

1

1

Ưu tiên mức cao nhất

Chung về các loại ngắt:

Các loại ngắt

Cờ ngắt

Địa chỉ vectơ ngắt

Bit cho phép ngắt

Các bit điều khiển mức ưu tiên ngắt

Xếp hạng ưu tiên khi hỏi vòng

Khả năng wakeup nguồn khi Power Down

Ngắt ngoài 0

IE0

0003H

EX0(IEN0.0)

IP0H.0, IP0.0

1

Ngắt từ Timer 0

TF0

000BH

ET0(IEN0.1)

IP0H.1, IP0.1

4

Không

Ngắt ngoài 1

IE1

0013H

EX1(IEN0.2)

IP0H.2, IP0.2

6

Ngắt từ Timer 1

TF1

001BH

ET1(IEN1.3)

IP0H.3, IP0.3

8

Không

Ngắt từ thu phát nối tiếp

TI&RI

0023H

ES/ES(IEN0.4)

IP0H.4, IP0.4

11

Không

Ngắt từ thu nối tiếp

RI

Phát hiện sai mã

BOF

002BH

EB0(IEN0.5)

IP0H.5, IP0.5

2

Ngắt từ đồng hồ thời gian thực/ watchdog Timer

WDOVF/RTCF

0053H

EWDRT

(IEN0.6)

IP0H.6, IP0.6

3

Ngắt từ giao tiếp I2C

SI

0033H

EI2C(IEN1.0)

IP1H.0, IP1.0

5

Không

Ngắt bàn phím

KBIF

003BH

EKBI(IEN1.1)

IP1H.1, IP1.1

7

Ngắt từ bộ so sánh

CMF1/CMF2

0043H

EC(IEN1.2)

IP1H.2, IP1.2

9

Ngắt từ cổng phát nối tiếp

TI

006BH

EST(IEN1.6)

P1H.6, IP1.6 

10

Không

 Lưu ý: Xem lại cách định thanh ghi SSTAT khi ngắt từ truyền/thu/hoặc truyền-thu nối tiếp.

            Xem hình dưới đây để ta hình dung một cách rõ ràng hơn về các loại ngắt của P89LPC922:

 

Lập trình ngắt ngoài:

Ví dụ:  Viết code cho PLC922 dùng ngắt ngoài.

Các bước tiến hành:

Khai báo dùng chương trình ngắt(Enable các bit EA và EX0 hoặc/và EX1)à Khai báo chân dùng cho ngắt (khởi tạo trị cho pin P1.4(ngắt ngoài 1) hoặc P1.3(Ngắt ngoài 0))àViết chương trình ngắt. Để tiện dụng, ta viết bằng C (mặc định dùng trong uV3-Keil for 8051)

 

Ví dụ: Viết chương trình sử dụng ngắt ngoài 0.

//Using C language, Keil for 8051 programmer, pin P1.3=EX_INT

//Hieu, Bui-trung, last modified on 9/10/2005 at 7:54:53 PM 

#include <reg922.h>

// define pin names  <EX0>

sbit EX_INT0 = P1^3;

 

void ports_init(void)   

{

//Port P0 (push-pull)

  P0M1 &= 0x00;

  P0M2 |= 0xFF;

//EX_INT0 is input pin(only)

  P1M1 |= 0x28;

  P1M2 &= 0xD7;

} // ports_init, review in last my paper or P89LPC922 datasheet. 

 

//Interrupt function

void EX0_isr(void) interrupt 0 using 1

{

    //process here

    //Disable external interrupt bit

    int i;

    i=100;

    EX_INT0=1;          

    //...do something, ex using Port 0 to test

    while(i--)//delay here

    {

    P0=0x11;      

    }

     //Remember, this is a example              

void main(void)

{

    ports_init();

    //set EX0 isr prioprity to 0

    IP0H&=0xFE;

    IP0 &=0xFE;

    //Enable interrupt

    EA=1;

    //Enable EX0 interrupt

    EX0=1;               

    //...do something...ex:

    while(1)

    {

    P0=0x55;

    }

//End here!

 

            Đoạn code trên, kết quả đơn giản là xuất ra ở port 0 giá trị 0x55(số hex) khi chưa có ngắt ngoài 0(chân P1.3!=0), khi có mức ngắt, P0 sẽ đổi sang giá trị 0x11 và delay nó trong một khoảng thời gian.

            Nếu dùng ASM để viết, chẳng khác gì MCU8051 cổ điển, tôi không muốn lặp lại trong bài này.

            Bạn có thể sử dụng file help ‘C51/CX51 User’s Guide’ để xem các mức ngắt và các báo ngắt.

 

LẬP TRÌNH CHO NGẮT TIMER:

LPC922 có hai Timer/Counter, ta có thể lập trình cho ngắt Counter/Timer như họ 8051 kinh điển:

Ví dụ: Lập trình ngắt Timer 0 cứ sau mỗi 50ms, sử dụng với thạch anh 12MHz; không ưu tiên ngắt (mức 0), xuất kết quả ra chân P0.0 và lật mức sau mỗi lần tràn Timer.

 

#include <reg922.h>

#include <intrins.h> //_nop_() function

sbit    Test_pin=P0^0;

//*********************************************************************

//Written by Hieu,Bui-trung, last modified:  at 19:54:53,on 9/10/2005**

//*********************************************************************

//*********************************************************************

 void timers_init(void)

{

  //configure timer 0

  TMOD &= 0xF0;

  TMOD |= 0x01;

  TAMOD &= 0xFE;

  //?Review in my paper or LPC922 datasheet.   

  //timer values

  TH0 = 0x00;

  TL0 = 0x01;

 

  //set timer 0 isr priority to 0

  IP0 &= 0xFD;

  IP0H &= 0xFD;

 

  //enable timer 0 interrupt

  ET0 = 1;

 

  //start timer 0

  TR0 = 1;

 

} // timers_init

//Sub function

void timers_starttimer0(void)

{

  TR0 = 1;

} // timers_starttimer0

 

//Sub function

void timers_stoptimer0(void)

{

  TR0 = 0;

} // timers_stoptimer0

 

//Sub function

//Timer 0 Interrupt Service Routine

void timers_isr0(void) interrupt 1 using 1  //Using register bank 1

{

  // reinitialize

  timers_stoptimer0();

  TH0 = 0x00;

  TL0 = 0x01;

//…do something… 

  timers_starttimer0();

//ex toggle Test_pin

  Test_pin^=Test_pin;

} // timers_isr0                      

 

 

/******************************************************************

******************************************************************/

//main.c function

void main(void)

{

//initialize Pin P1.0

      P0M1 &= 0xFE;

    P0M2 |= 0x01;

//Enable Interrupt

    EA=1;  

      timers_init();

//...do something

//wait interrupt

      while(1)    

      {

     _nop_();

      }

}

//do nothing J

 

Lập trình ngắt với Counter tương tự cho Timer.

LẬP TRÌNH CHO NGẮT CỔNG TRUYỀN PHÁT NỐI TIẾP: (Serial Port)

-         Địa chỉ ngắt 0x0023.

-         Loại 4 (theo thứ tự định bởi C51)

Tất nhiên, bạn có thể lập trình ngắt này dùng ASM (Tương tự 89C51 của ATMEL- ORG    0023H), tôi sẽ đề cập đến vấn đề này khi có dịp nói về UART.

LẬP TRÌNH CHO NGẮT TỪ BÀN PHÍM: (KBI Interrupt)

-         Địa chỉ ngắt: 0x003B

-         Loại 7 (theo thứ tự quy định bởi C51)

-         Để lập trình ngắt từ bàn phím, bạn nên tham khảo trang 83, 84 của User Manual P89LPC922 để biết cách khai báo các thanh ghi chức năng đặc biệt phục vụ quá trình ngắt keypad: KBMASK, KBCON, KBPATN.

Ví dụ: Sử dụng ngắt từ bàn phím, sao cho nếu 4 chân có địa chỉ thấp (P0.0 đến P0.3) khác 9 thì sinh ngắt, sử dụng ngắt ưu tiên mức 3 (nếu mức 4 cao nhất), chương trình ngắt sử dụng bank thanh ghi thứ 1.

/*******************************************************************

***************************Keypad Interrupt*************************

*******************************************************************/

//Written by Hieu, Bui-trung, last modifiled on  9/10/05 at   20:02:03

#include <reg922.h>      

#include<intrins.h>

void keypad_init(void)

{

  // define pattern

  KBPATN = 0x09;

  // define P0 pins that trigger interrupt

  KBMASK = 0x0F;

  // pattern must match

  KBCON = 0x02;

 

  // set P0 pins as inputs

  P0M1 |= 0x0F;

  P0M2 &= ~0x0F;

 

  // set isr priority to 2

  IP1 &= 0xFD;

  IP1H &= 0xFD;

  IP1H |= 0x02;

 

  // enable keypad interrupt

  EKBI = 1;

}                           

 

void keypad_isr(void) interrupt 7 using 1

{

  // clear interrupt flag

  KBCON &= 0xFE;

  //...do something

  _nop_();//do nothing :)

}

 

void main (void)

{

    //Enable Interrupt

     EA=1;

    //Initializes the keypad

     keypad_init();

     while(1)

     {

     //...do something

      //wait interrupt and do nothing

     _nop_();

     }             

}

 

LẬP TRÌNH CHO NGẮT TỪ BỘ SO SÁNH: (Comparators Interrupt)

-         Địa chỉ: 0x0043

-         Ngắt thứ 9 (Theo phân định mức ngắt của C51)

-         Trang 28-29 của Product Data P89LPC922, 79,80,81,82 của User Manual P89LPC9xx

-         Bạn đọc tự tham khảo. Lưu ý là cả hai bộ so sánh đều dùng chung một vector ngắt, nếu cả hai gây ra ngắt cùng lúc, người lập trình cần xem bộ so sánh nào đã gây ra ngắt sau khi chương trình ngắt được phục vụ, lưu ý thứ hai là khởi tạo bộ so sánh cần thời gian ít nhất 10μs trước khi sử dụng được.

 

        Tôi sẽ hỗ trợ các bạn các vấn đề về mạch nạp và chương trình C (uV3-Keil For 8051)  qua email: buitrunghieu@khvt.com (mỗi tuần sẽ check mail vào thứ 4 và thứ 7) hoặc trực tiếp qua cells phones: 0983210906 (trước 12 giờ tối và sau 7 giờ sáng), các bạn cũng có thể gởi thắc mắc qua messenger: trunghieukh@yahoo.com.

[Lên đầu trang]

 

 

© 2005 Bùi Trung Hiếu (http://www.khvt.com) Cập nhật lần cuối vào lúc 08:46:45 CH ngày 10 tháng chín 2005