Thiết kế hệ thống nhúng

Tài liệu Thiết kế hệ thống nhúng: THIẾT KẾ HỆ THỐNG NHÚNG 1 MỤC LỤC MỤC LỤC.......................................................................................................................................... 1 DANH MỤC HÌNH VẼ ..................................................................................................................... 4 Bài 1 ................................................................................................................................................... 5 TỔNG QUAN VỀ VI ĐIỀU KHIỂN PIC ......................................................................................... 5 1.1. Giới thiệu tổng quan về Pic .................................................................................................... 5 1.2. Kiến trúc Pic ........................................................................................................................... 6 1.2.1. Cấu trúc của PIC .................................................................................

pdf71 trang | Chia sẻ: putihuynh11 | Lượt xem: 502 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Thiết kế hệ thống nhúng, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
THIẾT KẾ HỆ THỐNG NHÚNG 1 MỤC LỤC MỤC LỤC.......................................................................................................................................... 1 DANH MỤC HÌNH VẼ ..................................................................................................................... 4 Bài 1 ................................................................................................................................................... 5 TỔNG QUAN VỀ VI ĐIỀU KHIỂN PIC ......................................................................................... 5 1.1. Giới thiệu tổng quan về Pic .................................................................................................... 5 1.2. Kiến trúc Pic ........................................................................................................................... 6 1.2.1. Cấu trúc của PIC ............................................................................................................ 6 1.2.2. RISC và CISC ................................................................................................................ 7 1.3. Vi điều khiển PIC 16F877A ................................................................................................... 7 1.3.1. Sơ đồ chân và kiểu đóng vỏ ........................................................................................... 7 1.3.2. Sơ đồi khối ..................................................................................................................... 9 1.3.3. Một số đặc điểm ............................................................................................................. 9 1.3.4. So sánh với vi điều khiển họ 8051 ............................................................................... 10 Bài 2 ................................................................................................................................................. 11 TỔNG QUAN VỀ LẬP TRÌNH NHÚNG TRÊN PIC .................................................................... 11 2.1. Ngôn ngữ lập trình và trình biên dịch .................................................................................. 11 2.1.1. Trên hệ điều hành window ........................................................................................... 11 2.1.2. Trên hệ điều hành Linux .............................................................................................. 12 2.1.3. Các mạch nạp và mạch gỡ rối chương trình ................................................................. 12 2.2. Lập trình PIC với CCS ......................................................................................................... 15 2.2.1. Tổng quan về CCS ....................................................................................................... 15 2.2.2. Tạo PROJECT đầu tiên trong CCS .............................................................................. 16 2.3. Biến, hàm, cấu trúc lệnh và các chỉ thị tiền xử lý ................................................................ 23 2.3.1. Biến, hằng, hàm và cấu trúc lệnh ................................................................................. 23 2.4. Mẫu chương trình cho lập trình CCS ................................................................................... 26 Bài 3 ................................................................................................................................................. 29 LẬP TRÌNH VÀO RA SỐ ............................................................................................................... 29 3.1. Các hàm xử lý bit và các phép toán ..................................................................................... 29 3.1.1. Hàm Shift_left, Shift_right ........................................................................................... 29 3.1.2. Hàm Bit_set, Bit_clear ................................................................................................. 29 3.1.3. Hàm Bit_test................................................................................................................. 29 3.1.4. Hàm Swap .................................................................................................................... 30 3.1.5. Hàm Make8 .................................................................................................................. 30 3.1.6. Hàm Make16 ................................................................................................................ 30 3.1.7. Make32 ......................................................................................................................... 30 3.2. Các hàm vào ra ..................................................................................................................... 31 3.2.1. Output_low (pin), Output_high (pin) ........................................................................... 31 3.2.2. Output_bit (pin, value) ................................................................................................. 31 3.2.3. Input (pin) .................................................................................................................... 32 3.2.4. Output_X (value) ......................................................................................................... 32 3.2.5. Input_X () ..................................................................................................................... 32 THIẾT KẾ HỆ THỐNG NHÚNG 2 3.2.6. Port_B_pullups ............................................................................................................. 32 3.2.7. Set_tris_X (value) ......................................................................................................... 32 3.3. Lập trình vào ra với led đơn, led 7 thanh và bàn phím ......................................................... 33 Bài 4 ................................................................................................................................................. 34 THỰC HÀNH: LẬP TRÌNH VÀO RA SỐ ..................................................................................... 34 Bài 5 ................................................................................................................................................. 34 LẬP TRÌNH VÀO RA TƯƠNG TỰ ............................................................................................... 34 5.1. Bộ chuyển đổi ADC và DAC ............................................................................................... 34 5.1.1 Tổng quan ..................................................................................................................... 34 5.1.2. Độ phân giải ................................................................................................................. 35 5.1.3. Điện áp tham chiếu ....................................................................................................... 36 5.2. Bộ chuyển đổi ADC trong PIC ............................................................................................. 36 5.2.1. ADC trong PIC 16F877A ............................................................................................. 37 5.2.2. Cấu hình bộ ADC trong CCS ....................................................................................... 39 5.2.3. Lập trình ứng dụng ....................................................................................................... 42 Bài 6 ................................................................................................................................................. 44 THỰC HÀNH: LẬP TRÌNH VÀO RA TƯƠNG TỰ ...................................................................... 44 Bài 7 ................................................................................................................................................. 44 LẬP TRÌNH VÀ XỬ LÝ NGẮT ..................................................................................................... 44 7.1. Tổng quan về ngắt trong PIC 16F877A ................................................................................ 44 7.2. Khai báo và sử dụng ngắt trong CCS ................................................................................... 45 7.3. Ngắt do sự thay đổi trạng thái của các chân trong PORTB .................................................. 48 7.4. Chế độ Sleep ......................................................................................................................... 50 7.5. Watch Dog Timer ................................................................................................................. 50 7.6. “Đánh thức” vi điều khiển .................................................................................................... 51 Bài 8 ................................................................................................................................................. 53 THẢO LUẬN LẬP TRÌNH XỬ LÝ NGẮT .................................................................................... 53 Bài 9 ................................................................................................................................................. 53 THỰC HÀNH: LẬP TRÌNH NGẮT................................................................................................ 53 Bài 10 ............................................................................................................................................... 53 TIMER TRONG PIC 16F877A ........................................................................................................ 53 10.1. Timer 0 ............................................................................................................................. 53 10.2. Timer 1 ............................................................................................................................. 55 10.3. Timer 2 ............................................................................................................................. 56 10.4. Khai báo Timer trong CCS ............................................................................................... 57 10.4.1. Các lệnh Timer0 ........................................................................................................... 57 10.4.2. Các lệnh Timer1 ........................................................................................................... 59 10.4.3. Các lệnh Timer2 ........................................................................................................... 59 10.5. Lập trình ứng dụng ........................................................................................................... 60 Bài 11 ............................................................................................................................................... 61 THỰC HÀNH: LẬP TRÌNH TIMER/COUNTER .......................................................................... 61 Bài 12 ............................................................................................................................................... 62 THẢO LUẬN VỀ TIMER/COUNTER ........................................................................................... 62 Bài 13 ............................................................................................................................................... 62 THIẾT KẾ HỆ THỐNG NHÚNG 3 THỰC HÀNH: LẬP TRÌNH TIMER/COUNTER (TIẾP) .............................................................. 62 Bài 14 ............................................................................................................................................... 62 LẬP TRÌNH TRUYỀN THÔNG ..................................................................................................... 62 14.1. Tổng quan về lập trình truyền thông ................................................................................ 62 14.2. Chuẩn RS232 ................................................................................................................... 62 14.3. Lập trình ứng dụng ........................................................................................................... 66 Bài 15 ............................................................................................................................................... 67 THỰC HÀNH: LẬP TRÌNH TRUYỀN THÔNG ........................................................................... 67 Bài 16 ............................................................................................................................................... 68 LẬP TRÌNH TRUYỀN THÔNG (tiếp) ........................................................................................... 68 16.1. Chuẩn I2C ........................................................................................................................ 68 16.2. Lập trình ứng dụng ........................................................................................................... 69 Bài 17: .............................................................................................................................................. 70 THỰC HÀNH: LẬP TRÌNH TRUYỀN THÔNG (TIẾP) ............................................................... 70 Bài 18: .............................................................................................................................................. 70 THẢO LUẬN VỀ LẬP TRÌNH TRUYỀN THÔNG ...................................................................... 70 Bài 19 ............................................................................................................................................... 70 LẬP TRÌNH NÂNG CAO ............................................................................................................... 70 19.1. GLCD ............................................................................................................................... 70 19.2. Thẻ nhớ ............................................................................................................................ 70 19.3. Ethernet ............................................................................................................................ 70 Bài 20: .............................................................................................................................................. 70 THỰC HÀNH: LẬP TRÌNH NÂNG CAO ..................................................................................... 70 Bài 21: .............................................................................................................................................. 70 BÀI TẬP, THẢO LUẬN TỔNG KẾT ............................................................................................ 70 TÀI LIỆU THAM KHẢO ................................................................................................................ 71 THIẾT KẾ HỆ THỐNG NHÚNG 4 DANH MỤC HÌNH VẼ Hình 1: Kiến truc Harvard và Von-Neumann..................................................................................... 6 Hình 2: Một số sơ đồ chân và kiểu đóng vỏ cho PIC 16F87XA ........................................................ 8 Hình 3: Sơ đồ khối của vi điều khiển PIC 16F877A .......................................................................... 9 Hình 4: Trình biên dịch MPASM trên .............................................................................................. 11 Hình 5: Mạch nạp PIC Kit 2 và PIC Kit 3 ........................................................................................ 13 Hình 6: MPLAB ICD3 - Công cụ nạp và gỡ rối ............................................................................... 14 Hình 7: MPLAB REAL ICE – In Circuit Emulator ......................................................................... 15 Hình 8: Giao diện PICC ................................................................................................................... 16 Hình 9: Cửa sổ Save As .................................................................................................................... 17 Hình 10: Tab General ....................................................................................................................... 18 Hình 11: Tab Communications......................................................................................................... 18 Hình 12: Tab SPI andLCD ............................................................................................................... 19 Hình 13: Tab Timer .......................................................................................................................... 20 Hình 14: Tab Analog ........................................................................................................................ 20 Hình 15: Tab Other ........................................................................................................................... 21 Hình 16: Tab Interrupts .................................................................................................................... 22 Hình 17: Tab Driver ......................................................................................................................... 22 Hình 18: Mạch flash ADC với 4 bộ so sánh ..................................................................................... 35 Hình 19: Minh họa tín hiệu Analog và digital của hàm sin .............................................................. 36 Hình 20: Sơ đồ khối bộ chuyển đổi ADC ......................................................................................... 38 Hình 21: Các cách lưu kết quả chuyển đổi ADC .............................................................................. 38 Hình 22: Sơ đồ kết nối với vi điều khiển PIC 16F877 ..................................................................... 42 Hình 23: Sơ đồ logic của các ngắt trong PIC 16F877A ................................................................... 45 Hình 24: Ghép nối điều khiển LED đơn ........................................................................................... 46 Hình 25: Sơ đồ ghép nối xử lý ngoài trên PortB .............................................................................. 49 Hình 26: Sơ đồ khối của bộ Timer0 ................................................................................................. 54 Hình 27: Sơ đồ khối của Timer1 ...................................................................................................... 55 Hình 28: Sơ đồ khối Timer2 ............................................................................................................. 57 Hình 29: Sơ đồ mạch ví dụ dùng Timer0 ......................................................................................... 60 Hình 30: Hình ảnh giao diện DB9 và DB25 ..................................................................................... 63 Hình 31: Sơ đồ chân trên giao diện DB9 và DB25 .......................................................................... 63 Hình 32: Sơ đồ khối các vi mạch MAX232, MAX233 .................................................................... 66 Hình 33: Sơ đồ ghép nối thiết bị chuẩn I2C ..................................................................................... 68 THIẾT KẾ HỆ THỐNG NHÚNG 5 ĐỀ CƯƠNG BÀI GIẢNG HỌC PHẦN THIẾT KẾ HỆ THỐNG NHÚNG Bài 1 TỔNG QUAN VỀ VI ĐIỀU KHIỂN PIC 1.1. Giới thiệu tổng quan về Pic PIC bắt nguồn là chữ viết tắt của "Programmable Intelligent Computer" (Máy tính khả trình thông minh) là một sản phẩm của hãng General Instrument đặt cho dòng sản phẩm đầu tiên của họ là PIC1650. PIC sử dụng tập lệnh RISC (Reduced Instructions Set Computer), với dòng PIC low-end (độ dài mã lệnh 12 bit, ví dụ: PIC12Cxxx) và mid-range (độ dài mã lệnh 14 bit, ví dụ: PIC16Fxxxx), tập lệnh bao gồm khoảng 35 lệnh, và 70 lệnh đối với các dòng PIC high-end (độ dài mã lệnh 16 bit, ví dụ: PIC18Fxxxx). Tập lệnh bao gồm các lệnh tính toán trên các thanh ghi, với các hằng số, hoặc các vị trí bộ nhớ, cũng như có các lệnh điều kiện, lệnh nhảy/gọi hàm, và các lệnh để quay trở về, nó cũng có các tính năng phần cứng khác như ngắt hoặc sleep (chế độ hoạt động tiết kiện điện). Microchip cung cấp môi trường lập trình MPLAB, nó bao gồm phần mềm mô phỏng và trình dịch ASM. Các dòng Pic hiện nay được phân chia theo các loại: - Vi điều khiển 8 bit: Pic10xxxx, Pic 12xxxx, Pic 14xxxx, Pic 16xxxx, Pic 17xxxx, Pic 18xxxx. - Vi điều khiển 16 bit: Điển hình ở đây là Pic 24, dsPIC30, dsPIC33F - Vi điều khiển 32 bit: PIC 32 Hiện nay có khá nhiều dòng PIC và có rất nhiều khác biệt về phần cứng, nhưng chúng ta có thể điểm qua một vài nét như sau: - FLASH và ROM có thể tuỳ chọn tùy theo từng loại chip - Các cổng Xuất/Nhập (I/O ports) (mức logic thường từ 0V đến 5. 5V, ứng với logic 0 và logic 1) - 8/16 Bit Timer - Các chuẩn giao Tiếp Ngoại Vi Nối Tiếp Đồng bộ/Không đồng bộ USART, AUSART, EUSARTs - Bộ chuyển đổi ADC Analog-to-Digital Converters, 8, 10/12... bit - Bộ so sánh điện áp (Voltage Comparators) - Các module Capture/Compare/PWM - MSSP Peripheral dùng cho các giao tiếp I2C, SPI, và I²S THIẾT KẾ HỆ THỐNG NHÚNG 6 - Bộ nhớ nội EEPROM - có thể ghi/xoá lên tới 1 triệu lần - FLASH (dùng cho bộ nhớ chương trình) có thể ghi/xóa 10. 000 lần (tiêu chuẩn) - Hỗ trợ giao tiếp USB - Hỗ trợ điều khiển Ethernet - Hỗ trợ giao tiếp CAN - Một số dòng có tích hợp bộ RF (PIC16F639, và rfPIC) - DSP những tính năng xử lý tín hiệu số (dsPIC) 1.2. Kiến trúc Pic 1.2.1. Cấu trúc của PIC Cấu trúc phần cứng của một vi điều khiển được thiết kế theo hai dạng kiến trúc: Kiến trúc Von Neuman và kiến trúc Harvard. Hình 1: Kiến truc Harvard và Von-Neumann Tổ chức phần cứng của Pic được thiết kế theo kiến trúc Harvard. Điểm khác biệt giữa kiến trúc Harvard và kiến trúc Von-Neumann là cấu trúc bộ nhớ dữ liệu và bộ nhớ chương trình. Đối với kiến trúc Von-Neumann, bộ nhớ dữ liệu và bộ nhớ chương trình nằm chung trong một bộ nhớ, do đó ta có thể tổ chức, cân đối một cách linh hoạt bộ nhớ chương trình và bộ nhớ dữ liệu. Tuy nhiên điều này chỉ có ý nghĩa khi tốc độ xử lý của CPU phải rất cao, vì với cấu trúc đó, trong cùng một thời điểm CPU chỉ có thể tương tác với bộ nhớ dữ liệu hoặc bộ nhớ chương trình. Như vậy có thể nói kiến trúc Von-Neumann không thích hợp với cấu trúc của một vi điều khiển. Đối với kiến truc Harvard, bộ nhớ dữ liệu và bộ nhớ chương trình tách ra thành hai bộ nhớ riêng biệt. Do đó trong cùng một thời điểm CPU có thể tương tác với cả hai bộ nhớ, như vậy tốc độ xử lý của vi điều khiển được cải thiện đáng kể. Một điểm cần lưu ý nữa là tập lệnh trong kiến trúc Harvard có thể được tối ưu theo yêu cầu kiến trúc của vi điều mà không phụ thuộc vào cấu trúc dữ liệu. Ví dụ, đối với vi điều khiển dòng 16F, độ dài lện luôn là 14 bit (trong khi dữ liệu được tổ Data memory CPU Program memory CPU Program and Data memory Harvard Von-Neumann THIẾT KẾ HỆ THỐNG NHÚNG 7 chức thành từng byte), còn đối với kiến truc Von-Neumann, độ dài lệnh luôn là bội số của 1 byte (do dữ liệu được tổ chức thành từng byte). 1.2.2. RISC và CISC Như đã trình bày, kiến truc Harvard là kiến trúc mới hơn so với kiến trục Von- Neumann. Khái ni Lệnh này được hình thành nhằm cải tiến tốc độ thực thi của một vi điều khiển. Qua việc tách rời bộ nhớ dữ liệu và bộ nhớ chương trình, bus của chương trình và bus dữ liệu, CPU có thể cùng một lúc truy xuất cả bộ nhớ chương trình và bộ nhớ dữ liệu, giúp tăng tốc độ xử lý của vi điều khiển lên gấp đôi. Đồng thời cấu trúc lệnh không còn phụ thuộc vào cấu trúc dữ liệu nữa mà có thể linh động điều chỉnh tùy theo khả năng và tốc độ của từng vi điều khiển. Và để cải thiện tốc độ thực thi lệnh, tập lệnh của họ vi điều khiển PIC được thiết kế sao cho chiều dài mã lệnh luôn cố định (ví dụ với họ 16Fxxxx chiều dài mã lệnh luôn là 14 bit) và cho phép thực thi lệnh trong một chu kỳ xung clock (ngoại trừ một số trường hợp đặc biệt như lệnh nhảy, gọi chương trình con cần hai chu kỳ xung đồng hồ). Điều này có nghĩa tập lệnh của vi điều khiển thuộc cấu trúc Harvard sẽ ít lệnh hơn, đơn giản hơn và ngắn hơn để đáp ứng yêu cầu mà mã hóa lệnh bằng một lượng bit nhất định. Vi điều khiển được tổ chức theo kiến trúc Harvard còn gọi là vi điều khiển RISC (Reduced Instructions Set Computer) hay vi điều khiển có tập lệnh rút gọn. Vi điều khiển được thiết kế theo kiến trúc Von-Neumann còn được gọi là vi điều khiển CISC (Complex Instructions Set Computer) hay vi điều khiển có tập lệnh phức tạp vì mã lệnh của nó không phải là một số cố định mà luôn là bội số của 8 bit. 1.3. Vi điều khiển PIC 16F877A 1.3.1. Sơ đồ chân và kiểu đóng vỏ THIẾT KẾ HỆ THỐNG NHÚNG 8 Hình 2: Một số sơ đồ chân và kiểu đóng vỏ cho PIC 16F87XA Hình 2 trình bày sơ đồ chân và kiểu đóng vỏ của Pic16F87XA. Trong đó: - Kiểu đóng vỏ 40-Pin PDIP: Pic16F87XA được đóng trong một vỏ có 44 chân, kích thước lớn, chân cắm hàn trên mạch, thích hợp lắp đặt cho các mạch có kích thước linh kiện lớn. - Kiểu đóng vỏ 44-Pin PLCC: là kiểu đóng vỏ kích thước IC nhỏ, có 4 hàng chân xung quanh, chân ngắn, thích hợp cho lắp mạch với linh kiện dán. - Kiểu đóng vỏ 44-Pin TQFP: gần tương tự kiểu đóng vỏ 44-Pin PLCC với kích thước chân dài hơn, dùng trên các mạch lắp linh kiện dán. Mặc dù được đóng vỏ khác nhau (kích thước lớn/nhỏ chênh lệch nhiều) song tính năng, khả năng hoạt động của Pic vẫn không thay đổi. THIẾT KẾ HỆ THỐNG NHÚNG 9 1.3.2. Sơ đồi khối Hình 3: Sơ đồ khối của vi điều khiển PIC 16F877A 1.3.3. Một số đặc điểm Đây là vi điều khiển thuộc họ PIC16Fxxx với tập lệnh gồm 35 lệnh có độ dài 14 bit. Mỗi lệnh đều được thực thi trong một chu kỳ xung clock. Tốc độ hoạt động tối đa cho phép là 20 MHz với một chu kỳ lệnh là 200ns. Bộ nhớ chương trình 8Kx14 bit, bộ nhớ dữ liệu 368x8 (368 byte) RAM và bộ nhớ dữ liệu EEPROM với dung lượng 256x8 (256 byte). Số PORT I/O là 5 với 33 pin I/O. Các đặc tính ngoại vi bao gồm các khối chức năng sau: THIẾT KẾ HỆ THỐNG NHÚNG 10 - Timer0: bộ đếm 8 bit với bộ chia tần số 8 bit. - Timer1: bộ đếm 16 bit với bộ chia tần số, có thể thực hiện chức năng đếm dựa vào xung clock ngoại vi ngay khi vi điều khiển hoạt động ở chế độ sleep. - Timer2: bộ đếm 8 bit với bộ chia tần số, bộ postcaler. - Hai bộ Capture/so sánh/điều chế độ rông xung. - Các chuẩn giao tiếp nối tiếp SSP (Synchronous Serial Port), SPI và I2C. - Chuẩn giao tiếp nối tiếp USART với 9 bit địa chỉ. - Cổng giao tiếp song song PSP (Parallel Slave Port) với các chân điều khiển RD, WR, CS ở bên ngoài. - Các đặc tính Analog: 8 kênh chuyển đổi ADC 10 bit. - Hai bộ so sánh. Bên cạnh đó là một vài đặc tính khác của vi điều khiển như: - Bộ nhớ flash với khả năng ghi xóa được 100. 000 lần. - Bộ nhớ EEPROM với khả năng ghi xóa được 1. 000. 000 lần. - Dữ liệu bộ nhớ EEPROM có thể lưu trữ trên 40 năm. - Khả năng tự nạp chương trình với sự điều khiển của phần mềm. - Nạp được chương trình ngay trên mạch điện ICSP (In Circuit Serial Programming). - Watchdog Timer với bộ dao động trong. - Chức năng bảo mật mã chương trình. - Chế độ Sleep. - Có thể hoạt động với nhiều dạng Oscillator khác nhau. 1.3.4. So sánh với vi điều khiển họ 8051 - Về kiến trúc VXL - Tốc độ làm việc - Bộ nhớ chương trình, dữ liệu, - Đặc điểm bộ lệnh - Các hỗ trợ vào ra số, vào ra tương tự - Hỗ trợ về truyền thông - Xử lý thời gian/bộ đếm (timer/counter) - Các tính năng khác THIẾT KẾ HỆ THỐNG NHÚNG 11 Bài 2 TỔNG QUAN VỀ LẬP TRÌNH NHÚNG TRÊN PIC 2.1. Ngôn ngữ lập trình và trình biên dịch 2.1.1. Trên hệ điều hành window a) Trình biên dịch MPASM (hợp ngữ) Microchip cung cấp trình biên dịch MPASM miễn phí, và đi kèm trong bộ cài MPLAB IDE. Khi không sử dụng trình soạn thảo chuyên dụng trong PIC, chúng ta hoàn toàn có thể sử dụng Notepad hoặc Notepad Plus,... để soạn thảo chương trình và sau đó trực tiếp chạy MPASMWIN. exe để biên dịch. Hình 4: Trình biên dịch MPASM trên b) Hi-Tech soft - Trình soạn thảo: HI-TIDE (Hitech IDE) - Trình biên dịch: HTPIC - Ngôn ngữ lập trình: C - Đây là trình biên dịch chuyên nghiệp dành cho PIC c) Microchip MPLAB C - Trình soạn thảo: MPLAB IDE - Trình biên dịch: C18 (dành cho PIC 18), C30 (dành cho PIC 24, dsPIC), C32 (dành cho PIC 32) - Ngôn ngữ lập trình: C THIẾT KẾ HỆ THỐNG NHÚNG 12 - MPLAB C không hỗ trợ cho PIC 10/12/16 do đó đây là một lựa chọn phù hợp cho những dòng PIC cao hơn. Tuy nhiên nếu muốn sử dụng trình hợp ngữ thì MPLAB cũng có thể giúp chúng ta thực hiện. d) CCSInfo - Trình soạn thảo: CCS IDE - Trình biên dịch: CCS C - Ngôn ngữ lập trình: C - Đây là trình biên dịch dễ dàng nhất cho người dùng, tuy nhiên các phiên bản CCS hỗ trợ các dòng chip mới thường rất chậm. Đây là công cụ phù hợp với mức độ sản xuất vừa và nhỏ và nó rất thuận tiện cho người mới bắt đầu hoặc chuyển từ vi điều khiển khác qua sử dụng PIC. e) Mikro Elektronika - Trình soạn thảo: MikroE IDE - Trình biên dịch: MikroC (ngôn ngữ C), MikroPascal (ngôn ngữ Pascal), MikroBasic (ngôn ngữ Basic) f) SourceBoost - Trình soạn thảo: SourceBoost IDE - Trình biên dịch: Boost C (ngôn ngữ C), Boost C++ (ngôn ngữ C++), BoostBasic (ngôn ngữ Basic), Novo RTOS (hệ điều hành), Flowcode (ngôn ngữ flowchart) - Đây là phần mềm được phát triển mạnh với nhiều ngôn ngữ lập trình khác nhau, đặc biệt là đây là phần mềm đầu tiên trong việc phát triển PIC trên nền tảng hướng đối tượng C++. 2.1.2. Trên hệ điều hành Linux a) Trình biên dịch hợp ngữ GPUTILS là một công cụ tổng hợp, bao gồm được phát triển từ năm 2001 và ngày nay được phát triển và hỗ trợ rất nhiều. b) PIKLab Trình biên dịch ngôn ngữ câp cấp mã nguồn mở cho PIC là SDCC và GCC. Bên cạnh các phần mềm mã nguồn mở, hai công ty CCSInfo và HI-TECH Soft cũng cung cấp phần mềm trên Linux 2.1.3. Các mạch nạp và mạch gỡ rối chương trình Nếu một vi điều khiển mà không có chương trình nằm bên trong nó (firmware) thì nó chưa thể thực hiện được một chức năng nào cả. Do đó, mạch nạp là một phần THIẾT KẾ HỆ THỐNG NHÚNG 13 không thể thiếu khi chúng tra nghiên cứu và sử dụng với vi điều khiển nói chung và với PIC nói riêng. Có rất nhiều mạch nạp trên thị trường thế giới cũng như Việt Nam. Tuy nhiên chúng ta có thể phân loại theo đối tượng sử dụng như sau: Mạch nạp và gỡ rối dành cho sinh viên: Loại này giá rẻ, chức năng tương đối bị hạn chế, và chủ yểu chỉ đảm nhiệm chức năng nạp chương trình (firmware). Hiện nay mạch nạp dành cho sinh viên rất phong phú, đặc biệt với mục tiêu hạ giá thành sản phẩm tới mức tối đa. Điển hình là một số mạch nạp sau: - Mạch nạp PICKit 2, PICKit 3 của microchip Tính năng: Nạp hầu hết các dòng sản phẩm Microchip PIC/dsPIC, hỗ trợ Programmer Go (Không cần sử dụng máy tính, nạp chương trình vào PICKit, sau đó cấp nguồn và bấm nút để nạp vào PIC), cấp nguồn từ USB Giá thành: Từ 30$ đến 50$ Hình 5: Mạch nạp PIC Kit 2 và PIC Kit 3 - Mạch gỡ rồi ICD2 LE (phiên bản giới hạn) Tính năng: nạp và debug hầu hết các dòng Microchip/dsPIC, không hỗ trợ nguồn từ ICDE LE. Bề ngoài nhìn giống PICKit 2 nhưng có màu xanh dương. Do đây là phiên bản giới hạn (limited Edition) nên sản phẩm không được phổ biến lắm. Giá thành: Từ 60$ đến 80$. - Mạch nạp PK2FUN của R&P Tính năng: giống với PICKit 2, nhưng bỏ đi 2 tính năng chính là tính năng Programmer To Go và tính năng cấp nguồn từ USB. Giá thành: Khoảng 10$ THIẾT KẾ HỆ THỐNG NHÚNG 14 - Mạch nạp Gusb của PduyTech Tính năng: Đây là một mạch phát triển từ mạch GTP-USB, sử dụng với chương trình nạp WinPIC800. Tuy nhiên, sau đó Pduytech đã phát triển lại phần mềm và phát triển khá tốt. Giá thành: Khoảng 10$ Mạch nạp, gỡ rối dành cho nhà thiết kế: Loại này trong bị nhiều tính năng hơn, chủ yếu tập trung vào tính năng gỡ rối và mô phỏng. Đây là phiên bản trả phí, với các nhà thiết kế ở Việt Nam thường chấp nhận bỏ qua tính năng mô phỏng (Emulator) mà chỉ dừng ở tính năng gỡ rồi (debugger) nhằm giảm chi phí trang thiết bị. Một số sản phẩm tiểu biểu: - ICD3 – In Circuit Debugger 3 Tính năng: Là một phiên bản cải tiến từ ICD2, tuy nhiên hiện nay ICD2 không còn sản xuất nữa, ICD3 tăng tốc độ nạp chip đáng kế. Giá thành: Khoảng 200$ Hình 6: MPLAB ICD3 - Công cụ nạp và gỡ rối - REAL ICE – In Circuit Emulator Tính năng: Mô phỏng trực tiếp trên mạch, chủ yếu sử dụng cho các mạch nạp phức tạp, thuật toán phức tạp Giá thành: Khoảng 550$ THIẾT KẾ HỆ THỐNG NHÚNG 15 Hình 7: MPLAB REAL ICE – In Circuit Emulator Mạch nạp dành cho nhà sản xuất: Chỉ tập trung vào tính năng duy nhất là tính năng nạp, điều quan trong nhất là phải nạp nhanh, thao tác đơn gian, bền vữ và đảm bảo cho công nhân kỹ thuật có thể sử dụng. Vấn đề chính của các nhà sản xuất chính là số giữa tốc độ nạp chip và số lượng nhân công. Một bài toán rất rõ ràng như sau: nếu khi nhà sản xuất lên tới khoảng 100000 sản phẩm mỗi năm, việc nạp chip trở thành một vấn đề lớn. Giải phải bắt buộc là phải nạp cùng lúc nhiều sản phẩm, vì thời gian nạp để cho chop gần như là khó có thể giam, tùy theo dung lượng của chip và kích thước firmware. Các loại mạch trên thị trường hiện nay cho phép nạp cúng lúc từ 4 đến 32 chip điển hình một số loại như sau: - SoftLog IC2GANG Tính năng: mỗi lần nạp 4 chip, có thể ghép nối với 16 mạch ICP2GANG với nhau để nạp tới 64 chip cùng lúc. Giá thành: Khoảng 1600$ - CCSInfo PRIME8 Tính năng: Mỗi lần nạp được 8 chip, không cần sử dụng máy tính, chỉ cần nạp firmware vào PRIM8 sau đó chỉ cần cấp nguồn để nạp Giá thành: Khoảng 900$ 2.2. Lập trình PIC với CCS 2.2.1. Tổng quan về CCS CCS là trình biên dịch lập trình ngôn ngữ C cho Vi điều khiển PIC của hãng Microchip. Chương trình là sự tích hợp của 3 trình biên dich riêng viết cho 3 dòng PIC khác nhau đó là: ‐ PCB cho dòng PIC 12‐bit opcodes ‐ PCM cho dòng PIC 14‐bit opcodes THIẾT KẾ HỆ THỐNG NHÚNG 16 ‐ PCH cho dòng PIC 16và 18‐bit Tất cả 3 trình biên dich này đuợc tích hợp lại vào trong một chương trình bao gồm cả trình soạn thảo và biên dịch là CCS. Giống như nhiều trình biên dịch C khác cho PIC, CCS giúp cho người sử dụng nắm bắt nhanh được vi điều khiển PIC và sử dụng PIC trong các dự án. Các chương trình diều khiển sẽ được thực hiện nhanh chóng và đạt hiệu quả cao thông qua việc sử dụng ngôn ngữ lập trình cấp cao – ngôn ngữ C 2.2.2. Tạo PROJECT đầu tiên trong CCS Để tạo một Project trong CCS có nhiều cách, có thể dùng ProjectWizard, ManualCreat, hay đơn giản là tạo một Files mới và thêm vào đó các khai báo ban đầu cần thiết và“bắt buộc”. Dưới đây sẽ trình bày cách tạo một project hợp lệ theo cả 3 phương pháp. Một điều ta cần chú ý khi tạo một Project đó là: khi tạo bắt cứ một Project nào mới thì ta nên tạo một thư mục mới với tên liên quan đến Project ta định làm, rồi lưu các files vào đó. Khi lập trình và biên dịch, CCS sẽ tạo ra rất nhiều files khác nhau, do đó nếu để chung các Project trong một thư mục sẽ rất mất thời gian trongviệc tìm kiếm sau này. Đây cũng là quy tắc chung khi ta làm việc với bất kỳ phần mềm nào, thiết kế mạch hay lập trình. Việc đầu tiên bạn cần làm là khởi động máy tính và bật chương trình PIC C Compiler. Tạo một PROJECT sử dụng PIC Wizard Trước chết bạn khởi động chương trình làm việc PICC Compiler. Từ giao diện chương trình bạn di chuột chọn Project ‐> New‐>PIC Wizard nhấn nút trái chuột để chọn. Hình 8: Giao diện PICC Sau khi nhấn chuột, một cửa sổ hiện ra yêu cầu ban nhập tên Files cần tạo. Bạn tạo một thư mục mới, vào thư mục đó và lưu tên files cần tạo tại đây. THIẾT KẾ HỆ THỐNG NHÚNG 17 Hình 9: Cửa sổ Save As Như vậy là xong bước đầu tiên. Sau khi nhấn nút Save, một cửa sổ NewProject hiện ra. Trong của sổ này bao gồm rất nhiều Tab, mỗi Tab mô tả về một vài tính năng của con PIC. Ta sẽ chọn tính năng sử dụng tại các Tab tương ứng. Dưới đây sẽ trình bày ý nghĩa từng mục chọn trong mỗi Tab. Các mục chọn này chính là đề cập đến các tính năng của một con PIC, tùy theo từng loại mà sẽ có các Tab tương ứng. Đối với từng dự án khác nhau, khi ta cần sử dụng tính năng nào của con PIC thì ta sẽ chọn mục đó. Tổng cộng có 13 Tab để ta lưa chọn, ta sẽ đi vào một số tab hay sử dụng a) Tab General Tab General cho phép ta lựa chọn loại PIC mà ta sử dụng và một số lựa chọn khác như chọn tần số thạch anh dao động, thiết lập các bit CONFIG nhằm thiết lập chế độ hoạt động cho PIC (hình dưới). - Device: Liệt kê danh sách các loại PIC12F, 16F, 18FTa sẽ chọn tên Vi điều khiển PIC mà ta sử dụng trong dự án. Lấy ví dụ chọn PIC16F877A - Oscilator Frequency: Tần số thạch anh ta sử dụng, chọn 20 MHz (tùy từng loại) - Fuses: Thiết lập các bit Config như: Chế độ dao động (HS, RC, Internal), chế độ bảovệ Code, Brownoutdetected - Chọn kiểu con trỏ RAM là 16bit hay 8bit THIẾT KẾ HỆ THỐNG NHÚNG 18 Hình 10: Tab General b) Tab Communications Tab Communications liệt kê các giao tiếp nối tiếp mà một con PIC hỗ trợ, thường là RS232 và I2C, cùng với các lựa chọn để thiết lập chế độ hoạt động cho từngloại giao tiếp. c) Giao tiếpRS232 Mỗi một Vi điều khiển PIC hỗ trợ một cổng truyền thông RS232 chuẩn. Tab này cho phép ta lựa chọn chân Rx, Tx, tốc độ Baud, Data bit, Bit Parity Hình 11: Tab Communications THIẾT KẾ HỆ THỐNG NHÚNG 19 d) Giao tiếp I2C Để sử dụng I2C ta tích vào nút chọn Use I2C, khi đó ta có các lựa chọn: Chân SDA, SCL, tốc độ truyền (Fast- Slow), chế độ Master hay Slave, địa chỉ cho Salve. e) Tab SPI and LCD Tab này liệt kê cho người dùng các lựa chọn đối với giao tiếp nối tiếp SPI, chuẩn giao tiếp tốc độ cao mà PIC hỗ trợ về phầncứng. Chú ý khi ta dùng I2C thì không thể dùng SPI và ngược lại. Để có thể sử dụng cả hai giao tiếp này cùng một lúc thì buộc một trong 2 giao tiếp phải lập trình bằng phần mềm (giồng như khi dùng I2C cho các chip AT8051, không có hỗ trợ phần cứng SSP). Phần cấuhình choLCD dành cho các chip dòng 18F và 30F. Hình 12: Tab SPI andLCD f) Tab Timer Liệt kê các bộ đếm/địnhthời mà các con PIC dòng Midrangecó: Timer0, timer1, timer2, WDT Trong các lựa chọn cấu hình cho các bộ đếm /định thời có: chọn nguồn xung đồng hồ (trong/ngoài), khoảng thời gian xảy ra tràn THIẾT KẾ HỆ THỐNG NHÚNG 20 Hình 13: Tab Timer g) Tab Analog Liệt kê các lựa chọn cho bộ chuyển đổi tương tự/số (ADC) của PIC. Tùy vàotừng IC cụthể mà cócáclựa chọn khácnhau, bao gồm: Lựa chọn cổng vào tương tự Chọn chânđiện áp lấymẫu (Vref) Chọn độ phângiải:8bit = 0~ 255 hay10bit = 0~1023 Nguồn xung đồng hồ cho bộ ADC (trong hay ngoài), từ đó mà ta có được tốc độ lấy mẫu, thường ta chọn là internal2-6 us. Khi khôngsử dụng bộ ADC ta chọn none Hình 14: Tab Analog THIẾT KẾ HỆ THỐNG NHÚNG 21 h) Tab Other Tab này cho phép ta thiết lập các thông số cho các bộ Capture/Comparator/PWM. Capture - Chọn bắt giữ xung theo sườn dương (risingedge) hay sườn âm (fallingedge) của xung vào - Chọn bắt giữ au 1, 4 hay 16 xung (copy giá trị của Timer X vào thanh ghi lưu trữ CCCPx sau1, 4 hay 16 xung). Compare Ta có các lựa chọn thực hiện lệnh khi xayư ra bằng nhau giữa 2 đối tượng so sánh là giá trị của Timer1 với giá trị lưu trong thanh ghi để so sánh. Bao gồm: - Thực hiệnngắt và thiết lập mức 0 - Thực hiệnngắt và thiết lập mức 1 - Thực hiệnngắt nhưng không thay đổi trạng thái của chân PIC. - Đưa Timer1 về 0 nhưng không thay đổi trạng thái chân. PWM - Điều chế độ rộng xung Lựa chọn về tần số xung ra và dutycycle. Ta có thể lựa chọn sẵn hay tự chọn tần số, tất nhiên tần số ra phải nằm trong một khoảng nhất định. Comparator - So sánh Lựa chọn mức điện áp so sánhVref. Có rất nhiều mức điện áp để ta lựa chọn. Ngoài ra ta còn có thể lựa chọn cho đầu vào của các bộ so sánh. Hình 15: Tab Other THIẾT KẾ HỆ THỐNG NHÚNG 22 i) Tab Interrupts và Tab Driver TabInterrupts cho phép ta lựa chọn nguồn ngắt mà ta muốn sử dụng. Tùy vào từng loại PIC mà số lượng nguồn ngắt khác nhau, bao gồm: ngắt ngoài 0 (INT0), ngắt RS232, ngắt Timer, ngắt I2C‐SPI, ngắt onchange PORTB. v. v TabDrivers được dùng để lựa chọn những ngoại vi mà trình dịch đã hỗ trợ các hàm giao tiếp. Đây là nhưng ngoại vi mà ta sẽ kết nối với PIC, trong các IC mà CCS hỗ trợ, đáng chú ý là các loại EEPROM như 2404, 2416, 2432, 9346, 9356Ngoài ra còn có IC RAM PCF8570, IC thời gian thực DS1302, Keypad3x4, LCD, ADCChi tiết ta có thể xem trong thư mục Driver của chươngtrình: \... \PICC\Drivers Hình 16: Tab Interrupts Hình 17: Tab Driver THIẾT KẾ HỆ THỐNG NHÚNG 23 Sau các bước chọn trên, ta nhấn OK để kết thúc quá trình tạo một Project trong CCS, một File ten_project. c được tạo ra, chứa những khai báo cần thiết cho PIC trong một Files ten_project. h. 2.3. Biến, hàm, cấu trúc lệnh và các chỉ thị tiền xử lý 2.3.1. Biến, hằng, hàm và cấu trúc lệnh Giống với ngôn ngữ lập trình C, tham khảo tài liệu lập trình c và CCS Chỉ thị tiền xử lý #ASM và #ENDASM Cho phép đặt một đoạn mã ASM giữa hai chỉ thị này, chỉ thị đặt trong hàm. CCS định nghĩa 1 biến 8 bit để giới hạn giá trị trả về cho hàm từ đoạn mã Assembly. Mã Assembly theo tập lệnh của vi điều khiển mà không phải theo kiểu mã của phần mềm hỗ trợ (MPLAB). #INCLUDE Cú pháp: #include Filename: tên file cho thiết bị *. h, *. c. Nếu chỉ định file ở đường dẫn khác thì thêm đường dẫn vào, luôn phải có khai báo chương trình viết cho VĐK nào và luôn đặt ở dòng đầu tiên Ví du: #include // Chương trình sử dụng vđk 16F877 #include #BIT, #BYTE, #LOCATE, #DEFENE #BIT Cú pháp: #BIT id = x. y id: tên biến, x: biến (8, 16, 32, bit) hay hằng số địa chỉ thanh ghi. y: vị trí bit trong x Tạo biến 1 bit đặt ở byte x vị trí bit y, tiện dùng kiểm tra hay gán trị cho bit thanh ghi. Điểm khác biệt so với dùng biến 1 bit từ khai báo int1 là: int1 tốn 1 bit bộ nhớ, đặt ở thanh ghi đa mục đích nào đó do CCS tự chọn, còn #BIT thì không tốn thêm bộ nhớ do id chỉ là danh định đại diện cho bit chỉ định ở biến x, thay đổi giá trị id (0 / 1) sẽ thay đổi giá trị bit tương ứng y do đó thay đổi trị x. VD: Int16 a=35; //a=00000000 00100011 #bit b= a. 11 //b=0 #BYTE Cú pháp: #BYTE id = x X: địa chỉ, id: tên biến THIẾT KẾ HỆ THỐNG NHÚNG 24 Gán tên biến id cho địa chỉ (thanh ghi) x, sau đó muốn gán hay kiểm tra địa chỉ x chỉ cần dùng id. Không tốn thêm bộ nhớ, tên id thường dùng tên gợi nhớ chức năng thanh ghi ở địa chỉ đó. Lưu ý rằng giá trị thanh ghi có thể thay đổi bất kỳ lúc nào do hoạt động chương trình nên giá trị id cũng tự thay đổi theo giá trị thanh ghi đó. Không nên dùng id cho thanh ghi đa mục đích như 1 cách dùng biến int8 vì CCS có thể dùng các thanh ghi này bất kỳ lúc nào cho chương trình, nếu muốn dùng riêng, hãy dùng #LOCATE. VD: #byte port_b = 0xc6; // 16F877:0xc6 là địa chỉ portb Muốn port b có giá trị 120 thì: port_b=120; #byte status = 0xc3 #LOCATE Cú pháp: #LOCATE id = x Làm việc như #byte nhưng có thêm chức năng bảo vệ không cho CCS sử dụng địa chỉ đó vào mục đích khác. VD: # LOCATE temp = 0xc20 // 0xc20:thanh ghi đa mục đích #DEFINE Cú pháp: #DEFINE id text Text: chuỗi hay số. Dùng định nghĩa giá trị. VD: #define a 12345 # DEVICE Cú pháp: #DEVICE chip option chip: tên VĐK sử dụng, không dùng tham số này nếu đã khai báo tên chip ở # include. option: toán tử tiêu chuẩn theo từng chip: * = 5 dùng pointer 5 bit (tất cả PIC) * = 8 dùng pointer 8 bit (PIC14 và PIC18) * = 16 dùng pointer 16 bit (PIC14, PIC 18) ADC = x sử dụng ADC x bit (8, 10,... bit tuỳ chip), khi dùng hàm read_adc (), sẽ trả về giá trị x bit. ICD = true: tạo mã tương thích debug phần cứng Microchip HIGH_INTS = TRUE : cho phép dùng ngắt ưu tiên cao - Khai báo pointer 8 bit, bạn sử dụng được tối đa 256 byte RAM cho tất cả biến chương trình. - Khai báo pointer 16 bit, bạn sử dụng được hết số RAM có của VDK - Chỉ nên dùng duy nhất 1 khai báo #device cho cả pointer và ADC. THIẾT KẾ HỆ THỐNG NHÚNG 25 VD: #device * = 16 ADC = 10 # ORG Cú pháp: #org start, end #org segment #org start, end { } Start, end: bắt đầu và kết thúc vùng ROM dành riêng cho hàm theo sau, hoặc để riêng không dùng VD: Org 0x30, 0x1F Void xu_ly () { } // hàm này bắt đầu ở địa chỉ 0x30 org 0x1E00 anotherfunc () { } //hàm này bắt đầu tuỳ ý ở 0x1E00 đến 0x1F00 Org 0x30, 0x1F { } // không có gì cả đặt trong vùng ROM này, thường thì không dùng ORG. #USE #USE delay (clock = speed) Speed: giá trị OSC mà bạn dùng. VD: dùng thạch anh dao động 40Mhz thì: #use delay (clock = 40000000) Chỉ khi có chỉ thị này thì trong chương trình bạn mới được dùng hàm delay_us () và delay_ms (). #USE fast_io (port) Port: là tên port:từ A-G (tuỳ chip) Dùng cái này thì trong chương trình khi dùng các lệnh io như output_low (), nó sẽ set chỉ với 1 lệnh, nhanh hơn so với khi không dùng chỉ thị này. Trong hàm main () bạn phải dùng hàm set_tris_x () để chỉ rõ chân vào ra thì chỉ thị trên mới có hiệu lực, không thì chương trình sẽ chạy sai. Không cần dùng nếu không có yêu cầu gì đặc biệt. VD: # use fast_io (A) #USE I2C (options) - thiết lập giao tiếp I2C. Option bao gồm các thông số sau, cách nhau bởi dấu phẩy: THIẾT KẾ HỆ THỐNG NHÚNG 26 Master : chip ở chế độ master Slave : chip ở chế độ slave SCL = pin : chỉ định chân SCL SDA = pin : chỉ định chân SDA ADDRESS = x : chỉ định địa chỉ chế độ slave FAST : chỉ định FAST I2C SLOW : chỉ định SLOW I2C RESTART_WDT: restart WDT trong khi chờ I2C_READ () FORCE_HW : sử dụng chúc năng phần cứng I2C (nếu chip hỗ trợ) VD: #use I2C (master, sda=pin_B0, scl = pin_B1) #use I2C (slave, sda= pin_C4, scl= pin_C3, address = 0xa00, FORCE_HW) #USE RS232 (options) Thiết lập giao tiếp RS232 cho chip (có hiệu lực sau khi nạp chương trình cho chip, không phải giao tiếp RS232 đang sử dụng để nạp chip). Option bao gồm: BAUD = x : thiết lập tốc độ baud rate: 19200, 38400, 9600,... PARITY = x : x= N, E hay O, với N: không dùng bit chẵn lẻ. XMIT = pin : set chân transmit (chuyển data) RCV = pin : set chân receive (nhận data) - Các thông số trên là những thông hay dùng nhất, các tham số khác sẽ bổ sung sau. VD: #use rs232 (baud=19200, parity=n, xmit=pin_C6, rcv=pin_C7) 2.4. Mẫu chương trình cho lập trình CCS a) Mô tả một số nội dung tiền xử lý #include16f877a. h:Đikèmchươngtrìnhdịch, chứakhaibáovềcácthanhghitrong mỗi con PIC, dùng cho việc cấuhình cho PIC. #include def_877a. h: Files do người lập trình tạo ra, chứa khai báo về cácthanhghitrongPICgiúpchoviêclậptrìnhđượcdễdanghơnvídụtacothểgánPORTB=0 xAA (chi tiết files này sẽ trình bày trong phần dưới đây) #device *=16 ADC = 10: Khai báo dùng con trỏ 8 hay 16 bit, bộ ADC là 8 hay 10 bit #FUSES NOWDT, HS: Khai báovề cấu hình cho PIC THIẾT KẾ HỆ THỐNG NHÚNG 27 #use delay (clock=20000000) : Tần số thạch anh sử dụng #use rs232 (baud=9600, ) : Khai báo cho giao tiếp nốitiếp RS232 #use i2c (master, SDA=PIN_C4, ) : Khai báo dùng I2C, chế độ hoạt động #include :Khai báo các files thư việnđược sử dụng vídụ LCD_lib_4bit. c #INT_xxx: Khai báo địa chỉ chương trình phục vụ ngắt Void tên_chương_trình (tên_biến) {}: Chương trình chínhhay chươngtrình con b) Viết chương trình trong CCS Đầu tiên là chỉ thị tiền xử lý #... có nhiệm vụ báo cáo cho CCS cần sử dụng những gì trong chương trình: Dùng loại chip nào, dùng ADC hay không? Sử dụng thạch anh.... Khai báo các biến Chương trình con: Có hoặc không Các hàm phục vụ ngắt theo sau bởi một tiền xử lý cho biết dùng ngắt nào: Nếu sử dụng ngắt Chương trình chính Chương trình được thể hiện qua đoạn code sau: #include #device PIC6f877*=16 ADC = 10 #use delay (clock = 20000000) .............. Int 16 a, b; Void CTC_ADC () { ............. } # INT_TIMER1 Void ngat_timer () { .......... } Main () { ............ } THIẾT KẾ HỆ THỐNG NHÚNG 28 Vi dụ //#include"E:\TES PIC_HIEU\NGAT\ngat timer0\ctrinh. h" #include #include #device *=16 adc=8 #use delay (clock=4000000) // su dung thach anh 20mhz #use fast_io (b) // dung voi cac lenh nhu output_low... nhanh hon binh thuong #byte portb=0x06 #byte portd=0x08 int16 count; int8 a; // chuong trinh ngat ngat timer0 #int_timer0 // cho phep vao ngat timer0 void interrupt_timer0 () { //set_timer0 (6) ;//T_dinhthi = 2* (256 - 6) *1us = 500us ++count; if (count==2000) //2000*500=1s {count=0; rotate_left (&a, 1) ; //xuay bien a 1 lan 1 bit } } // chuong trinh chinh void main () { set_tris_d (0) ; //cong B la cong xuat enable_interrupts (int_timer0) ; //cho phep ngat timer0 hoat dong setup_timer_0 (rtcc_internal|rtcc_div_2) ; //chon xung clock noi va chia tan enable_interrupts (global) ; //cho phep tat ca ngat hoat dong set_timer0 (6) ; a=0x01; while (true) { portd=a; } } THIẾT KẾ HỆ THỐNG NHÚNG 29 Bài 3 LẬP TRÌNH VÀO RA SỐ 3.1. Các hàm xử lý bit và các phép toán 3.1.1. Hàm Shift_left, Shift_right Cú pháp: Shift_right (address, byte, value) Shift_left (address, byte, value) Chức năng Dịch phải (trái) 1 bit vào 1 mảng hay 1 cấu trúc. Địa chỉ có thể là địa chỉ mảng hay địa chỉ trỏ tới cấu trúc (kiểu như &data). Bit 0 byte thấp nhất là LSB. 3.1.2. Hàm Bit_set, Bit_clear Cú pháp: Bit_set (var, bit) Dùng set=1 bit được chỉ định bởi vị trí bit trong biến var Bit_clear (var, bit) dùng xóa (set = 0) bit được chỉ định bởi vị trí bit trong biến var. var: biến 8, 16, 32 bit bất kỳ. bit: vị trí clear (set) : từ 0-7 (biến 8 bit), 0-15 (biến 16 bit), 0-31 (biến 32 bit). Hàm không trả về trị. VD: Int x; x=11; //x=1011 Bit_clear (x, 1) ; // x= 1001b = 9 3.1.3. Hàm Bit_test - Cú pháp: Bit_test (var, bit) - Tác dụng: Dùng kiểm tra vị trí bit trong biến var. - Hàm trả về 0 hay 1 là giá trị bit đó trong var. - var: biến 8, 16, 32 bit. - bit: vị trí bit trong var. Ví dụ: Giả sử có biến x 32 bit đếm từ 0 lên và muốn kiểm tra xem nó có lớn hơn 4096 không (4096= 2^12 =1000000000000b) : If (x >= 4096)... // phép kiểm tra này mất ~5 us Trong 1 vòng lặp, việc kiểm tra thường xuyên như vậy sẽ làm mất 1 thời gian đáng kể. Để tối ưu, chỉ cần dùng: if (bit_test (x, 12) ) : chỉ mất ~ 0. 4 us. (20 Mhz thạch anh). Do đó việc kiểm tra đếm lên tới những giá trị đặc biệt (2^ i) thì dùng hàm này rất tiện lợi. THIẾT KẾ HỆ THỐNG NHÚNG 30 3.1.4. Hàm Swap - Cú pháp: Swap (var) - var: biến 1 byte - Hàm này đảo vị trí 4 bit trên với 4 bit dưới của var, tương đương var = (var>>4) | (var << 4) - Hàm không trả về trị. VD: X= 5; //x=00000101b Swap (x) ; //x = 01010000b = 80 3.1.5. Hàm Make8 - Cú pháp: Make8 (var, offset) - Hàm này trích 1 byte từ biến var. - var: biến 8, 16, 32 bit. - offset: là vị trí của byte cần trích (0, 1, 2, 3). - Hàm trả về giá trị byte cần trích. VD: Int16 x = 1453; // x=0x5AD Y = Make (x, 1) ; //Y= 5 = 0x05 3.1.6. Hàm Make16 - Cú pháp: Make16 (varhigh, varlow) - Tác dung: Hàm trả về giá trị 16 bit kết hợp từ 2 biến 8 bit varhigh và varlow Byte cao là varhigh, thấp là varlow 3.1.7. Make32 - Cú pháp: Make32 (var1, var2, var3, var4) - Trả về giá trị 32 bit kết hợp từ các giá trị 8 bit hay 16 bit từ var1 tới var4. Trong đó var2 đến var4 có thể có hoặc không. Giá trị var1 sẽ là MSB, kế tiếp là var2,... Nếu tổng số bit kết hợp ít hơn 32 bit thì 0 được thêm vào MSB cho đủ 32 bit. VD: Int a=0x01, b=0x02, c=0x03, d=0x04; // các giá trị hex Int32 e; e = make32 (a, b, c, d) ; // e = 0x01020304 e = make32 (a, b, c, 5) ; // e = 0x01020305 e = make32 (a, b, 8) ; // e = 0x00010208 THIẾT KẾ HỆ THỐNG NHÚNG 31 e = make32 (a, 0x1237) ; // e = 0x00011237 3.2. Các hàm vào ra 3.2.1. Output_low (pin), Output_high (pin) - Tác dụng: + Dùng thiết lập mức 0 (low, 0V) hay mứ c 1 (high, 5V) cho chân IC, pin chỉ vị trí chân, + Hàm sẽ đặt pin làm ngõ ra. + Hàm này dài 2-4 chu kỳ máy. Cũng có thể xuất xung dùng set_tris_X () và #use fast_io. Ví dụ: Chương trình sau xuất xung vuông chu kỳ 500ms, duty =50% ra chân B0, nối B0 với 1 led sẽ làm nhấp nháy led. #include #use delay (clock=20000000) Main () { while (1) { output_high (pin_B0) ; Delay_ms (250) ; // delay 250ms Output_low (pin_B0) ; Delay_ms (250) ; } } 3.2.2. Output_bit (pin, value) - Pin: tên chân của vi điều khiển - value: có giá trị 0 hoặc 1 - Hàm này cũng xuất giá trị 0 / 1 trên pin, tương tự 2 hàm trên. Thường dùng nó khi giá trị ra tuỳ thuộc giá trị biến 1 bit nào đó, hay muốn xuất đảo của giá trị ngõ ra trước đó. Ví dụ: Khai báo int1 x; // x mặc định = 0 Trong hàm main: Main () { while (1) { output_bit (pin_B0, !x) ; Delay_ms (250) ; THIẾT KẾ HỆ THỐNG NHÚNG 32 } } Chương trình trên cũng xuất xung vuông chu kỳ 500ms, duty =50% 3.2.3. Input (pin) Hàm này trả về giá trị 0 hay 1 là trạng thái của chân IC và có giá trị là 1 bit 3.2.4. Output_X (value) - X là tên port có trên chip. - Value là giá trị 1 byte. - Hàm này xuất giá trị 1 byte ra port. Tất cả chân của port đó đếu là ngõ ra. Ví dụ: Output_B (212) ; // xuất giá trị 11010100 ra port B 3.2.5. Input_X () - X: là tên port (a, b, c, d e) của PIC - Hàm này trả về giá trị 8 bit là giá trị đang hiện hữu của port đó. Ví dụ: m=input_E () ; 3.2.6. Port_B_pullups - Hàm này thiết lập ngõ vào port B pullup. Value =1 sẽ kích hoạt tính năng này và value =0 sẽ ngừng. - Chỉ các chip có port B có tính năng này mới dùng hàm này. 3.2.7. Set_tris_X (value) - Hàm này định nghĩa chân IO cho 1 port là ngõ vào hay ngõ ra. Chỉ được dùng với #use fast_IO. Sử dụng #byte để tạo biến chỉ đến port và thao tác trên biến này chính là thao tác trên port. - Value là giá trị 8 bit. Mỗi bit đại diện 1 chân và bit=0 sẽ set chân đó là ngõ vào, bit= 1 set chân đó là ngõ ra. Ví dụ: Chương trình sau cho phép thao tác trên portB: #include #use delay (clock=20000000) #use Fast_IO (B) #byte portB = 0x6 // 16F877 có port b ở địa chỉ 6h #bit B0 = portB. 0 // biến B0 chỉ đến chân B0 #bit B1=portB. 1 // biến B1 chỉ đến chân B1 #bit B2=portB. 2 // biến B2 chỉ đến chân B2 THIẾT KẾ HỆ THỐNG NHÚNG 33 #bit B3=portB. 3 // biến B3 chỉ đến chân B3 #bit B4=portB. 4 // biến B4 chỉ đến chân B4 #bit B5=portB. 5 // biến B5 chỉ đến chân B5 #bit B6=portB. 6 // biến B6 chỉ đến chân B6 #bit B7=portB. 7 // biến B7 chỉ đến chân B7 Main () { set_tris_B (126) ; //portB=01111110 b // B0 là ngõ vào, thường làm ngắt ngoài //B1... B6 là ngõ ra, ví dụ làm 6 ngõ ra điều chế PWM //B7 là ngõ vào, Vd là nhận tín hiệu cho phép chẳng hạn if (B7) //nếu ngõ vào chân B7 là 1 thì xuất 3 cặp xung đối nghịch { B1 = 1; B2 = 0; B3 = 1; B4 = 0; B5 = 1; B6 = 0; } Else B1=B2=B3=B4=B5=B6= 0; } Chú ý: - Set_tris_B (0) : port B =00000000: tất cả chân portB là ngõ ra - Set_tris_B (1) : portB = 00000001: chỉ B0 là ngõ vào, còn lại là ngõ ra - Set_tris_B (255) : portB=11111111: tất cả chân portB là ngõ vào 3.3. Lập trình vào ra với led đơn, led 7 thanh và bàn phím - Sử dụng hàm set_tris_X () để thiết lập trạng thái cho cổng ứng dụng cho việc nhập hay xuất. Nếu đường tín hiệu vào phải thiết lập “1”, đường ra phải thiết lập “0”. - Với LED đơn thực hiện bật tắt theo 2 phương pháp: active “1” và active “0” tùy theo cách ghép nối LED. - LED 7 thanh có thể điều khiển theo 2 phương pháp là quét từng thanh hoặc sử dụng IC chuyên dụng để chốt tín hiệu cho từng thanh. THIẾT KẾ HỆ THỐNG NHÚNG 34 Bài 4 THỰC HÀNH: LẬP TRÌNH VÀO RA SỐ Chi tiết theo cuốn bài tập thực hành Bài 5 LẬP TRÌNH VÀO RA TƯƠNG TỰ 5.1. Bộ chuyển đổi ADC và DAC 5.1.1 Tổng quan Trong các ứng dụng đo lường và điều khiển bằng vi điều khiển bộ chuyển đổi tương tự-số là một thành phần rất quan trọng. Dữ liệu trong thực tế là các dữ liệu tương tự (analog). Ví dụ nhiệt độ không khí buổi sáng là 250C và buổi trưa là 320C, giữa hai mức giá trị này có vô số các giá trị liên tục mà nhiệt độ phải “đi qua” để có thể đạt mức 320 C từ 250C, đại lượng nhiệt độ như thế gọi là một đại lượng analog. Trong khi đó, rõ ràng vi điều khiển là một thiết bị số (digital), các giá trị mà một vi điều khiển có thể thao tác là các con số rời rạc vì thực chất chúng được tạo thành từ sự kết hợp của hai mức 0 và 1. Ví dụ chúng ta muốn dùng một thanh ghi 8 bit trong vi điều khiển để lưu lại các giá trị nhiệt độ từ 00 C đến 2550C, như chúng ta đã biết, một thanh ghi 8 bit có thể chứa tối đa 256 (28) giá trị nguyên từ 0 đến 255, như thế các mức nhiệt độ không nguyên như 28. 123 0C sẽ không được ghi lại. Nói cách khác, chúng ta đã “số hóa” (digitalize) một dữ liệu analog thành một dữ liệu số (digital signal). Quá trình “số hóa” này thường được thực hiện bởi một thiết bị gọi là “bộ chuyển đổi tương tự - số” hay gọi tắt là ADC (Analog to Digital Converter). Có rất nhiều phương pháp chuyển đổi ADC trong đó phương pháp chuyển đổi trực tiếp (direct converting) hoặc flash ADC là phương pháp cơ bản nhất. Các bộ chuyển đổi ADC theo phương pháp này được cấu thành từ một dãy các bộ so sánh, các bộ so sánh được mắc song song và được kết nối trực tiếp với tín hiệu analog cần chuyển đổi. Một điện áp tham chiếu (reference) và một mạch chia áp được sử dụng để tạo ra các mức điện áp so sánh khác nhau cho mỗi bộ so sánh. Hình dưới mô tả một bộ chuyển đổi flash ADC có 4 bộ so sánh, Vin là tín hiệu analog cần chuyển đổi và giá trị sau chuyển đổi là các con số tạo thành từ sự kết hợp các mức nhị phân trên các chân Vo. Trong hình dưới, ta thấy rằng do ảnh hưởng của mạch chia áp (các điện trở mắc nối tiếp từ điện áp +15V đến ground), điện áp trên chân âm của các bộ so sánh sẽ khác nhau. Trong lúc chuyển đổi, giả sử điện áp Vin lớn hơn điện áp “V-“ của bộ so sánh 1 (opamp ở phía thấp nhất trong mạch) nhưng lại nhỏ hơn điện áp V- của các bộ so sánh khác, khi đó ngõ Vo1 ở mức 1 và các ngõ Vo khác ở THIẾT KẾ HỆ THỐNG NHÚNG 35 mức 0, chúng ta thu được một kết quả số. Một cách tương tự, nếu tăng điện áp Vin ta thu được các tổ hợp số khác nhau. Với mạch điện có 4 bộ so sánh như trong hình 1, sẽ có tất cả 5 trường hợp có thể xảy ra, hay nói theo cách khác điện áp analog Vin được chia thành 5 mức số khác nhau. Tuy nhiên, chú ý là các ngõ Vo không phải là các bit của tín hiệu số ngõ ra, chúng chỉ là đại diện để tổ hợp thành tín hiệu số ngõ ra, dễ hiểu hơn chúng ta không sử dụng được các bit Vo trực tiếp mà cần một bộ giải mã (decoder). Hình 18: Mạch flash ADC với 4 bộ so sánh Bảng 1: Giá trị số ngõ ra sau khi giải mã 5.1.2. Độ phân giải Như trong ví dụ trên, nếu mạch điện có 4 bộ so sánh, ngõ ra digital sẽ có 5 mức giá trị. Tương tự nếu mạch điện có 7 bộ so sánh thì sẽ có 8 mức giá trị có thể ở ngõ ra digital, khoảng cách giữa các mức tín hiệu trong trường hợp 8 mức sẽ nhỏ hơn trường hợp 4 mức. Nói cách khác, mạch chuyển đổi với 7 bộ so sánh có giá trị THIẾT KẾ HỆ THỐNG NHÚNG 36 digital ngõ ra “mịn” hơn khi chỉ có 4 bộ, độ “mịn” càng cao tức độ phân giải (resolution) càng lớn. Khái niệm độ phân giải được dùng để chỉ số bit cần thiết để chứa hết các mức giá trị digital ngõ ra. Trong trường hợp có 8 mức giá trị ngõ ra, chúng ta cần 3 bit nhị phân để mã hóa hết các giá trị này, vì thế mạch chuyển đổi ADC với 7 bộ so sánh sẽ có độ phân giải là 3 bit. Một cách tổng quát, nếu một mạch chuyển đổi ADC có độ phân giải n bit thì sẽ có 2n mức giá trị có thể có ở ngõ ra digital. Để tạo ra một mạch chuyển đổi flash ADC có độ phân giải n bit, chúng ta cần đến 2n-1 bộ so sánh, giá trị này rất lớn khi thiết kế bộ chuyển đổi ADC có độ phân giải cao, vì thế các bộ chuyển đổi flash ADC thường có độ phân giải ít hơn 8 bit. Độ phân giải liên quan mật thiết đến chất lượng chuyển đổi ADC, việc lựa chọn độ phân giải phải phù hợp với độ chính xác yêu cầu và khả năng xử lý của bộ điều khiển. Trong hình phía dưới mô tả một ví dụ “số hóa” một hàm sin analog thành dạng digital. Hình 19: Minh họa tín hiệu Analog và digital của hàm sin 5.1.3. Điện áp tham chiếu Cùng một bộ chuyển đổi ADC nhưng có người muốn dùng cho các mức điện áp khác nhau, ví dụ người A muốn chuyển đổi điện áp trong khoảng 0-1V trong khi người B muốn dùng cho điện áp từ 0V đến 5V. Rõ ràng nếu hai người này dùng 2 bộ chuyển đổi ADC đều có khả năng chuyển đổi đến điện áp 5V thì người A đang “phí phạm” tính chính xác của thiết bị. Vấn đề sẽ được giải quyết bằng một đại lượng gọi là điện áp tham chiếu - Vref (reference voltage). Điện áp tham chiếu thường là giá trị điện áp lớn nhất mà bộ ADC có thể chuyển đổi. Trong các bộ ADC, Vref thường là thông số được đặt bởi người dùng, nó là điện áp lớn nhất mà thiết bị có thể chuyển đổi. Ví dụ, một bộ ADC 10 bit (độ phân giải) có Vref=3V, nếu điện áp ở ngõ vào là 1V thì giá trị số thu được sau khi chuyển đổi sẽ là: 1023x (1/3) =314. Trong đó 1023 là giá trị lớn nhất mà một bộ ADC 10 bit có thể tạo ra (1023=210-1). Vì điện áp tham chiếu ảnh hưởng đến độ chính xác của quá trình chuyển đổi, chúng ta cần tính toán để chọn 1 điện áp tham chiếu phù hợp, không được nhỏ hơn giá trị lớn nhất của input nhưng cũng đừng quá lớn. 5.2. Bộ chuyển đổi ADC trong PIC THIẾT KẾ HỆ THỐNG NHÚNG 37 Các bộ ADC trong vi điều khiển nói chung và trong PIC nói riêng có độ phân giải khác nhau, có thể là 10bit, 12bit, 16bit, 24bit... Tốc độ lấy mẫu trong ADC nhanh hay chậm, tùy từng ứng dụng mà ta chọn tốc độ cho thích hợp. Với vi điều khiển PIC là một trong những dòng vi điều khiển có phần giao tiếp ngoại vi mạnh và đa dạng. Bên trong PIC đã tích hợp sẵn một bộ ADC thường có độ phân giải là 8bit hay 10bit (có thể cao hơn tùy dòng PIC). 5.2.1. ADC trong PIC 16F877A PIC16F877A có 8 ngõ vào analog (RA4:RA0 và RE2:RE0). Hiệu điện thế chuẩn VREF có thể được lựa chọn là VDD, VSS hay hiệu điện thể chuẩn được xác lập trên hai chân RA2 và RA3. Kết quả chuyển đổi từ tín tiệu tương tự sang tín hiệu số là 10 bit số tương ứng và được lưu trong hai thanh ghi ADRESH:ADRESL. Khi không sử dụng bộ chuyển đổi ADC, các thanh ghi này có thể được sử dụng như các thanh ghi thông thường khác. Khi quá trình chuyển đổi hoàn tất, kết quả sẽ được lưu vào hai thanh ghi ADRESH:ADRESL, bit (ADCON0) được xóa về 0 và cờ ngắt ADIF được set. Quy trình chuyển đổi từ tương tự sang số bao gồm các bước sau: 1. Thiết lập các thông số cho bộ chuyển đổi ADC: - Chọn ngõ vào analog, chọn điện áp mẫu (dựa trên các thông số của thanh ghi ADCON1) - Chọnh kênh chuyển đổi AD (thanh ghi ADCON0) - Chọn xung clock cho kênh chuyển đổi AD (thanh ghi ADCON0) - Cho phép bộ chuyển đổi AD hoạt động (thanh ghi ADCON0) 2. Thiết lập các cờ ngắt cho bộ AD - Clear bit ADIF - Set bit ADIE - Set bit PEIE - Set bit GIE 3. Đợi cho tới khi quá trình lấy mẫu hoàn tất 4. Bắt đầu quá trình chuyển đổi (set bit) 5. Đợi cho tới khi quá trình chuyển đổi hoàn tất bằng cách: - Kiểm tra bit. Nếu =0, quá trình chuyển đổi đã hoàn tất - Kiểm tra cờ ngắt 6. Đọc kết quả chuyển đổi và xóa cờ ngắt, set bit (nếu cần tiếp tục chuyển đổi) 7. Tiếp tục thực hiện các bước 1 và 2 cho quá trình chuyển đổi tiếp theo THIẾT KẾ HỆ THỐNG NHÚNG 38 Hình 20: Sơ đồ khối bộ chuyển đổi ADC Cần chú ý là có hai cách lưu kết quả chuyển đổi AD, việc lựa chọn cách lưu được điều khiển bởi bit ADFM và được minh họa cụ thể trong hình sau: Hình 21: Các cách lưu kết quả chuyển đổi ADC Các thanh ghi liên quan đến bộ chuyển đổi ADC bao gồm: - INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh) : cho phép các ngắt (các bit GIE, PEIE). THIẾT KẾ HỆ THỐNG NHÚNG 39 - PIR1 (địa chỉ 0Ch) : chứa cờ ngắt AD (bit ADIF). - PIE1 (địa chỉ 8Ch) : chứa bit điều khiển AD (ADIE). - ADRESH (địa chỉ 1Eh) và ADRESL (địa chỉ 9Eh) : các thanh ghi chứa kết quả chuyển đổi AD. - ADCON0 (địa chỉ 1Fh) và ADCON1 (địa chỉ 9Fh) : xác lập các thông số cho bộ chuyển đổi AD. - PORTA (địa chỉ 05h) và TRISA (địa chỉ 85h) : liên quan đến các ngõ vào analog ở PORTA. - PORTE (địa chỉ 09h) và TRISE (địa chỉ 89h) : liên quan đến các ngõ vào analog ở PORTE. 5.2.2. Cấu hình bộ ADC trong CCS Thông dụng nhất khi dùng ADC là sử dụng 1 biến trở, điều chỉnh bởi 1 nút vặn, qua đó thu được 1 điện áp nhỏ hơn điện áp tham chiếu (Vref – áp max), đưa vào chân biến đổi ADC, kết quả cho 1 giá trị số ADC 8 bit (0-255) hay ADC 10 bit (0- 1023). Thường thì áp Vref lấy bằng Vdd (5V). Trên các PIC có ngõ AVdd và AVss (PIC 18), thường thì bạn luôn nối AVdd tới Vdd, AVss tới Vss để đảm bảo họat động cho lập trình qua ICD 2. Các hàm phục vụ ADC Setup_ADC (mode) : Không trả về giá trị. Dùng xác định cách thức hoạt động bộ biến đổi ADC. Tham số mode tuỳ thuộc file thiết bị *. h có tên tương ứng tên chip bạn đang dùng, nằm trong thư mục DEVICES của CCS. Muốn biết có bao nhiêu tham số có thể dùng cho chip đó, ta có thể mở file tương ứng đọc, tìm tới chỗ các định nghĩa cho chức năng ADC dùng cho chip đó tương ứng với hàm này. Sau đây là các giá trị mode của 16F877, (1 số khác có thể không có hoặc có thêm như 16F877A có thêm 1 số thứ là ADC_CLOCK_DIV_2/4/8/16/32/64... ) : - ADC_OFF: Tắt hoạt động ADC (tiết kiệm điện, dành chân cho hoạt động khác). - ADC_CLOCK_INTERNAL: thời gian lấy mẫu bằng xung clock IC (mất 2-6 us) thường là chung cho các chip. - ADC_CLOCK_DIV_2: thời gian lấy mẫu bằng xung clock / 2 (mất 0. 4 us trên thạch anh 20MHz) - ADC_CLOCK_DIV_8: thời gian lấy mẫu bằng xung clock / 8 (1. 6 us) - ADC_CLOCK_DIV_32 : thời gian lấy mẫu bằng xung clock / 32 (6. 4 us) Setup_ADC_ports (value) : Xác định chân lấy tín hiệu analog và điện thế chuẩn sử dụng. Tùy thuộc bố trí chân trên chip, số chân và chân nào dùng cho ADC THIẾT KẾ HỆ THỐNG NHÚNG 40 và số chức năng ADC mỗi chip mà value có thể có những giá trị khác nhau. Xem file tương ứng trong thư mục DEVICES để biết số chức năng tương ứng chip đó. Để tương thích chương trình viết cho phiên bản cũ, 1 số tham số có 2 tên khác nhau (nhưng cùng 15 chức năng do định nghĩa cùng địa chỉ). Lưu ý: - Vref: áp chuẩn, - Vdd: áp nguồn. Sau đây là các giá trị cho value (chỉ dùng 1 trong các giá trị) của 16F877: - ALL_ANALOGS: dùng tất cả chân sau làm analog: A0 A1 A2 A3 A5 E0 E1 E2 (Vref=Vdd) - NO_ANALOG: không dùng analog, các chân đó sẽ là chân I /O. - AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF : A0 A1 A2 A5 E0 E1 E2 VRefh=A3 - AN0_AN1_AN2_AN3_AN4: A0 A1 A2 A3 A5 (tên thì giống nhau cho tất cả thiết bị nhưng 16F877 chỉ có portA có 5 chân nên A0, A1, A2, A5 được dùng, A6, A7 không có) - AN0_AN1_AN3: A0 A1 A3, Vref = Vdd - AN0_AN1_VSS_VREF: A0 A1 VRefh = A3 - AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF : A0 A1 A5 E0 E1 E2 VRefh=A3, VRefl=A2. - AN0_AN1_AN2_AN3_AN4_AN5: A0 A1 A2 A3 A5 E0 - AN0_AN1_AN2_AN4_AN5_VSS_VREF : A0 A1 A2 A5 E0 VRefh=A3 - AN0_AN1_AN4_AN5_VREF_VREF: A0 A1 A5 E0 VRefh=A3 VRefl=A2 - AN0_AN1_AN4_VREF_VREF: A0 A1 A5 VRefh=A3 VRefl=A2 - AN0_AN1_VREF_VREF: A0 A1 VRefh=A3 VRefl=A2 - AN0: A0 - AN0_VREF_VREF: A0 VRefh=A3 VRefl=A2 Ví Dụ: setup_adc_ports (AN0_AN1_AN3) ; // A0, A1, A3 nhận analog, áp nguồn +5V cấp cho IC sẽ là điện áp chuẩn. Set_ADC_channel (channel) Chọn chân để đọc vào giá trị analog bằng lệnh Read_ADC (). Giá trị channel tuỳ số chân chức năng ADC mỗi chip. Với 16F877, channel có giá trị từ 0 -7: 0-chân A0, 1-chân A1, 2-chân A2, 3-chân A3 4-chân A5, 5-chân E0, 6-chân E1, 7-chân E2. THIẾT KẾ HỆ THỐNG NHÚNG 41 Hàm không trả về trị. Nên delay 10 us sau hàm này rồi mới dùng hàm read_ADC () để bảo đảm kết quả đúng. Hàm chỉ hoạt động với A /D phần cứng trên chip. Read_ADC (mode) Dùng đọc giá trị ADC từ thanh ghi (cặp thanh ghi) chứa kết quả biến đổi ADC. Lưu ý hàm này sẽ hỏi vòng cờ cho tới khi cờ này báo đã hoàn thành biến đổi ADC (sẽ mất vài us) thì xong hàm. Nếu giá trị ADC là 8 bit như khai báo trong chỉ thị #DEVICE, giá trị trả về của hàm là 8 bit, ngược lại là 16 bit nếu khai báo #DEVICE sử dụng ADC 10 bit trở lên. Khi dùng hàm này, nó sẽ lấy ADC từ chân bạn chọn trong hàm Set_ADC_channel () trước đó. Nghĩa là mỗi lần chỉ đọc 1 kênh Muốn đổi sang đọc chân nào, dùng hàm set_ADC_channel () lấy chân đó. Nếu không có đổi chân, dùng read_ADC () bao nhiêu lần cũng được. Mode có thể có hoặc không, bao gồm: - ADC_START_AND_READ: giá trị mặc định - ADC_START_ONLY: bắt đầu chuyển đổi và trả về - ADC_READ_ONLY: đọc kết quả chuyển đổi lần cuối #DEVCE 8 bit 10 bit 11 bit 16 bit - ADC=8 0-255 0-255 00-255 00-255 - ADC=10 x 0-1023 x x - ADC=11 x x 0-2047 x - ADC=16 0-65280 0-65472 0-65504 0-65535 Ví dụ: setup_adc (ADC_CLOCK_INTERNAL) ; setup_adc_ports (ALL_ANALOG) ; set_adc_channel (1) ; while (input (PIN_B0) ) { delay_ms (5000) ; value = read_adc () ; printf ("A/D value = %2x\n\r", value) ; } read_adc (ADC_START_ONLY) ; sleep () ; value=read_adc (ADC_READ_ONLY) ; THIẾT KẾ HỆ THỐNG NHÚNG 42 Chú ý: trên PIC 18, cấu trúc ADC tương đối phức tạp, đa năng hơn như là cho phép lấy 2 mẫu cùng lúc,... cũng sử dụng với các hàm trên, có nhiều thông số trong file *. h. 5.2.3. Lập trình ứng dụng Viết chương trình lấy ADC 8 bit, đọc và xuất ra dãy led được kết nối ở Port B và xuất ra màn hình máy tính. Hình 22: Sơ đồ kết nối với vi điều khiển PIC 16F877 Code chương trình: #include #use delay (clock=20000000) #device *= 16 ADC = 8 // sử dụng ADC 8 bit, giá trị ADC vào từ 0-255 #use rs232 (baud=19200, parity=n, xmit=pin_C6, rcv=pin_C7) Int8 adc; Main () { Setup_ADC (ADC_internal) ; Setup_ADC_ports (AN0) ; Set_ADC_channel (0) ; Delay_us (10) ; // delay 10 us While (true) { adc = read_adc () ; THIẾT KẾ HỆ THỐNG NHÚNG 43 Output_B (adc) ; // xuat ra port B gia tri bien adc Printf (“ gia tri adc la: %u “, adc) ; // in ra man hinh } Chú ý: Giá trị biến adc từ 0-255, khi thiết lập thông số truyền với máy tính phải trùng với thông số được khởi tạo ở đầu chương trình (ở ví dụ trên ta sẽ thiết lập tốc độ là 19200 như khai báo bên trên đầu chương trình). THIẾT KẾ HỆ THỐNG NHÚNG 44 Bài 6 THỰC HÀNH: LẬP TRÌNH VÀO RA TƯƠNG TỰ Chi tiết theo cuốn bài tập thực hành Bài 7 LẬP TRÌNH VÀ XỬ LÝ NGẮT 7.1. Tổng quan về ngắt trong PIC 16F877A PIC16F877A có đến 15 nguồn tạo ra hoạt động ngắt được điều khiển bởi thanh ghi INTCON (bit GIE). Bên cạnh đó mỗi ngắt còn có một bit điều khiển và cờ ngắt riêng. Các cờ ngắt vẫn được set bình thường khi thỏa mãn điều kiện ngắt xảy ra bất chấp trạng thái của bit GIE, tuy nhiên hoạt động ngắt vẫn phụ thuôc vào bit GIE và các bit điều khiển khác. Bit điều khiển ngắt RB0/INT và TMR0 nằm trong thanh ghi INTCON, thanh ghi này còn chứa bit cho phép các ngắt ngoại vi PEIE. Bit điều khiển các ngắt nằm trong thanh ghi PIE1 và PIE2. Cờ ngắt của các ngắt nằm trong thanh ghi PIR1 và PIR2. Trong một thời điểm chỉ có một chương trình ngắt được thực thi, chương trình ngắt được kết thúc bằng lệnh RETFIE. Khi chương trình ngắt được thực thi, bit GIE tự động được xóa, địa chỉ lệnh tiếp theo của chương trình chính được cất vào trong bộ nhớ Stack và bộ đếm chương trình sẽ chỉ đến địa chỉ 0004h. Lệnh RETFIE được dùng để thoát khỏi chương trình ngắt và quay trở về chương trình chính, đồng thời bit GIE cũng sẽ được set để cho phép các ngắt hoạt động trở lại. Các cờ hiệu được dùng để kiểm tra ngắt nào đang xảy ra và phải được xóa bằng chương trình trước khi cho phép ngắt tiếp tục hoạt động trở lại để ta có thể phát hiện được thời điểm tiếp theo mà ngắt xảy ra. Đối với các ngắt ngoại vi như ngắt từ chân INT hay ngắt từ sự thay đổi trạng thái các chân của PORTB (PORTB Interrupt on change), việc xác định ngắt nào xảy ra cần 3 hoặc 4 chu kỳ lệnh tùy thuộc vào thời điểm xảy ra ngắt. Cần chú ý là trong quá trình thực thi ngắt, chỉ có giá trị của bộ đếm chương trình được cất vào trong Stack, trong khi một số thanh ghi quan trọng sẽ không được cất và có thể bị thay đổi giá trị trong quá trình thực thi chương trình ngắt. Điều này nên được xử lí bằng chương trình để tránh hiện tượng trên xảy ra. THIẾT KẾ HỆ THỐNG NHÚNG 45 Hình 23: Sơ đồ logic của các ngắt trong PIC 16F877A 7.2. Khai báo và sử dụng ngắt trong CCS Trong CCS ngắt được khai báo với các dòng lệnh sau: - enable_interrupts (level) ; //cho phép ngắt kiểu level - disable_interrupts (level) ; //cấm ngắt kiểu level - ext_int_edge (edge) ; // chọn cách lấy xung loại edge Level bao gồm: - GLOBAL: ngắt toàn cục - INT_RTCC: tràn TMR0 - INT_RB: có thay đổi trạng thái một trong các chân RB4 đến RB7 - INT_EXT: ngắt ngoài - INT_AD: chuyển đổi AD đã hoàn tất - INT_TBE: bộ đệm chuyển RS232 trống - INT_RDA: data nhận từ RS232 sẵn sàng - INT_TIMER1: tràn TMR1 - INT_TIMER2: tràn TMR2 - INT_CCP1: có capture hay compare trên CCP1 - INT_CCP2: có capture hay compare trên CCP2 - INT_SSP: có hoạt động SPI hay I2C - INT_PSP: có data vào cổng parallel slave - INT_BUSCOL: xung đột bus THIẾT KẾ HỆ THỐNG NHÚNG 46 - INT_EEPROM: ghi vào eeprom hoàn tất - INT_TIMER0: tràn TMR0 - INT_COMP: kiểm tra bằng nhau comparator Edge bao gồm: - L_TO_H: cạnh lên - H_TO_L: cạnh xuống Sau khai báo trên để vào đoạn chương trình ngắt, khai báo: #INT_......... Ví dụ: Ví dụ 1: Viết chương trình sử dụng ngắt INT trong PIC hiển thị led đơn theo các trạng thái khác Hình 24: Ghép nối điều khiển LED đơn Code: // CTRINH su dung ngat ngoai tren chan RB0 // Nhan 1 lan ctrinh 1 se chay, nhan lan 2 ctrinh 2 se chay, nhan lan 3 ctrinh 3 chay // nhan lien luc ba lan se chay lan luot ctrinh1, ctrinh2, ctrinh3 #include #include #device *=16 adc=8 #use delay (clock=20000000) // su dung thach anh 20mhz #use fast_io (d) // dung voi cac lenh nhu output_low... nhanh hon binh thuong #byte portb=0x06 THIẾT KẾ HỆ THỐNG NHÚNG 47 #byte portd=0x08 int8 mode, i; byte a; //chuong trinh ngat #int_ext // giup vao ngat ngat_int () { mode++; if (mode==4) mode=0; } //khai bao ham nguyen mau cho chuong trinh con void ctrinh1 () ; void ctrinh2 () ; void ctrinh3 () ; // chuong trinh chinh void main () { set_tris_d (0) ; //cong D la cong xuat trisb= (0XFF) ; portd=0xff; // cong d o muc cao enable_interrupts (int_ext) ; // cho phep ngat ngoai ext_int_edge (h_to_l) ; //chon canh kich ngat la tu cao xuong thap enable_interrupts (global) ; mode=0; while (1) { switch (mode) { case 1: ctrinh1 () ; break; case 2: ctrinh2 () ; break; case 3: ctrinh3 () ; break; THIẾT KẾ HỆ THỐNG NHÚNG 48 } } } // cac chuong trinh con void ctrinh1 () { a=0xff; for (i=0;i<=8;i++) { portd =a; delay_ms (50) ; a>>=1; //dich trai a; } } void ctrinh2 () { a=0xff; for (i=0;i<=8;i++) { portd =a; delay_ms (50) ; a<<=1; //dich trai a; } } void Ctrinh3 () { portd=0x00; delay_ms (50) ; portd=0xff; } 7.3. Ngắt do sự thay đổi trạng thái của các chân trong PORTB Các chân của PortB được dùng cho ngắt này và được điều khiển bởi bit RBIE (trong thanh ghi INTCON). Cờ ngắt này là bit RBIF (INTCON). Lưu ý: Phải dùng lệnh đọc cổng B để xóa cờ ngắt khi lập trình ngắt này. Ví dụ 1: THIẾT KẾ HỆ THỐNG NHÚNG 49 Sử dụng ngắt RB để điều khiển bật tắc các led được nối vào các chân tương ứng trên PortD Hình 25: Sơ đồ ghép nối xử lý ngoài trên PortB Code: #include #include #device *=16 adc=8 #use delay (clock=20000000) // su dung thach anh 20mhz #use fast_io (b) // dung voi cac lenh nhu output_low... nhanh hon bthuong #byte portb=0x06 #byte portd=0x08 // Chương trình ngắt RB #int_rb void rb_led () { portd=portb;//Xóa ngắt, đưa trạng thái ra cổng D } void main () { set_tris_b (0xf0) ; //portb=11110000: B4:B7 la ngo vao, B0:B3 la ngo ra THIẾT KẾ HỆ THỐNG NHÚNG 50 set_tris_d (0x00) ; //pordD la ngo ra enable_interrupts (int_rb) ; //cho phep ngat RB: bat ki thay doi nao tren B4:B7 enable_interrupts (global) ; //cho phep ngat tat ca ngat while (true) { } } Ví dụ 2: Cho sơ đồ kết nối như hình trên, hãy viết chương trình điều khiển các nút nhấn thay đổi tốc độ nhấp nháy của các led được nối ở Port B (Sử dụng ngắt RB). Code: sinh viên tự lập trình Gợi ý: Sử dụng một biến để lưu khoảng thời gian tắt mở của led và cho thay đổi trong ngắt RB khi kiểm tra từng chân (RB7:RB4). 7.4. Chế độ Sleep Đây là chế độ hoạt động của vi điều khiển khi lệnh SLEEP được thực thi. Khi đó nếu được cho phép hoạt động, bộ đếm của WDT sẽ bị xóa nhưng WDT vẫn tiếp tục hoạt động, bit PD (STATUS) được reset về 0, bit TO được set, oscillator ngưng tác động và các PORT giữ nguyên trạng thái như trước khi lệnh SLEEP được thực thi. Do khi ở chế độ SLEEP, dòng cung cấp cho vi điều khiển là rất nhỏ nên ta cần thực hiện các bước sau trước khi vi điều khiển thực thi lệnh SLEEP: - Đưa tất cả các pin về trạng thái VDD hoặc VSS - Cần bảo đảm rằng không còn mạch ngoại vi nào được điều khiển bởi dòng điện của vi điều khiển vì dòng điện nhỏ không đủ khả năng cung cấp cho các mạch ngoại vi hoạt động - Tạm ngưng hoạt động của khối A/D và không cho phép các xung clock từ bên ngoài tác động vào vi điều khiển - Để ý đến chức năng kéo lên điện trở ở PORTB - Chân Reset phải ở mức cao 7.5. Watch Dog Timer Watchdog timer (WDT) là bộ đếm độc lập dùng nguồn xung đếm từ bộ tạo xung được tích hợp sẵn trong vi điều khiển và không phụ thuộc vào bất kỳ nguồn xung clock ngoại vi nào. Điều đó có nghĩa là WDT vẫn hoạt động ngay cả khi xung clock được lấy từ pin OSC1/CLKI và pin OSC2/CLKO của vi điều khiển ngưng hoạt THIẾT KẾ HỆ THỐNG NHÚNG 51 động (chẳng hạn như do tác động của lệnh sleep). Bit điều khiển của WDT là bit WDTE nằm trong bộ nhớ chương trình ở địa chỉ 2007h (Configuration bit). WDT sẽ tự động reset vi điều khiển (Watchdog Timer Reset) khi bộ đếm của WDT bị tràn (nếu WDT được cho phép hoạt động), đồng thời bit tự động được xóa. Nếu vi điều khiển đang ở chế độ sleep thì WDT sẽ đánh thức vi điều khiển (Watchdog Timer Wake-up) khi bộ đếm bị tràn. Như vậy WDT có tác dụng reset vi điều khiển ở thời điểm cần thiết mà không cần đến sự tác động từ bên ngoài, chẳng hạn như trong quá trình thực thi lệnh, vi điều khiển bị “kẹt” ở một chổ nào đó mà không thoát ra được, khi đó vi điều khiển sẽ tự động được reset khi WDT bị tràn để chương trình hoạt động đúng trở lại. WDT cũng có sự phiền toái vì vi điều khiển sẽ thường xuyên được reset sau một thời gian nhất định, do đó cần tính toán thời gian thích hợp để xóa WDT (dùng lệnh CLRWDT). Và để việc ấn định thời gian reset được linh động, WDT còn được hỗ trợ một bộ chia tần số prescaler được điều khiển bởi thanh ghi OPTION_REG (prescaler này được chia sẻ với Timer0). Một điểm cần chú ý nữa là lệnh sleep sẽ xóa bộ đếm WDT và prescaler. Ngoài ra lệnh xóa CLRWDT chỉ xóa bộ đếm chứ không làm thay đổi đối tượng tác động của prescaler (WDT hay Timer0). 7.6. “Đánh thức” vi điều khiển Vi điều khiển có thể được “đánh thức” dưới tác động của một trong số các hiện tượng sau: - Tác động của reset ngoại vi. - Tác động của Watchdog timer (WDT) khi bị tràn. - Tác động từ các ngắt ngoại vi từ PORTB (PORTB Interrupt on change hoặc pin INT). Các bit PD và TO được dùng để thể hiện trạng thái của vi điều khiển và để phát hiện nguồn tác động làm reset vi điều khiển. Bit PD được set khi vi điều khiển được cấp nguồn và được reset về 0 khi vi điều khiển ở chế độ sleep. Bit TO được reset về 0 khi WDT tác động do bộ đếm bị tràn. Ngoài ra còn có một số nguồn tác động khác từ các chức năng ngoại vi bao gồm: - Đọc hay ghi dữ liệu thông qua PSP (Parallel Slave Port). - Ngắt Timer1 khi hoạt động ở chế độ đếm bất đồng bộ. - Ngắt CCP khi hoạt động ở chế độ Capture. - Các hiện tượng đặc biệt làm reset Timer1 khi hoạt động ở chế độ đếm bất đồng bộ dùng nguồn xung clock ở bên ngoài). - Ngắt SSP khi bit Start/Stop được phát hiện. - SSP hoạt động ở chế độ Slave mode khi truyền hoặc nhận dữ liệu. THIẾT KẾ HỆ THỐNG NHÚNG 52 - Tác động của USART từ các pin RX hay TX khi hoạt động ở chế độ Slave mode đồng bộ. - Khối chuyển đổi A/D khi nguồn xung clock hoạt động ở dạng RC. - Hoàn tất quá trình ghi vào EEPROM. - Ngõ ra bộ so sánh thay đổi trạng thái. Các tác động ngoại vi khác không có tác dụng đánh thức vi điều khiển vì khi ở chế độ sleep các xung clock cung cấp cho vi điều khiển ngưng hoạt động. Bên cạnh đó cần cho phép các ngắt hoạt động trước khi lệnh SLEEP được thực thi để bảo đảm tác động của các ngắt. Việc đánh thức vi điều khiển từ các ngắt vẫn được thực thi bất chấp trạng thái của bit GIE. Nếu bit GIE mang giá trị 0, vi điều khiển sẽ thực thi lệnh tiếp theo sau lệnh SLEEP của chương trình (vì chương trình ngắt không được cho phép thực thi). Nếu bit GIE được set trước khi lệnh SLEEP được thực thi, vi điều khiển sẽ thực thi lệnh tiếp theo của chương trình và sau đó nhảy tới địa chỉ chứa chương trình ngắt (0004h). Trong trường hợp lệnh tiếp theo không đóng vai trò quan trọng trong chương trình, ta cần đặt thêm lệnh NOP sau lệnh SLEEP để bỏ qua tác động của lệnh này, đồng thời giúp ta dễ dàng hơn trong việc kiểm soát hoạt động của chương trình ngắt. Tuy nhiên cũng có một số điểm cần lưu ý như sau: - Nếu ngắt xảy ra trước khi lệnh SLEEP được thực thi, lệnh SLEEP sẽ không được thực thi và thay vào đó là lệnh NOP, đồng thời các tác động của lệnh SLEEP cũng sẽ được bỏ qua. - Nếu ngắt xảy ra trong khi hay sau khi lệnh SLEEP được thực thi, vi điều khiển lập tức được đánh thức từ chế độ sleep, và lệnh SLEEP sẽ được thực thi ngay sau khi vi điều khiển được đánh thức. - Để kiểm tra xem lệnh SLEEP đã được thực thi hay chưa, ta kiểm tra bit. Nếu bit vẫn mang giá trị 1 tức là lệnh SLEEP đã không được thực thi và thay vào đó là lệnh NOP. Bên cạnh đó ta cần xóa WDT để chắc chắn rằng WDT đã được xóa trước khi thực thi lệnh SLEEP, qua đó cho phép ta xác định được thời điểm vi điều khiển được đánh thức do tác động của WDT. THIẾT KẾ HỆ THỐNG NHÚNG 53 Bài 8 THẢO LUẬN LẬP TRÌNH XỬ LÝ NGẮT - Quy trình xử lý ngắt - Phương pháp triển khai trong Pic Bài 9 THỰC HÀNH: LẬP TRÌNH NGẮT Chi tiết theo cuốn bài tập thực hành Bài 10 TIMER TRONG PIC 16F877A Trong vi điều khiển PIC 16F877A được tích hợp 2 bộ timer 8 bit là Timer0, Timer 2 và một bộ Timer 16 bit là Timer 1. Timer được sử dụng vào nhiều ứng dụng khác nhau: Interrupts, capture, pwm... 10.1. Timer 0 Đây là một trong ba bộ đếm hoặc bộ định thời của vi điều khiển PIC16F877A. Timer0 là bộ đếm 8 bit được kết nối với bộ chia tần số (prescaler) 8 bit. Cấu trúc của Timer0 cho phép ta lựa chọn xung clock tác động và cạnh tích cực của xung clock. Ngắt Timer0 sẽ xuất hiện khi Timer0 bị tràn. Bit TMR0IE (INTCON) là bit điều khiển của Timer0. TMR0IE=1 cho phép ngắt Timer0 tác động, TMR0IF= 0 không cho phép ngắt Timer0 tác động. Sơ đồ khối của Timer0 như sau: THIẾT KẾ HỆ THỐNG NHÚNG 54 Hình 26: Sơ đồ khối của bộ Timer0 Muốn Timer0 hoạt động ở chế độ Timer ta clear bit TOSC (OPTION_REG), khi đó giá trị thanh ghi TMR0 sẽ tăng theo từng chu kỳ xung đồng hồ (tần số vào Timer0 bằng ¼ tần số oscillator). Khi giá trị thanh ghi TMR0 từ FFh trở về 00h, ngắt Timer0 sẽ xuất hiện. Thanh ghi TMR0 cho phép ghi và xóa được giúp ta ấn định thời điểm ngắt Timer0 xuất hiện một cách linh động. Muốn Timer0 hoạt động ở chế độ counter ta set bit TOSC (OPTION_REG). Khi đó xung tác động lên bộ đếm được lấy từ chân RA4/TOCK1. Bit TOSE (OPTION_REG) cho phép lựa chọn cạnh tác động vào bột đếm. Cạnh tác động sẽ là cạnh lên nếu TOSE=0 và cạnh tác động sẽ là cạnh xuống nếu TOSE=1. Khi thanh ghi TMR0 bị tràn, bit TMR0IF (INTCON) sẽ được set. Đây chính là cờ ngắt của Timer0. Cờ ngắt này phải được xóa bằng chương trình trước khi bộ đếm bắt đầu thực hiện lại quá trình đếm. Ngắt Timer0 không thể “đánh thức” vi điều khiển từ chế độ sleep. Bộ chia tần số (prescaler) được chia sẻ giữa Timer0 và WDT (Watchdog Timer). Điều đó có nghĩa là nếu prescaler được sử dụng cho Timer0 thì WDT sẽ không có được hỗ trợ của prescaler và ngược lại. Prescaler được điều khiển bởi thanh ghi OPTION_REG. Bit PSA (OPTION_REG) xác định đối tượng tác động của prescaler. Các bit PS2:PS0 (OPTION_REG) xác định tỉ số chia tần số của THIẾT KẾ HỆ THỐNG NHÚNG 55 prescaler. Xem lại thanh ghi OPTION_REG để xác định lại một cách chi tiết về các bit điều khiển trên. Các lệnh tác động lên giá trị thanh ghi TMR0 sẽ xóa chế độ hoạt động của prescaler. Khi đối tượng tác động là Timer0, tác động lên giá trị thanh ghi TMR0 sẽ xóa prescaler nhưng không làm thay đổi đối tượng tác động của prescaler. Khi đối tượng tác động là WDT, lệnh CLRWDT sẽ xóa prescaler, đồng thời prescaler sẽ ngưng tác vụ hỗ trợ cho WDT. Các thanh ghi điều khiển liên quan đến Timer0 bao gồm: - TMR0 (địa chỉ 01h, 101h) : chứa giá trị đếm của Timer0. - INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh) : cho phép ngắt hoạt động (GIE và PEIE). - OPTION_REG (địa chỉ 81h, 181h) : điều khiển prescaler. 10.2. Timer 1 Timer1 là bộ định thời 16 bit, giá trị của Timer1 sẽ được lưu trong hai thanh ghi (TMR1H:TMR1L). Cờ ngắt của Timer1 là bit TMR1IF (PIR1). Bit điều khiển của Timer1 sẽ là TMR1IE (PIE). Tương tự như Timer0, Timer1 cũng có hai chế độ hoạt động: chế độ định thời (timer) với xung kích là xung clock của oscillator (tần số của timer bằng ¼ tần số của oscillator) và chế độ đếm (counter) với xung kích là xung phản ánh các sự kiện cần đếm lấy từ bên ngoài thông qua chân RC0/T1OSO/T1CKI (cạnh tác động là cạnh lên). Việc lựa chọn xung tác động (tương ứng với việc lựa chọn chế độ hoạt động là timer hay counter) được điều khiển bởi bit TMR1CS (T1CON). Sau đây là sơ đồ khối của Timer1: Hình 27: Sơ đồ khối của Timer1 Ngoài ra Timer1 còn có chức năng reset input bên trong được điều khiển bởi một trong hai khối CCP (Capture/Compare/PWM). THIẾT KẾ HỆ THỐNG NHÚNG 56 Khi bit T1OSCEN (T1CON) được set, Timer1 sẽ lấy xung clock từ hai chân RC1/T1OSI/CCP2 và RC0/T1OSO/T1CKI làm xung đếm. Timer1 sẽ bắt đầu đếm sau cạnh xuống đầu tiên của xung ngõ vào. Khi đó PORTC sẽ bỏ qua sự tác động của hai bit TRISC và PORTC được gán giá trị 0. Khi clear bit T1OSCEN Timer1 sẽ lấy xung đếm từ oscillator hoặc từ chân RC0/T1OSO/T1CKI. Timer1 có hai chế độ đếm là đồng bộ (Synchronous) và bất đồng bộ (Asynchronous). Chế độ đếm được quyết định bởi bit điều khiển T1SYNC (T1CON). Khi =1 xung đếm lấy từ bên ngoài sẽ không được đồng bộ hóa với xung clock bên trong, Timer1 sẽ tiếp tục quá trình đếm khi vi điều khiển đang ở chế độ sleep và ngắt do Timer1 tạo ra khi bị tràn có khả năng “đánh thức” vi điều khiển. Ở chế độ đếm bất đồng bộ, Timer1 không thể được sử dụng để làm nguồn xung clock cho khối CCP (Capture/Compare/Pulse width modulation). Khi =0 xung đếm vào Timer1 sẽ được đồng bộ hóa với xung clock bên trong. Ở chế độ này Timer1 sẽ không hoạt động khi vi điều khiển đang ở chế độ sleep. Các thanh ghi liên quan đến Timer1 bao gồm: - INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh) : cho phép ngắt hoạt động (GIE và PEIE). - PIR1 (địa chỉ 0Ch) : chứa cờ ngắt Timer1 (TMR1IF). - PIE1 (địa chỉ 8Ch) : cho phép ngắt Timer1 (TMR1IE). - TMR1L (địa chỉ 0Eh) : chứa giá trị 8 bit thấp của bộ đếm Timer1. - TMR1H (địa chỉ 0Eh) : chứa giá trị 8 bit cao của bộ đếm Timer1. - T1CON (địa chỉ 10h) : xác lập các thông số cho Timer1. 10.3. Timer 2 Timer2 là bộ định thời 8 bit và được hỗ trợ bởi hai bộ chia tần số prescaler và postscaler. Thanh ghi chứa giá trị đếm của Timer2 là TMR2. Bit cho phép ngắt Timer2 tác động là TMR2ON (T2CON). Cờ ngắt của Timer2 là bit TMR2IF (PIR1). Xung ngõ vào (tần số bằng ¼ tần số oscillator) được đưa qua bộ chia tần số prescaler 4 bit (với các tỉ số chia tần số là 1:1, 1:4 hoặc 1:16 và được điều khiển bởi các bit T2CKPS1:T2CKPS0 (T2CON)). THIẾT KẾ HỆ THỐNG NHÚNG 57 Hình 28: Sơ đồ khối Timer2 Timer2 còn được hỗ trợ bởi thanh ghi PR2. Giá trị đếm trong thanh ghi TMR2 sẽ tăng từ 00h đến giá trị chứa trong thanh ghi PR2, sau đó được reset về 00h. Khi reset thanh ghi PR2 được nhận giá trị mặc định FFh. Ngõ ra của Timer2 được đưa qua bộ chia tần số postscaler với các mức chia từ 1:1 đến 1:16. Postscaler được điều khiển bởi 4 bit T2OUTPS3:T2OUTPS0. Ngõ ra của postscaler đóng vai trò quyết định trong việc điều khiển cờ ngắt. Ngoài ra ngõ ra của Timer2 còn được kết nối với khối SSP, do đó Timer2 còn đóng vai trò tạo ra xung clock đồng bộ cho khối giao tiếp SSP. Các thanh ghi liên quan đến Timer2 bao gồm: - INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh) : cho phép toàn bộ các ngắt (GIE và PEIE). - PIR1 (địa chỉ 0Ch) : chứa cờ ngắt Timer2 (TMR2IF). - PIE1 (địa chị 8Ch) : chứa bit điều khiển Timer2 (TMR2IE). - TMR2 (địa chỉ 11h) : chứa giá trị đếm của Timer2. - T2CON (địa chỉ 12h) : xác lập các thông số cho Timer2. 10.4. Khai báo Timer trong CCS 10.4.1. Các lệnh Timer0 Setup_TIMER_0 (mode) ; Chọn chế độ làm việc cho Timer0 Set_TIMER0 (value) // hay set_RTCC (value) Khởi tạo giá trị ban đầu cho Timer THIẾT KẾ HỆ THỐNG NHÚNG 58 Get_TIMER0 () ; // hay get_RTCC () Trả lại giá trị cho timer0 là giá trị xung hoặc giá trị đếm Setup_COUNTERS (rtcc_state, ps_state) ; Trong đó mode là một hoặc hai constant (nếu dùng hai thì chèn dấu "|"ở giữa) được định nghĩa trong file 16F877A. h gồm: - RTCC_INTERNAL : chọn xung clock nội - RTCC_EXT_L_TO_H: chọn bit cạnh lên trên chân RA4 - RTCC_EXT_H_TO_L: chọn bit cạnh xuống trên chân RA4 - RTCC_DIV_2:chia prescaler 1:2 - RTCC_DIV_4 1:4 - RTCC_DIV_8 1:8 - RTCC_DIV_16 1:16 - RTCC_DIV_32 1:32 - RTCC_DIV_64 1:64 - RTCC_DIV_128 1:128 - RTCC_DIV_256 1:256 rtcc_state là một trong những constant sau: - RTCC_INTERNAL - RTCC_EXT_L_TO_H - RTCC_EXT_H_TO_L ps_state là một trong những constant sau: - RTCC_DIV_2 - RTCC_DIV_4 - RTCC_DIV_8 - RTCC_DIV_16 - RTCC_DIV_32 - RTCC_DIV_64 - RTCC_DIV_128 - RTCC_DIV_256 - WDT_18MS - WDT_36MS - WDT_72MS - WDT_144MS THIẾT KẾ HỆ THỐNG NHÚNG 59 - WDT_288MS - WDT_576MS - WDT_1152MS - WDT_2304MS 10.4.2. Các lệnh Timer1 Setup_TIMER_1 (mode) ; Chọn chế độ làm việc cho Timer0 Set_TIMER1 (value) ; Khởi tạo giá trị ban đầu cho Timer 1 (16 bit) Get_TIMER1 () ; // hay get_RTCC () Trả lại giá trị của bộ Timer1 là giá trị xung hoặc giá trị đếm mode gồm (có thể kết hợp bằng dấu "|") : - T1_DISABLED: tắt Timer1 - T1_INTERNAL: xung clock nội (Fosc/4) - T1_EXTERNAL: xung clock ngoài trên chân RC0 - T1_EXTERNAL_SYNC: xung clock ngoài đồng bộ - T1_CLK_OUT - T1_DIV_BY_1 - T1_DIV_BY_2 - T1_DIV_BY_4 - T1_DIV_BY_8 10.4.3. Các lệnh Timer2 setup_TIMER_2 (mode, period, postscale) Chọn chế độ làm việc cho Timer0 Set_TIMER2 (value) ; Khởi tạo giá trị ban đầu cho Timer 2 Get_TIMER2 () ; // hay get_RTCC () Trả lại giá trị của bộ Timer THIẾT KẾ HỆ THỐNG NHÚNG 60 là giá trị xung hoặc giá trị đếm Với mode gồm (có thể kết hợp bằng dấu "|") : - T2_DISABLED - T2_DIV_BY_1 - T2_DIV_BY_4 - T2_DIV_BY_16 period là số nguyên từ 0-255, xác định giá trị xung reset postscale là số nguyên 1-16, xác định reset bao nhiêu lần trước khi ngắt. 10.5. Lập trình ứng dụng Ví dụ 1: Cho sơ đồ kết nối như hình vẽ: Hình 29: Sơ đồ mạch ví dụ dùng Timer0 Lập trình cho các led sáng lần lượt từ trái sang phải sau khoảng thời gian nhất định (sử dụng timer0) Code: #include #include #device *=16 adc=8 #use delay (clock=4000000) // #use fast_io (b) // dung voi cac lenh nhu output_low... nhanh hon binh thuong THIẾT KẾ HỆ THỐNG NHÚNG 61 #byte portb=0x06 #byte portd=0x08 int16 count; int8 a; // chuong trinh ngat ngat timer0 #int_timer0 // cho phep vao ngat timer0 void interrupt_timer0 () { ++count; if (count==2000) //2000*500=1s {count=0; rotate_left (&a, 1) ; //xuay bien a 1 lan 1 bit } } // chuong trinh chinh void main () { set_tris_d (0) ; //cong B la cong xuat enable_interrupts (int_timer0) ; //cho phep ngat timer0 hoat dong setup_timer_0 (rtcc_internal|rtcc_div_2) ; //chon xung clock noi va chia tan trc 1:2 enable_interrupts (global) ; //cho phep tat ca ngat hoat dong set_timer0 (6) ; //T_dinhthoi = 2* (256 - 6) *1us = 500us a=0x01; while (true) { portd=a; } } Bài 11 THỰC HÀNH: LẬP TRÌNH TIMER/COUNTER Chi tiết theo cuốn bài tập thực hành THIẾT KẾ HỆ THỐNG NHÚNG 62 Bài 12 THẢO LUẬN VỀ TIMER/COUNTER - Timer - Counter - Phương pháp lập trình Timer/Counter trong Pic Bài 13 THỰC HÀNH: LẬP TRÌNH TIMER/COUNTER (TIẾP) Chi tiết theo cuốn bài tập thực hành Bài 14 LẬP TRÌNH TRUYỀN THÔNG 14.1. Tổng quan về lập trình truyền thông Vi điều khiển PIC 16F877A hỗ trợ nhiều chuẩn truyền thông khác nhau như chuẩn nối tiếp USART giao tiếp với máy tính theo chuẩn RS232, PSP (chuẩn song song), SPI, I2C. - USART: chuẩn truyền thông nối tiếp không đồng bộ hoàn toàn tương thích với giao tiếp máy tính qua RS232. Do chuẩn điện áp sử dụng tại PIC 16F877A là TTL nên để ghép nối với máy tính hoặc thiết bị khác sử dụng chuẩn RS232 cần có bộ chuyển đổi điện áp, ví dụ như IC MAX232. USART mặc định sử dụng 2 chân C6 và C7 để truyền thông. - PSP: với giao tiếp này, Pic sử dụng cổng D với vai trò là cổng truyền nhận song song 8 bit. Với PSP cho phép PIC có thể giao tiếp trực tiếp với các VĐK khác bằng bus dữ liệu 8 bit. Các chân RD, CS, WR sẽ giúp điều khiển đường truyền, chế độ hoạt động. PSP không hỗ trợ trên PIC16F873A, PIC16F876A. - Truyền thông nối tiếp đồng bộ: hỗ trợ 2 chế độ là SPI và I2C. 14.2. Chuẩn RS232 Với USART cho phép PIC 16F877A giao tiếp với máy tính theo chuẩn RS232. Đặc điểm RS232: Giao diện: THIẾT KẾ HỆ THỐNG NHÚNG 63 Hình 30: Hình ảnh giao diện DB9 và DB25 Giao diện COM sử dụng cổng nối 9 chân và 25 chân. Cổng nối 25 chân chỉ có một số chân được sử dụng. Thông dụng nhất là cổng nối 9 chân. Hình 31: Sơ đồ chân trên giao diện DB9 và DB25 Giao diện và công dụng các chân được thể hiện ở bảng sau: Sơ đồ chuyển đổi, ghép nối giữa giao diện 9 chân và giao diện 25 chân: THIẾT KẾ HỆ THỐNG NHÚNG 64 Các kiểu ghép nối truyền thông trên cổng RS232: Điện áp sử dụng truyền thông trong RS232 bao gồm cả mức điện áp âm và dương (không tương thích với các mức logic TTL và CMOS). Số "0" được biểu diện bằng mức điện áp +5V còn số "1" biểu diễn bằng mức đienẹ áp -5V. Giải điện áp sử dụng trong RS232 thể hiện trong bảng sau: THIẾT KẾ HỆ THỐNG NHÚNG 65 Các chip giao tiếp, hỗ trợ chuyển đổi mức logic TTL sang mức điện áp thích hợp trên cổng RS232, sử dụng giao tiếp được với VĐK Pic: MAX232, MAX233,... THIẾT KẾ HỆ THỐNG NHÚNG 66 Hình 32: Sơ đồ khối các vi mạch MAX232, MAX233 Ghép nối pic với máy tính qua RS232: - Sử dụng phương pháp truyền thông không điều khiển luồng: chỉ dùng 3 chân: TX (truyền), RX (nhận), Ground (chung-nối đất). - Ghép nối thông qua IC chuyển điện áp MAX232. 14.3. Lập trình ứng dụng Để lập trình truyền thông nối tiếp trên Pic ta cần thực hiện một số thiết lập sau: - Sử dụng chỉ thị: #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) Trong đó: tham số thứ nhất là tốc độ truyền, thứ 2 là sử dụng kiểu kiểm tra chẵn lẻ gì, thứ 3 chân truyền đi, thứ 4 là chân nhận về, thứ 5 là số bit dữ liệu truyền - Gửi dữ liệu: trong CCS có thể sử dụng các hàm PutC(), Putchar(), Printf() - Nhận dữ liệu: trong CCS có thể dùng các hàm GetC(), Getchar() - Thiết lập cấu hình bằng: setup_uart(baud, stream) Ví dụ: printf("Continue (Y,N)?"); do { answer=getch(); THIẾT KẾ HỆ THỐNG NHÚNG 67 }while(answer!='Y' && answer!='N'); #use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7,stream=HOSTPC) #use rs232(baud=1200,xmit=pin_b1, rcv=pin_b0,stream=GPS) #use rs232(baud=9600,xmit=pin_b3, stream=DEBUG) ... while(TRUE) { c=fgetc(GPS); fputc(c,HOSTPC); if(c==13) fprintf(DEBUG,"Got a CR\r\n"); } Bài 15 THỰC HÀNH: LẬP TRÌNH TRUYỀN THÔNG Chi tiết theo cuốn bài tập thực hành THIẾT KẾ HỆ THỐNG NHÚNG 68 Bài 16 LẬP TRÌNH TRUYỀN THÔNG (tiếp) 16.1. Chuẩn I2C Vi điều khiển PIC 16F877A hỗ trợ nhiều chuẩn truyền thông nối tiếp đồng bộ theo 2 chế độ: SPI, I2C. Một giao tiếp I2C gồm có 2 dây: Serial Data (SDA) và Serial Clock (SCL). SDA là đường truyền dữ liệu 2 hướng, còn SCL là đường truyền xung đồng hồ và chỉ the o một hướng. Như hình vẽ , khi một thiết bị ngoại vi kết nối vào đường I2C thì chân SDA của nó sẽ nối với dây SDA của bus, chân SCL sẽ nối với dây SCL. Hình 33: Sơ đồ ghép nối thiết bị chuẩn I2C Mỗi dây SDA hay SCL đều được nối với điện áp dương của nguồn cấp thông qua một điện trở kéo lên (pull‐up resistor). Sự cần thiết của các điện trở kéo này là vì chân giao tiếp I2C của các thiết bị ngoại vi thường là dạng cực máng hở (open‐drain or open‐collector). Giá trị của các điện trở này khác nhau tùy vào từng thiết bị và chuẩn giao tiếp, thường dao động trong khoảng 1KΩ đến 4.7KΩ. Trở lại với hình trên, ta thấy có rất nhiều thiết bị (ICs) cùng được kết nối vào một bus I2C, tuy nhiên sẽ không xảy ra chuyện nhầm lẫn giữa các thiết bị, bởi mỗi thiết bị sẽ được nhận ra bởi một địa chỉ duy nhất với một quan hệ chủ/tớ tồn tại trong suốt thời gian kết nối. Mỗi thiết bị có thể hoạt đông như là thiết bị nhận dữ liệu hay có thể vừa truyền vừa nhận. Hoạt động truyền hay nhận còn tùy thuộc vào việc thiết bị đó là chủ (master) hay tớ (slave). Một thiết bị hay một IC khi kết nối với bus I2C, ngoài một địa chỉ (duy nhất) để phân biệt, nó còn được cấu hình là thiết bị chủ (master) hay tớ (slave). Tại sao lại có sự phân biệt này ? Đó là vì trên một bus I2C thì quyền điều khiển thuộc về thiết bị chủ (master). Thiết bị chủ nắm vai trò tạo xung đồng hồ cho toàn hệ thống, khi giữa hai thiết bị chủ/tớ giao tiếp thì thiết bị chủ có nhiệm vụ tạo xung đồng hồ và quản lý địa chỉ của thiết bị tớ trong suốt quá trình giao tiếp. Thiết bị chủ giữ vai trò chủ động, còn thiết bị tớ giữ vai trò bị động trong viêc giao tiếp. THIẾT KẾ HỆ THỐNG NHÚNG 69 Về dữ liệu truyền trên bus I2C, một bus I2C chuẩn truyền 8‐bit dữ liệu có hướng trên đường truyền với tốc độ là 100Kbits/s – Chế độ chuẩn (Standard mode). Tốc độ truyền có thể lên tới 400Kbits/s – Chế độ nhanh (Fast mode) và cao nhất là 3,4Mbits/s – Chế độ cao tốc (High‐speed mode). Một bus I2C có thể hoạt động ở nhiều chế độ khác nhau: - Một chủ một tớ (one master – one slave) - Một chủ nhiều tớ (one master – multi slave) - Nhiều chủ nhiều tớ (Multi master – multi slave) Dù ở chế độ nào, một giao tiếp I2C đều dựa vào quan hệ chủ/tớ. Giả thiết một thiết bị A muốn gửi dữ liệu đến thiết bị B, quá trình được thực hiện như sau: ‐ Thiết bị A (Chủ) xác định đúng địa chỉ của thiết bị B (tớ), cừng với việc xác định địa chỉ, thiết bị A sẽ quyết định việc đọc hay ghi vào thiết bị tớ

Các file đính kèm theo tài liệu này:

  • pdf01200050_0051_1983579.pdf