Chào mừng đến với Câu Lạc Bộ Sáng Tạo
Chia sẻ kinh nghiệm
Kết nối đam mê
Đang cập nhật thời gian...
BÀI VIẾT NỔI BẬT
Xin chào! Tôi là Ếch Sáng Tạo :-)
Chia sẻ trang




Chuyên mục
Bài mới
Xem nhiều
Thống kê
  • Bài viết: 334/334
  • Thành viên: 10.085
  • Đang online: 12
  • Khách hôm nay: 285
  • Khách hôm qua: 2.955
  • Tổng khách: 16.197.843
Bài viết
[Bài 3] Lập trình ngắt cho AVR trên CodeVisionAVR - SangTaoClub.Net
[Bài 3] Lập trình ngắt cho AVR trên CodeVisionAVR
Đăng bởi: Vũ Văn Thái - Thời gian: 16-06-2014, 14:06
Chuyên mục: Học lập trình AVR - Lượt xem: 23.184

Lập trình ngắt cho AVR trên CodeVisionAVR

1. Khái niệm

        Ngắt là một quá trình can thiệp vào chương trình chính đang chạy, sau khi thực hiện xong quá trình đó nó sẽ quay trở lại tiếp tục thực hiện chương trình đang chạy.

        VD: Bạn đang làm một việc nào đó theo trình tự từ đầu đến cuối rồi lại quay lại, cứ như vậy có vẻ như không có chuyện gì xảy ra, đột nhiên xếp (Trưởng phòng) gọi bạn đem cho một cốc cafe chẳng hạn, thì bạn sẽ dừng công việc đó lại để đi pha cafe đem cho xếp, xong việc pha cafe thì bạn lại cắm đầu vào công việc đang dang dở vữa nãy. Nếu hôm nào xếp không yêu cầu pha cafe thì "ngắt" sẽ không thể xảy ra.

Thứ tự ưu tiên giảm dần theo địa chỉ của chương trình, tức ngằt RESET và INT0, INT1 có mức ưu tiên cao nhất. Trong quá trình chạy chương trình nếu có 2 ngắt cùng xảy ra thì ngắt nào có thứ tự ưu tiên cao hơn sẽ được thực thi trước.

2. Danh sách các ngắt trên AVR

STT Tên ngắt Địa chỉ chương trình Miêu tả chức năng
1 RESET 0X000 Ngắt phần cứng Reset
2 INT0 0x001 Ngắt ngoài tại chân INT0
3 INT1 0x002 Ngắt ngoài tại chân INT1
4 TIMER2 COMP 0x003 Ngắt so sánh timer 2
5 TIMER2 OVF 0x004 Ngắt tràn timer 2
6 TIMER1 CAPT 0x005 Ngắt chụp sự kiện timer 1
7 TIMER1 COMPA 0x006 Ngắt so sánh A timer 1
8 TIMER1 COMPB 0x007 Ngắt so sánh B timer 1
9 TIMER1 OVF 0x008 Ngăt tràn timer 1
10 TIMER0 OVF 0x009 Ngắt tràn timer 0
11 SPI, STC 0x00A Ngắt giao tiếp SPI
12 USART, RXC 0x00B Ngắt nhận dữ liệu cổng nối tiếp
13 USART, UDRE 0x00C Ngắt thanh ghi dữ liệu cổng nối tiếp trống
14 USART, TXC 0x00D Ngắt truyền dữ liệu cổng nối tiếp
15 ADC 0x00E Ngắt chuyển đổi ADC
16 EEP_RDY 0x00F Ngắt bộ nhớ EEPROM sẵn sàng
17 ANA_COMP 0x010 Ngắt bộ so sánh analog
18 TWI 0x011 Ngắt giao tiếp 2 dây
19 SPM_RDY 0x012 Ngắt bộ nhớ chương trình sẵn sàng

3. Bảng vector ngắt cho lập trình C trên CodeVisionAVR

