Lập trình C cho hệ thống nhúng (P3- Học về các ngắt với micro controller V850E)
Ngắt (Interrupt) là một số sự kiện khẩn cấp bên trong hoặc bên ngoài bộ vi điều khiển xảy ra, buộc vi điều khiển tạm dừng thực hiện chương trình hiện tại, phục vụ ngay lập tức nhiệm vụ mà ngắt yêu cầu – nhiệm vụ này gọi là trình phục vụ ngắt (ISR: Interrupt Service Routine). Vì sao nên sử dụng ...
Ngắt (Interrupt) là một số sự kiện khẩn cấp bên trong hoặc bên ngoài bộ vi điều khiển xảy ra, buộc vi điều khiển tạm dừng thực hiện chương trình hiện tại, phục vụ ngay lập tức nhiệm vụ mà ngắt yêu cầu – nhiệm vụ này gọi là trình phục vụ ngắt (ISR: Interrupt Service Routine).
Vì sao nên sử dụng ngắt : với vi điều khiển có thể phục vụ cho nhiều thiết bị, có 2 cách để thực hiện điều này đó là sử dụng các ngắt (Interrupts) và thăm dò (polling):
Phương pháp sử dụng ngắt: mỗi khi có một thiết bị bất kỳ cần được phục vụ thì nó báo cho bộ vi điều khiển bằng cách gửi một tín hiệu ngắt. Khi nhận được tín hiệu ngắt thì bộ vi điều khiển ngừng tất cả những gì nó đang thực hiện để chuyển sang phục vụ thiết bị gọi ngắt. Chương trình ngắt được gọi là trình phục vụ ngắt ISR (Interrupt Service Routine) hay còn gọi là trình quản lý ngắt (Interrupt handler). Sau khi phục vụ ngắt xong, bộ vi xử lý lại quay trở lại điểm bị ngắt trước đó và tiếp tục thực hiện công việc.
Khi có một ngắt xảy ra, thì chương trình( trình phục vụ ngắt) sẽ được hoạt động như sau
- Hoàn thành lệnh đang thực hiện.
- Dừng chương trình đang thực hiện
- Lưu địa chỉ của lệnh kế tiếp
- Thực hiện chương trình con phục vụ ngắt
- Sau khi thực hiện xong bước trên ,Vi điều khiển sẽ lấy lại địa chỉ lệnh kế tiếp và thực hiện tiếp chương trình. Sơ đồ hoạt động của ngắt
Khi nhiều ngắt cùng xảy ra một lúc thì vi điều khiển sẽ dựa vào độ ưu tiên của ngắt để tiến hành thứ tự thực hiện các chương trình con phục vụ ngắt.Độ ưu tiên các ngắt sẽ được thiết lập trong các thanh ghi điều khiển riêng của từ ngắt. Trong V850 có thể thiết lập 8 mức độ ưu tiên cho ngắt và mức độ được ưu tiên cao nhất là mức 0.Và nếu như devloper không thiết lập mức độ ưu tiên thì sẽ được lấy giá trị default(tham khảo manual của mỗi VĐK) Cách thức xử lý nhiều ngắt. Như hình trên ta thấy , 3 ngắt a,b,c xảy ra đồng thời nhưng b và c có mức độ ưu tiên cao hơn(mức 1) nên sẽ thực hiện b,c trước.Trong trường hợp b,c có cùng mức độ ưu tiên thì sẽ dựa vào giá trị default để quyết định thực hiện b trước.
Tạo ngắt Timer trên V850
Trên V850 có tất cả 4 bộ Timer 16 bit , chúng ta sẽ sử dụng thử một Internal Timer M để tạo ta Timer 1ms. Để tạo được timer 1ms chúng ta phải biết được tần số thạch anh của thiết bị chúng ta đang sử dụng. Giả sử trong trường hợp này
Tần số thạch anh 8Mhz --> System clock frequency(fxx) = 8 x 8 = 64Mhz |
---|
- Dùng bộ chia tần số để chọn tần sô hoạt động của Timer ft= fxx/2 = 32MHz
- Tính Count clock cycle(chu kỳ của 1 lần đếm) = 1/32 μs
- Interval = (Set value of TAAnCCR0 register + 1) × Count clock cycle Interval : timer 1ms(1000 μs) muốn tạo ra. => Set value of TAAnCCR0 register = 32000 - 1
- Cho phép ngắt hoạt động
- Chọn độ ưu tiên cho ngắt
- Khởi động Timer
/************************************************************************************************************/ /* Create TMM0 Timer 1ms */ /************************************************************************************************************/ TM0CTL0 = 0x00; /* Set Timer frequency fxx/2 */ TM0CMP0 = (32000 - 1); /* Set value of TAAnCCR0 register */ TM0EQIC0 = 0x03; /* Timer operation Accepted, Set priority level 4 */ TM0CTL0.7 = 1; /* TMM0 Timer operation Start */
- Tạo chương trình con phục vụ ngắt (Cứ mỗi 1ms thì chương trình con dưới đây sẽ được thực hiện)
#pragma interrupt INTTM0EQ0 IntTM0EQ0 /* Định nghĩa lại tên vector ngắt INTTM0EQ0*/ __interrupt void IntTM0EQ0(void) { // Chương trình xử lý trong ngắt được thực hiện ở đây }
Khởi động và xử lý ngắt chức năng biến đổi ADC(Analog - Digital Converter) trên V850
Trong kỹ thuật số, ta thấy đại lượng số có giá trị xác định là một trong hai khả năng là 0 hoặc 1, cao hay thấp, đúng hoặc sai, vv… Trong thực tế chúng ta thấy rằng một đại lượng số (chẳng hạn mức điện thế) thực ra có thể có một giá trị bất kỳ nằm trong khoảng xác định và ta định rõ các giá trị trong phạm vi xác định sẽ có chung giá trị dạng số. Do đó ADC thực hiện chuyển đổi một đại lượng vật lý tương tự liên tục nào đó (thường là điện áp) sang giá trị số biểu diễn độ lớn của đại lượng đó. V850 có 2 bộ ADC (ADC0,ADC1)và với mỗi bộ có 4 kênh tín hiệu analog đầu vào.Chúng ta sẽ khởi tạo ngắt và hoạt động cho ADC0
AD0OCKS = 0x12; /* Set ADC frequency fxx/4 */ AD0SCM = 0x0082; /*Select the operation mode for ADC */ for (ulCount=0 ; ulCount<10000 ; ulCount++); /* Waitng 1us to setting finish */ AD0CTC = 0x00; /* Set ADC Interupt Intervel Timer=5.56us */ AD0CHEN = 0x001E; /*Select ADC channel */ AD0CTL0 = 0x00; /* Not use Op-amp */ AD0IC = 0x03; /* Set priority level 3 */
* Tạo chương trình con phục vụ ngắt cho ADC0 #pragma interrupt INTAD0 IntAD0 /* Định nghĩa lại tên vector ngắt INTAD0*/ __interrupt void IntAD0(void) { // Chương trình xử lý trong ngắt được thực hiện ở đây }
4.Lưu ý khi viết chương trình con phục vụ ngắt
- Chương trình con con phải được viết gọn gàng, thời gian xử lý ngắn vì khi đang thực hiện một ngắt thì các ngắt khác hoặc chương trình chính sẽ không được thực hiện.
- Kiểm tra lại thời gian hoạt động của một chương trình con phục vụ ngắt bằng máy hiện sóng.
- Thiết lập mức ưu tiên cho các ngắt phù hợp với mục đích thiết bị
- Lưu ý sẽ có một số lệnh sẽ không được thực hiện khi chúng ta gọi trong ngắt (tùy vi điều khiển)
- Sử dụng các vòng lặp một cách có kiểm soát để tránh thời gian xử lý trong ngắt quá lâu.