Giới Giới Giới thiệu thiệu thiệu chung chung chung về về về ngắt ngắt - Khi chúng ta mong muốn bộ xử lí thực hiện một công việc nào ñó khi có một sự kiện xảy ra ngắt - Có 2 phương pháp ñ
Trang 1CHƯƠNG 4
MODUL NGẮT (INTERRUPT)
1
1 Giới Giới Giới thiệu thiệu thiệu chung chung chung về về về ngắt ngắt
- Khi chúng ta mong muốn bộ xử lí thực hiện một công việc
nào ñó khi có một sự kiện xảy ra ngắt
- Có 2 phương pháp ñể kiểm tra sự xuất hiện của một
sự kiện
+ Hỏi vòng (Polling): Phải kiểm tra liên tục tại các thời ñiểm khác
nhau của chương trình chính ñể phát hiện sự kiện xảy ra và thực
thi chương trình phục vụ sự kiện
+ Ngắt (Interrupt): Tự ñộng tạm dừng chương trình chính và bắt
ñầu thực thi chương trình phục vụ sự kiện ngay khi sự kiện xảy ra.
Trang 2• Tín hiệu thông báo cho bộ xử lý về một sự kiện gọi là tín
hiệu ngắt(nguồn ngắt)
chương trình con phục vụ ngắt (ISR: interrupt Service
Routine)
thi để chuyển sang thực hiện chương trình ngắt, sau khi
thực hiện xong chương trình ngắt thì bộ xử lý sẽ quay trở
về tiếp tục công việc đang thực thi bị tạm dừng
1
1 Giới Giới Giới thiệu thiệu thiệu chung chung chung về về về ngắt ngắt
2 CÁC NGUỒN NGẮT CỦA PIC16F887
Trang 33 CHO PHÉP / CẤM CÁC NGẮT
- Mặc định thì tất cả các ngắt đều bị cấm
- Mỗi ngắt được cho phép hoặc cấm bởi người sử dụng
thông qua các bit cho phép IE (Interrupt Enable) tương
ứng
IE = 0: Cấm
IE = 1: Cho phép
PIC16F887 cho phép các ngắt thông qua các bit trong
một số thanh ghi sau:
Interrupt Control Register (INTCON)
Peripheral Interrupt Enable Register 1 (PIE1)
Peripheral Interrupt Enable Register 2 (PIE2)
3 CHO PHÉP / CẤM CÁC NGẮT
- Mỗi ngắt được kết hợp với 1 bit khác, dùng để chỉ thị
rằng “sự kiện ngắt” đã xảy ra Bit này được gọi là cờ ngắt
(IF: Interrupt Flag)
IF = 0: Không có sự kiện
IF = 1: Có sự kiện
- Cờ ngắt IF sẽ có mức cao (IF = 1) ngay khi “sự kiện ngắt”
tương ứng xảy ra, bất chấp ngắt đó có được cho phép
hay không
Cờ ngắt IF phải được xóa (IF = 0) bởi người sử dụng trước
khi thoát khỏi ISR của nó.
Trang 44 CÁC THANH GHI CỦA MODUL NGẮT
- Thanh ghi INTCON: cho phép ngắt và yêu cầu ngắt (cờ ngắt)
nội
- Thanh ghi PIE1: Thanh ghi cho phép ngắt ngoại vi 1
- Thanh ghi PIR1: Thanh ghi yêu cầu ngắt (cờ ngắt) ngoại vi 1
- Thanh ghi PIE2: Thanh ghi cho phép ngắt ngoại vi 2
- Thanh ghi PIR2: Thanh ghi yêu cầu ngắt (cờ ngắt) ngoại vi 2
5 NGẮT NỘI (CORE INTERRUPT)
8
GIE PEIE T0IE INTE RBIE T0IF INTF RBIF
CÁC BIT CHO PHÉP
GIE: Cho phép ngắt toàn cục
* Phải ñược ñặt ñể sử dụng BẤT KỲ ngắt nào của PIC
PEIE: Cho phép ngắt ngoại vi
* Phải ñược ñặt ñể sử dụng các ngắt ngoại vi
T0IE: Cho phép ngắt Timer0 tràn
INTE: Cho phép ngắt ngoài INT
RBIE: Cho phép ngắt Port B thay ñổi
CÁC BIT CỜ T0IF: Cờ ngắt Timer0 tràn INTF: Cờ ngắt ngoài INT RBIF: Cờ ngắt Port B thay ñổi
Các cờ ngắt vẫn sẽ
ñược ñặt ngay cả khi
các ngắt không ñược
cho phép
Thanh ghi INTCON
Trang 56 NGẮT NGOẠI VI (PERIPHERAL INTERRUPT)
9
ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
Thanh ghi PIE1 (Cho phép ngắt)
ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF
Thanh ghi PIR1 (Cờ ngắt)
ADIE ADIF Hoàn thành chuyển ñổi ADC
RCIE RCIF ðầy bộ ñệm nhận EUSART
TXIE TXIF ðầy bộ ñệm truyền EUSART
SSPIE SSPIF Ngắt I 2 C hoặc SPI
CCP1IE CCP1IF Hoàn thành so sánh hoặc bắt giữ cho Timer1
TMR2IE TMR2IF Giá trị thanh ghi Timer2 bằng giá trị thanh ghi PR2
TMR1IE TMR1IF Thanh ghi Timer1 bị tràn
Cho phép Cờ ðiều kiện
Các cờ ngắt vẫn sẽ ñược ñặt ngay cả khi các ngắt không
ñược cho phép
6 NGẮT NGOẠI VI (PERIPHERAL INTERRUPT)
10
Các cờ ngắt vẫn sẽ ñược ñặt ngay cả khi các ngắt không
ñược cho phép
C2IE C1IE EEIE BCLIE ULPWUIE CCP2IE
OSCFIE
PIE2 Register (Interrupt Enables)
C2IF C1IF EEIF BCLIF ULPWUIF CCP2IF
OSCFIF
PIR2 Register (Interrupt Flags)
C2IE C2IF Ngõ ra bộ so sánh 2 bị thay ñổi
C1IE C1IF Ngõ ra bộ so sánh 1 bị thay ñổi
EEIE EEIF Thao tác ghi EEPROM hoàn tất
BCLIE BCLIF Xung ñột bus xuất hiện ở chế ñộ MSSP I 2 C
ULPWUIE ULPWUIF ðiều kiện “ñánh thức” xảy ra
CCP2IE CCP2IF Hoàn thành so sánh hoặc bắt giữ cho Timer1
OSCFIE OSCFIF Bộ dao ñộng hệ thống bị lỗi
Cho phép Cờ ðiều kiện
Trang 67 ĐỘ TRỄ CỦA NGẮT
- Độ trễ của ngắt: Là khoảng thời gian tính từ lúc sự kiện
xảy ra cho đến khi lệnh tại địa chỉ 0004h được thực thi
- Độ trễ của các ngắt đồng bộ (thường là ngắt bên trong)
khoảng 3 chu kỳ máy
- Độ trễ của các ngắt không đồng bộ (thường là ngắt bên
ngoài) khoảng 3 – 3.5 chu kỳ máy
SAO LƯU DỮ LIỆU KHI NGẮT
Trong khi xảy ra ngắt:
Chỉ có giá trị PC được lưu lại (vào ngăn xếp),giá trị của
các thanh ghi khác có thể bị thay đổi sau khi thực thi
xong ISR → Do đó cần phải sao lưu và phục hồi giá trị
các thanh ghi quan trọng
Các thanh ghi mà người dùng nên lưu lại:
Thanh ghi W
Thanh ghi STATUS
Thanh ghi PCLATH
Thanh ghi ñược ñịnh nghĩa bởi người dùng
Trang 77 ƯU TIÊN NGẮT
- Vi điều khiển họ Mid-Range (PIC16F) thiết lập tất cả
các ngắt có cùng một mức ưu tiên
- Việc thiết lập mức ưu tiên khác nhau cho các nguồn
ngắt là do người sử dụng
- Thiết lập mức ưu tiên cho các ngắt:
Bước 1: Xác định các nguồn ngắt
Bước 2: Xác định thứ tự của các ISR
Bước 2: Lập trình để xác lập mức ưu tiên
Ví dụ: Thiết lập thứ tự ưu tiên từ cao xuống thấp cho các
ngắt: Port B, Timer 2 và Timer 1
void interrupt isr(void)
{
if (RBIE == 1) && (RBIF == 1)
PORTB_ISR()
if (TMR2IE == 1) && (TMR2IF == 1)
Timer2_ISR()
if (TMR1IE == 1) && (TMR1IF == 1)
Timer1_ISR() }
Trang 8Ví dụ 1: Sử dụng ngắt ngoài lập trình điều khiển led theo yêu cầu sau
Bình thường: Led đếm 0 7 theo mã nhị phân
Ngắt: led chớp tắt 3 lần
Gợi ý:
• Ngắt ngoài xảy ra khi có sự thay đổi mức logic tại chân RB0
Nên chọn thay đổi 0 1 hoặc 10
• Gắn nút nhấn và kích hoạt R kéo lên tại chân RB0
• Xem led nối với chân nào để cấu hình PORT
• Kích hoạt tính năng ngắt ngoài
• Viết chương trình chính
• Viết chương trình ngắt
• Kiểm tra kết quả trên mạch mô phỏng
Trang 9#include <htc.h>
#include <math.h>
CONFIG (FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF &
BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
#define _XTAL_FREQ 4000000
void interrupt isr(void)
{
unsigned char j;
if (INTE && INTF)
{
INTF = 0;
for (j=0;j<=2;j++) {
PORTE = 0X00;
delay_ms(500);
PORTE = 0X07;
delay_ms(500);
} }
}
void main(void)
{ unsigned char i;
ANSEL = 0X00;
ANSELH = 0X00;
TRISE = 0X00;
TRISB0 = 1;
nRBPU = 0;
WPUB = 0x01;
INTF = 0;
GIE = 1;
INTE = 1;
INTEDG = 0;
while(1) { for (i=0; i<8; i++)
{ PORTE = i;
delay_ms(500);
} }
}
Ví dụ 2: Sử dụng ngắt portB lập trình điều khiển led theo yêu cầu sau
Bình thường: Led tắt hết
Ngắt portB :
+ nhấn RB0: led chop tat 3 lan + nhấn RB1: led sang trong 2s + nhấn RB3: led đếm 0 7
Trang 10Gợi ý:
• Ngắt ngoài xảy ra khi có sự thay đổi mức logic tại PORTB
• Gắn nút nhấn và kích hoạt R kéo lên tại chân RB0,RB1,RB2
• Xem led nối với chân nào để cấu hình PORT
• Kích hoạt tính năng ngắt portB
• Viết lưu đồ giải thuật
• Viết chương trình chính
• Viết chương trình con
• Viết chương trình ngắt
• Kiểm tra kết quả trên mạch mô phỏng
#include <htc.h>
#include <math.h>
CONFIG (FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF
& IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
#define _XTAL_FREQ 4000000
void choptat ()
{
unsigned char i;
for (i=0;i<3;i++)
{
PORTE = 0X00;
delay_ms(500);
PORTE = 0X07;
delay_ms(500);
}
}
void sang2s ()
{
PORTE = 0X07;
delay_ms(2000);
}
void dem()
{
unsigned char i;
for (i=0;i<8;i++) {
PORTE = i;
delay_(500);
} }
void interrupt isr()
{
PORTB;
RBIF = 0;
if (!RB0)
choptat();
else if (!RB1)
sang2s();
else if (!RB2)
dem();
}
Trang 11void main()
{
unsigned char i;
ANSEL = 0X00;
ANSELH = 0X00;
TRISE = 0X00;
TRISB = 0xFF;
nRBPU = 0;
WPUB = 0x07;
RBIF = 0; // xoa co ngat
RBIE = 1; //cho phep ngat portb
GIE = 1; //cho phep ngat toan cuc
IOCB0 = 1;
IOCB1 = 1;
IOCB2 = 1;
while(1)
{
PORTE = 0X00;
PORTB;
}
}