STT Tên ngắt Vector ngắt
1 RESET  
2 INT0 EXT_INT0
3 INT1 EXT_INT1
4 TIMER2 COMP TIM2_COMP
5 TIMER2 OVF TIM2_OVF
6 TIMER1 CAPT TIM2_CAPT
7 TIMER1 COMPA TIM1_COMPA
8 TIMER1 COMPB TIM1_COMPB
9 TIMER1 OVF TIM1_OVF
10 TIMER0 OVF TIM0_OVF
11 SPI, STC SPI_STC
12 USART, RXC USART_RXC
13 USART, UDRE USART_UDRE
14 USART, TXC USART_TXC
15 ADC ADC_INT
16 EEP_RDY EEP_RDY
17 ANA_COMP ANA_COMP
18 TWI TWI
19 SPM_RDY SPM_RDY

4. Khai báo chương trình phục vụ ngắt trên CodeVisionAVR

interrupt [vector_ngắt] void tên_ctr(void)
{

//Nội dung code chương trình phục vụ ngắt

}

VD cho ngắt ADC:

interrupt [ADC_INT] void adc_int(void)
{

adc_data=ADCH; //Lấy dữ liệu ADC 8bit vừa chuyển đổi

}

5. VD về ngắt ngoài và ngắt timer

a. Ngắt ngoài

Ngắt ngoài là quá trình tác động từ bên ngoài vào bên trong VDK làm cho VDK thực hiện một ngoại lệ nào đó.

Trong AVR cung cấp cho chúng ta 2 ngắt ngoài là INT0 và INT1  cơ chế hoạt động giống hệt nhau, có 4 kiểu là:

- Ngắt mức thấp Low level - Chỉ xảy ra ngắt khi chân INT0 hoặc INT1 ở mức thấp

- Ngắt thay đổi logic Any change - Bất kỳ thay đổi logic nào trên chân INT0 hoặc INT1

- Ngắt sườn lên Rising Edge (logic 0 lên logic 1)

- Ngắt sườn xuống Falling Edge (logic 1 xuống logic 0)

 

Do cơ chế giống nhau ta chỉ xét 1 ngắt cho cả 2 ngắt luôn, các thanh ghi tham gia điều khiển ngắt ngoài:

MCUCR (MCU Control Register): Là thanh ghi điều khiển ngắt ngoài, ta chỉ quan tâm tới 4bit thấp của thanh ghi này, 4bit cao không phụ trách điều khiển ngắt ngoài:

7 6 5 4 3 2 1 0
SE SM2 SM1 SM0 ISC11 ISC10  ISC01  ISC00

Trong đó:

               - ISC01 và ISC00 là 2bit chọn kiểu ngắt ngoài INT0.

               - ISC11 và ISC10 là 2bit chọn kiểu ngắt ngoài INT1.

Ta có bảng sau:

ISC01/ISC11 ISC00/ISC10 Kiểu ngắt
0 0 Ngắt mức thấp
0 1 Ngắt thay đổi logic
1 0 Ngắt sườn xuống
1 1 Ngăt sườn lên

VD ta muốn sử dụng cả 2 ngắt ở kiểu ngắt sườn xuống thì ta set như sau: MCUCR=0x0A; tương đương MCUCR=00001010

GICR (General Interrupt Control Register): Là thanh ghi mặt nạ ngắt cho ngắt ngoài có 2 bit cho phép ngắt là:

7 6 5 4 3 2 1 0
INT1 INT0   -     -     -     -    IVSEL IVCE

Ta chỉ việc set 1 trong 2 bit trên lên logic 1 là sử dụng được ngắt ngoài tương ứng. Lưu ý các chip AVR như AT90 thì thanh ghi mặt nạ ngắt là GIMSK.

GIFR (General Interrupt Flag Register): Là thanh ghi lưu trạng thái cờ ngắt ta không quan tâm thanh ghi này trong lập trình mà chỉ biết là nó có 2bit cờ là INTF1, INTF0.

Như vậy ta sẽ có code VD ngắt ngoài INT0 như sau:

Code này sẽ bật tắt LED khi nhấn nút, nút nhấn được nối với chân INT0, minh họa bằng chip ATmega8.

