Interrupt on change như thế nào
bubeohl24-11-2008, 10:12 PMchào các bác! em có chút rắc rối như sau:
em sử dụng 2 ngắt của 16f887 là ngắt ngoài(trên rb0), và một ngắt on_change(rb5 chẳng hạn) .em sử dụng 2 phím bấm nối tới 2 chân này. mục đích của em là: ấn button1 thì thực hiện chuong_trinh1 ấn button2 thì thực hiện void chuong_trinh2() nhưng khi lắp mạch test thì kết quả luôn như sau: đầu tiên , hiện dòng chữ " hello" trong main(),5 giây sau thì chương trình TỰ ĐỘNG nhảy vào ngắt luôn (thực hiện chương _trinh1) mà em chưa hề ấn phím(tất nhiên ấn phím 2 cũng ko tác dụng).em ko hiểu tại sao nữa.đây là code: #include <16f887.h> #include #device *=16 ADC=10 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #include void chuong_trinh1(); void chuong_trinh2(); #int_RB void RB_isr(void) { chuong_trinh1(); } #int_EXT void EXT_isr(void) { chuong_trinh2(); } void chuong_trinh1() { lcd_init(); lcd_putcmd(0x01);//xoa man hinh lcd_putcmd(0x80); lcd_putchar("chaocacban"); delay_ms(5000); } void chuong_trinh2() { lcd_init(); lcd_putcmd(0x01);//xoa man hinh lcd_putcmd(0xc0); lcd_putchar("mynamehung"); delay_ms(5000); } void main() { trisb=0xff; enable_interrupts(INT_RB); enable_interrupts(INT_EXT); ext_int_edge( H_TO_L ); enable_interrupts(GLOBAL); lcd_init(); lcd_putcmd(0x01);//xoa man hinh lcd_putcmd(0x80); lcd_putchar("hello"); delay_ms(5000); while(1); } các bác giúp em với.thanks các bác nhiều ah,còn một vấn đề nữa là muốn thoát khỏi ngắt thì làm thế nào ạ(ví dụ đang làm ctrinh thu nhất em muốn thực hiện chuong trình 2 ngay sau động tác bấm phím chẳng hạn) falleaf 26-11-2008, 07:54 AM Đại ý của nó là bởi khi ghi và khi đọc, mặc dù giá trị mong muốn là giá trị logic 0/1, nhưng thực tế tín hiệu ghi ra chân và tín hiệu đọc vào CPU để xử lý có thể khác nhau (mức điện áp). Để tránh tình trạng này, khi ghi ra chân PIC thì người ta ghi nhớ nó vào một biến tạm (thanh ghi đệm port - shadow register), sau đó khi đọc vào thì đọc luôn cái biến tạm này (0/1). tdm 21-12-2010, 02:46 PM sữ dụng interrupt on change. Trong quá trình làm việc, bỗng nhiên bạn nhận được một yêu cầu gấp, cần phải thực hiện ngay lập tức. Lúc này, bạn buộc phải dừng công việc hiện tại để thực hiện yêu cầu đó và chỉ có thể tiếp tục công việc đang dở dang khi hoàn thành song yêu câu. Tương tự vậy, trong lập trình, chúng ta có một khái niệm, đó chính là ngắt (Interrupt). Hình 1. Ngắt Ngắt là khi một tín hiệu khẩn cấp được gửi tới bộ xử lý, yêu cầu bộ xử lý tạm dừng tức khắc các hoạt động hiện tại để nhảy đến một nơi khác thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này được gọi là trình phục vụ ngắt – ISR (Interrupt Service Routine). Sau khi kết thúc trình phục vụ ngắt – ISR, bộ đếm chương trình sẽ trả về giá trị trước đó để bộ xử lý quay về thực hiện chương trình đang dang dở. Vì sao cần sử dụng ngắt Quay trở lại ví dụ về button đã đề cập ở phần Hello world, chúng ta phải liên tục đọc trạng thái của nút nhấn bằng hàm
Điều này sẽ cực kì khó khăn khi số lượng các câu lệnh trong chương trình Điều này sẽ giúp tốc độ đáp ứng của chương trình đối với các thao tác của bạn được nhanh hơn và việc quản lý chương trình của bạn được dễ dàng và hiệu quả hơn. Vector ngắt Trong thực tế trên mỗi bộ xử lý đều có rất nhiều ngắt khác nhau, vậy điều gì sẽ xảy ra khi cùng một lúc có hai ngắt xuất hiện? Cũng như ví dụ đầu bài, nhưng bây giờ bạn nhận đến 2 yêu cầu cần thực hiện gấp, vậy bạn sẽ thực hiện yêu cầu nào? Tất nhiên là sẽ ưu tiên yêu cầu cấp thiết nhất, sau khi hoàn thành thì mới thực hiện yêu cầu tiếp theo và cuối cùng là trở lại công việc đang làm dở. Cũng như trong lập trình, mỗi ngắt đều được quy định một mức ưu tiên khác nhau, được gọi là vector ngắt (vector ngắt có giá trị càng nhỏ thì độ ưu tiên càng cao), Reset là ngắt có mức ưu tiên cao nhất. Ngắt trong Arduino Trong khuôn khổ của Arduino và mục tiêu của sách là đơn giản hóa mọi vấn đề để các bạn mới bắt đầu dễ dàng tiếp cần thì chúng ta sẽ không đi sâu vào vấn đề này. Trong Arduino, chúng ta được hỗ trợ 2 loại ngắt như sau:
Để sử dụng ngắt chúng ta cần phải kết nối nút nhấn hoặc cảm biến vào hai chân này để tạo tín hiệu ngắt cho bộ xử lý. Tùy thuộc vào vi điều khiển trên board mà mỗi dòng Arduino có số lượng các ngắt khác nhau. Bạn có thể tham khảo bảng sau: Bảng 1. Số lượng ngắt trên các Board ArduinoBoardInt.0Int.1Int.2Int.3Int.4Int.5Uno. Ehternet 2 3 . . . . Mega2560 2 3 21 20 19 18 Leonardo 2 3 0 1 7 . Arduino hỗ trợ 2 lệnh giúp ta khai báo và hủy một ngắt bất kì một cách dễ dàng đó là
Lệnh attachInterrupt()
Trong mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital vẫn còn giữ ở mức điện áp thấp hoặc cao.
Lệnh detachInterrupt()
Ví dụYêu cầu Thiết kế hệ thống tự động bật sáng đèn khi trời tối. Linh kiện cần dùng
Cảm biến ánh sáng quang trở Hình 2. Cảm biến ánh sáng quang trở Relay Hình 3. Module Relay 5v 1 kênh. Relay là công tắc chuyển mạch (có thể đóng cắt điện áp DC và AC) được điều khiển bằng tín hiệu DC. Đây là linh kiện thụ động rất thường gặp trong các mạch điện tử. Relay có hai dạng phổ biến: Relay đóng mức thấp và đóng mức cao. Để hiểu thêm nguyên lý hoạt động của Relay, Module relay và cách sử dụng. Phân tích chương trình:
Kết nối Bảng 2. Bảng đấu nối board Arduino Uno và RelayArduino UnoRelay5V 5V GND GND A0 IN Bảng 3. Bảng đấu nối board Arduino Uno và Cảm biến ánh sángArduino UnoCảm biến ánh sáng5V 5V GND GND 2 DO Hình 4. Hình ảnh kết nối cảm biến ánh sáng quang trở và Relay với board Arduino Uno Source code
Trong ví dụ sử dụng Relay đóng mức cao. Khi sử dụng Relay đóng mức thấp thì cần phải đảo tín hiệu điều khiển. Timer/CounterGiới thiệuTimer/Counter là một trong những ngoại vi hoạt động độc lập và không thể thiếu trong bất kì vi điều khiển nào. Thực chất, Timer/Counter chỉ là một bộ đếm xung clock (có thể là xung nhịp nội bên trong vi điểu khiển hoặc xung clock bên ngoài). Nó tương tự như việc đếm giờ, thay vì ngồi canh đồng hồ và đếm từng giây thì chúng ta có thể đặt báo thức và làm những công việc khác, việc đếm thời gian thì giao cho đồng hồ xử lý. Quá trình hoạt động của Timer/Counter được quản lý bởi thanh ghi, chúng gồm thanh ghi chứa giá trị Timer/Counter đếm được và thanh ghi điều khiển các hoạt động đếm của nó. Trong khuôn khổ của sách này, chúng ta sẽ không tìm hiểu sâu về thanh ghi, nếu bạn có nhu cầu tìm hiễu rõ hơn có thể truy cập vào đường dẫn: arduino.vn/bai-viet/411-timercounter-tren-avrarduino. Timer/Counter được sử dụng rất nhiều trong các ứng dụng định thời, đếm sự kiện, tạo xung PWM,… Timer/Counter trong Arduino Một số định nghĩa mà các bạn cần lưu ý trong khi sử dụng Timer/Counter:
Chip ATMega328p (vi điều khiển của board Arduino Uno) bao gồm các Timer/Counter sau:
Khi sử dụng bộ Timer/Counter nào thì chúng ta cần lưu ý đến những hàm hoặc thư viện sử dụng bộ Timer/Counter đó nhằm tránh việc chương trình bị xung đột hoặc chạy không chính xác. Thư viện TimerOneTrên nền tảng Arduino và mục tiêu của eBook là đơn giản hóa cho những bạn mới tiếp cận, vì vậy chúng ta sẽ không điều khiển trực tiếp Timer bằng thanh ghi mà thay vào đó sẽ sử dụng thư viện TimerOne để tiếp cận với Timer/Counter. Đúng như tên gọi, thư viện sẽ sử dụng bộ Timer/Counter 1 (16 bit), ngoài ra nếu bạn muốn tìm hiểu rõ hơn về cách sử dụng cũng như quá trình hoạt động của tất cả Timer trong board Arduino Uno, bạn có thể tham khảo bài viết sau: arduino.vn/bai-viet/411-timercounter-tren-avrarduino. Các hàm cần chú ý trong thư viện:
Một số ví dụĐiều khiển LED Yêu cầu Sử dụng Timer để điều khiển LED trên board nháy sau mỗi 0,15s và hiển thị số lần LED sáng lên OLED. Linh kiện cần dùng
Phân tích:
Thư viện
Sau khi tải thư viện về, bạn mở phần mềm arduino, chọn Sketch → Import Library… → Add Library…. Sau đó chọn file .zip mà bạn vừa tải về để có thể sử dụng thư viện. Source code
Từ khóa volatile được dùng cho những biến sử dụng trong chương trình phục vụ ngắt và các chương trình khác. Điều khiển tốc độ quạt Yêu cầu Điều khiển tốc độ quạt sử dụng băm xung PWM. Thực tế chúng ta vẫn có thể điều khiển tốc độ quạt bằng hàm
Linh kiện sử dụng
Hình 5. FAN FAN nói chung hoặc quạt tản nhiệt nói riêng thông thường sẽ có 3 chân, chân (+) màu đỏ, chân GND màu đen và chân còn lại là chân điều khiển tốc độ. Kết nối Bảng 4. Bảng đấu nối board Arduino Uno và quạt miniArduino UnoFAN5V 5V GND GND 4 Xanh dương Hình 6. Hình ảnh kết nối quạt mini với board Arduino Uno Source code
Giải thích source code:
Điều khiển động cơ Servo bằng biến trở Servo là gì? Khác với những dạng động cơ thông thường chỉ quay liên tục khi cấp nguồn điện, Servo là dạng động cơ điều khiển được góc quay bằng xung PWM. Trên thị trường có rất nhiều loại động cơ Servo với kích thước, khối lượng, cấu tạo khác nhau, từ những loại Servo kích thước nhỏ gọn (dùng cho máy bay mô hình) đến những loại sỡ hữu moment xoắn cực lớn (vài chục N/m). Để điều khiển được góc quay Servo (trong khoảng từ 0o – 180o ) chúng ta sẽ dùng xung PWM như sau: Hình 7. Hình điều khiển Servo Biến trở Biến trở là linh kiện điện tử mà giá trị điện trở có thể thay đổi được. Chúng có thể được sử dụng trong các mạch điện để điều chỉnh hoạt động của mạch điện. Hình 8. Biến trở Yêu cầu
Sơ đồ kết nối Bảng 5. Bảng đấu nối board Arduino Uno với động cơ ServoArduino UnoServo Motor5V Màu Đỏ GND Màu nâu 9 Màu Vàng Bảng 6. Bảng đấu nối board Arduino Uno với Biến trởArduino UnoBiến trở5V 1 GND 3 A7 2 Hình 9. Hình ảnh kết nối biến trở và động cơ Servo với Arduino Uno Thư viện Trong ứng dụng này, chúng ta sẽ sử dụng thư viện servo.h Thư viện servo.h sử dụng bộ Timer/Counter 1, đóng vai trò quan trọng nếu bạn muốn làm về dự án robot. Nó cung cấp cho bạn một phương thức cực kì đơn giản để điều khiển động cơ Servo. Đồng thời, thư viện đã được tích hợp sẵn trong arduino IDE nên bạn không cần phải tải thêm thư viện khi sử dụng. Một số hàm cần chú ý như:
Source code
SummaryQua chương này, chúng ta đã tìm hiểu được những khái niệm cơ bản về ngắt (Interrupt) và Timer/counter, lý do tại sao chúng ta cần sử dụng nó trong các ứng dụng. Đồng thời chúng ta biết được thêm thư viện TimerOne giúp ta dễ dàng tiếp cận và làm chủ bộ Timer/Couter trên board Arduino Uno. Đối với những ví dụ đơn giản, khó có thể không nhận thấy sự khác biệt khi sử dụng ngắt (Interrupt) và Timer/Counter. Nhưng khi thực hiện những ví dụ phức tạp, cần khai thác tối ta khả năng xử lý của vi điều khiển thì đây sẽ là trợ thủ đắc lực cho bạn. |