#include <mega8.h>
#define LED PORTB.0   //Chan PB0 gan LED
interrupt [EXT_INT0] void ngat_ngoai_0(void)
{
         LED = ~LED;   //Dao muc logic
}
void main()
{
         DDRB.0 = 1;          //PB0 lam Output
         MCUCR |= (1<<ISC01);      //ISC01=1, ISC00=0 Ngat suon xuong INT0
         GICR |= (1<<INT0);          //Ngat ngoai INT0
         LED = 0;          //Led tat
         #asm("sei")          //Cho phep ngat cuc bo
         while(1);                //Khong lam gi ca
}

Mô phỏng trên proteus 7.10:

Lập trình ngắt cho AVR trên CodeVisionAVR - SangTaoClub.Net

 

b. Ngắt timer 

Để hiểu rõ về timer vui lòng xem bài 2 để hiểu rõ về cơ chế của timer, ở bài 2 đã nói rất rõ các thanh ghi phụ trách điều khiển timer trong đó ngắt, phần code bên dưới sẽ là code mẫu cho tất cả các timer trong AVR, các bạn dựa vào code mẫu để xây dựng chương trình của riêng các bạn:

Link: http://sangtaoclub.net/bai-viet/176-bai-2-tim-hieu-bo-timer-counter-tren-avr.html

Code mẫu: Nhấp nháy LED sau mỗi lần ngắt timer 0

#include <mega8.h>
#define LED PORTD.0   //Chan PD0 gan LED
interrupt [TIM0_OVF] void ngat_timer_0(void)
{
         LED = ~LED;   //Dao muc logic
         TCNT0 = 5;   //Set lai gia tri
}
void main()
{
         DDRD.0 = 1;   //PD0 lam Output
         TCCR0 = (1<<CS02) | (1<<CS00);   //CS02=1, CS01=0, CS00=1: xung clock bang Fosc/1024
         TCNT0 = 5;    //Khoi tao gia tri
         TIMSK = (1<<TOIE0);   //Ngat tran timer 0
         LED = 0;    //Led tat
         #asm("sei")           //Cho phep ngat cuc bo
         while(1);    //Khong lam gi ca
}

Mạch mô phỏng:

Lập trình ngắt cho AVR trên CodeVisionAVR - SangTaoClub.Net

Các bạn tải code mẫu và mô phỏng về trong File đính kèm...


Tải về đính kèm:
Ngat_AVR.zip
Kích thước: 69.78 KB
Bài viết sửa lúc 16-06-2014, 21:01 bởi Vũ Văn Thái
  • Bạn chưa đăng nhập, không thể viết bình luận!
    Bấm vào đây để Đăng nhập hoặc Đăng ký!
  • Vũ Văn Thái lúc 24-10-2014, 16:14
    Mình đã ghi rõ trong ngoặc đơn bên cạnh nhưng mình sẽ nhắc lại như sau:
    - Ngắt sườn xuống là khi ta thay đổi logic từ 1 về 0 tại chân ngắt thì sẽ xảy ra một sự kiện ngắt ngoài
    - Ngắt sườn lên thì ngược lại và tương tự khi ta thay đổi logic từ 0 lên 1
    - Ngắt logic thấp là quá trình ta thay đổi logic về 0 và giữ ở trạng thái đó đây không phải là ngắt sườn
    - ngắt thay đổi logic là cả 2 trạng thái của ngắt logic, tức khi đang ở logic 1 mà ta thay đổi về 0 là nó sẽ sinh ra ngắt và khi đang ở 0 ta cho lên 1 cũng sinh ra ngắt...
  • DQQ_kk lúc 24-10-2014, 15:51
    cho e hỏi ngắt sườn xuống với ngắt sườn lên là như thế nào vậy?
  • el_tri lúc 30-06-2014, 21:45
    vâng e cảm ơn ạ
  • Vũ Văn Thái lúc 25-06-2014, 18:21
    khi khai báo ngắt thì nó mặc định rồi, mới lại khi khởi động các thanh ghi đều được set bằng 0x00 hết, lên nó đã là input rồi.
  • el_tri lúc 25-06-2014, 16:35
    anh ơi, em hỏi là ở code ngắt ngoài INT0. e thêm code : DDRD=0x00 ; // để đặt portD làm input được không ạ ? thấy trong code không có mà trên mạch lại có ?
  • Trang 1/1: 1

    Bài viết cùng chuyên mục
    ATMG16 giao tiếp với LCD ATMG16 giao tiếp với LCD
    Đăng bởi: haydayanh - Thời gian: 04-06-2021, 22:33
    Chuyên mục: Học lập trình AVR - Lượt xem: 2.684
    Hướng dẫn làm KIT AVR đơn giản Hướng dẫn làm KIT AVR đơn giản
    Đăng bởi: Vũ Văn Thái - Thời gian: 25-10-2014, 09:39
    Chuyên mục: Học lập trình AVR - Lượt xem: 11.064
    [Bài 6] Lập trình giao tiếp USART và RS232 với AVR [Bài 6] Lập trình giao tiếp USART và RS232 với AVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 15-08-2014, 15:25
    Chuyên mục: Học lập trình AVR - Lượt xem: 19.137
    [Bài 5] Lập trình ADC - Đo nhiệt độ dùng LM35 hiển thị LCD với AVR [Bài 5] Lập trình ADC - Đo nhiệt độ dùng LM35 hiển thị LCD với AVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 25-06-2014, 10:17
    Chuyên mục: Học lập trình AVR - Lượt xem: 57.886
    [Bài 4] Lập trình giao tiếp LCD16x2 cho AVR trên CodeVisionAVR [Bài 4] Lập trình giao tiếp LCD16x2 cho AVR trên CodeVisionAVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 22-06-2014, 10:42
    Chuyên mục: Học lập trình AVR - Lượt xem: 24.172
    [Bài 2] Tìm hiểu bộ Timer-Counter trên AVR [Bài 2] Tìm hiểu bộ Timer-Counter trên AVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 15-06-2014, 11:55
    Chuyên mục: Học lập trình AVR - Lượt xem: 20.630
    [Bài 1] Xuất nhập Port đơn giản cho AVR [Bài 1] Xuất nhập Port đơn giản cho AVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 29-05-2014, 21:22
    Chuyên mục: Học lập trình AVR - Lượt xem: 9.838
    Hướng dẫn set fuse bit cho AVR Hướng dẫn set fuse bit cho AVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 16-05-2014, 22:09
    Chuyên mục: Học lập trình AVR - Lượt xem: 22.641
    Mạch nạp ISP cho vi điều khiển AVR và 89S Mạch nạp ISP cho vi điều khiển AVR và 89S
    Đăng bởi: Vũ Văn Thái - Thời gian: 10-05-2014, 12:22
    Chuyên mục: Học lập trình AVR - Lượt xem: 20.759
    Lập trình C trong CodeVisionAVR Lập trình C trong CodeVisionAVR
    Đăng bởi: Vũ Văn Thái - Thời gian: 28-04-2014, 19:30
    Chuyên mục: Học lập trình AVR - Lượt xem: 17.149
    
    Chào mừng hieutrang đã tham gia câu lạc bộ sáng tạo!
    Vũ Văn Thái - vuthai
    Hôm nay là sinh nhật của doinhugiobayxa, bangguong84, thaivande, haidong0212, quynang, ocbieu3636, skytnut, soidonghoangtd94, vuquocdungmta, khangdlk123, thanh7780, ngovanson, tuananhckd2504, lybang, splendid2504, Lesondt, thucduyen2604, hanhbe, tuanngocly95, anhhungsg, anhkhoa951, ← Gửi tin nhắn chúc mừng
    Múi giờ: UTC+07:00 - Asia/Ho Chi Minh ***** IP của bạn: 18.117.107.90 ***** Thời gian xử lý trang: 0.060 giây - Cache: Sẵn sàng!