Tập bài giảng Vi xử lý 2

- Cấu trúc lựa chọn switch Cú pháp của lệnh switch có điểm đặc biệt hơn các cấu trúc trên mà ta đã xét. Dạng thức của cấu trúc switch như sau: switch (biểu thức) Case n1: các câu lệnh ; break ; Case n2: các câu lệnh ; break ; ....... Case nk: các câu lệnh ; break ; [ default: các câu lệnh ] ni là các hằng số nguyên hoặc ký tự. Phụ thuộc vào giá trị của biểu thức viết sau switch, nếu: + Giá trị biểu thức = ni thì thực hiện câu lệnh sau case ni. + Khi giá trị biểu thức không thỏa tất cả các ni thì thực hiện câu lệnh sau default nếu có, hoặc thoát khỏi câu lệnh switch. + Khi chương trình đã thực hiện xong câu lệnh của case ni nào đó thì nó sẽ thực hiện luôn các lệnh thuộc case bên dưới nó mà không xét lại điều kiện (do các ni được xem như các nhãn). Vì vậy, để chương trình thoát khỏi lệnh switch sau khi thực hiện xong một trường hợp, ta dùng lệnh break. - Câu lệnh rẽ nhánh và nhảy + Lệnh break. Sử dụng break chúng ta có thể thoát khỏi vòng lặp ngay cả khi điều kiện để kết thúc chưa được thoả mãn. Lệnh này có thể được dùng để kết thúc một vòng lặp không xác định hay buộc phải kết thúc giữa chừng thay vì kết thúc một cách bình thường. + Lệnh continue. Lệnh continue làm cho chương trình bỏ qua phần còn lại của vòng lặp và nhảy sang lần lặp tiếp theo. + Lệnh goto. Lệnh này cho phép nhảy vô điều kiện tới bất kì điểm nào trong chương trình. Nói chung bạn nên tránh dùng nó trong chương trình C++.

pdf216 trang | Chia sẻ: Tiểu Khải Minh | Ngày: 19/02/2024 | Lượt xem: 185 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Tập bài giảng Vi xử lý 2, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
rúc hàm: + Hàm trả lại giá trị Cấu trúc: kieugiatritralaiham tên hàm (Biến truyền vào hàm) { Các câu lệnh xử lý ở đây; } Bài giảng Vi xử lý 2 157 Trong hàm này thường được sử dụng lệnh return để truyền một giá trị ra ngoài hàm. Tất cả các hàm trừ void đều được xử dụng bằng lệnh return ví dụ: unsigned char bien(unsigned char x, unsigned char y) { x=x+y; return x; } + Hàm không trả lại giá trị Cấu trúc: void ten_ham() { Các câu lệnh thực hiện ở đây; } kiểu giá trị hàm này cũng dễ hiểu hơn cái này là đặc trưng cho C. Ví dụ: void bien() // Khai bao ham mang ten bien { unsigned char x,y; x+=y; } i. Mảng trong C Mảng được dùng để lưu các nhóm dữ liệu giống nhau. Khuân dạng mảng một chiều: cấu trúc: kiểu tên[số phần tử ]; Trong đó: Kiểu là kiểu dữ liệu trong C như int, char tên là tên biến số phần tử là một số nguyên chỉ giá trị lớn nhất của mảng. Ví dụ: int bien[3]={0,1,2}; // mảng này gồm 3 phần tử có độ dài là 3 Ngoài ra nó còn mảng nhiều chiều thường được sử dụng mảng 2 chiều và 3 chiều cấu trúc: kiểu tên [số pt1][số pt2]...[]; ví dụ: unsigned char bien[20][30]; j. Bộ tiền xử lý Ngoài kiểu khai báo thư viện trong C thì nó còn câu lệnh #define. Câu lệnh này cho phép người lập trình định nghĩa trực tiếp các cổng vào ra, biến hơn thế nữa còn cho phép định nghĩa một marco. Ví dụ: Bài giảng Vi xö lý 2 158 #define LCD_DATA4 PIN_D4 ở trên ta nhận thấy rằng chân dữ liệu thứ 4 của LCD được kết nối tới chân RD4. 4.5.4 Cấu trúc một chƣơng trình C Hình 4.20 Cấu trúc khung chương trình trong C a. Khối khai báo Bao gồm các khai báo về sử dụng thư viện, khai báo hằng số, khai báo hàm con (các nguyên mẫu hàm), khai báo các biến toàn cục và khai báo các kiểu dữ liệu tự định nghĩa. b. Hàm chính (main()) Chứa các biến, các lệnh và các lời gọi hàm cần thiết trong chương trình. c. Các hàm con Được sử dụng nhằm mục đích: Khi có một công việc giống nhau cần thực hiện ở nhiều vị trí. Khi cần chia một chương trình lớn phức tạp thành các đơn thể nhỏ (hàm con) để chương trình được trong sáng, dễ hiểu trong việc xử lý, quản lý việc tính toán và giải quyết vấn đề. d. Nguyên mẫu hàm Tên hàm ([ danh sách các tham số]); Nguyên mẫu hàm thực chất là dòng đầu của hàm thêm dấu chấm phẩy (;) vào cuối, tuy nhiên tham số trong nguyên mẫu hàm có thể bỏ phần tên. 4.5.5 Lập trình cho vi điều khiển PIC bằng CCS C a. Tổng quan về CCS Khối khai báo Hàm main() Các hàm con (nếu có) Bài giảng Vi xử lý 2 159 Sự ra đời của một loại vi điều khiển đi kèm với việc phát triển phần mềm ứng dụng cho việc lập trình cho vi điều khiển đó. Vi điều khiển chỉ hiểu và làm việc với ngôn ngữ máy là các số 0 và 1. Ban đầu để việc lập trình cho vi điều khiển là làm việc với dãy các số 0 và 1. Sau này khi kiến trúc của vi điều khiển ngày càng phức tạp, số luợng thanh ghi, lệnh nhiều lên, việc lập trình với dãy các số 0 và 1 không còn phù hợp nữa, đòi hỏi ra đời một ngôn ngữ mới thay thế. Ngôn ngữ lập trình Assembly, ngôn ngữ C ra đời. Nhu cầu dùng ngôn ngữ C đề thay cho ASM trong việc mô tả các lệnh lập trình cho vi điều khiển một cách ngắn gọn và dễ hiểu hơn đã dẫn đến sự ra đời của nhiều chương trình soạn thảo và biên dịch C cho vi điều khiển: Keil C, HT-PIC, MikroC, CCS Trong giáo trình, nhóm tác giả chọn CCS để giới thiệu vì CCS là một công cụ lập trình C mạnh cho vi điều khiển PIC. b. Giới thiệu về CCS C ? 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 dịch riêng biế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 - PCH cho dòng PIC 16 và 18- bit Tất cả 3 trình biên dịch 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 Tài liệu hướng dẫn sử dụng có rất nhiều, nhưng chi tiết nhất chính chúng ta nên tham khảo bản Help đi kèm theo phần mềm (tài liệu Tiếng Anh). Trong bản trợ giúp nhà sản xuất đã mô tả rất nhiều về hằng, biến, chỉ thị tiền xử lý, cấu trúc các câu lệnh trong chương trình, các hàm tạo sẵn cho người sử dụng c. Tạo PROJECT trong CCS Để tạo một Project trong CCS có nhiều cách, có thể dùng Project Wizard, Manual Creat, 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 Bài giảng Vi xö lý 2 160 các Project trogn một thư mục sẽ rất mất thời gian trong việ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... Trước tiên ta cần mở chương trình PIC C Compiler. - Tạo một PROJECT sử dụng PIC Wizard Khởi động chương trình làm việc PIC C Compiler. Từ giao diện chương trình ta chọn menu Project -> New -> PIC Wizard. Hình 4.21 Tạo dự án trên CCS C Tiếp đến, một cửa sổ hiện ra yêu cầu ta nhập tên Files cần tạo. Ta 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. Hình 4.22 Cửa sổ SaveAs để lưu dự án trên CCS Như vậy là xong bước đầu tiên. Sau khi nhấn nút Save, một cửa sổ New Project 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 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 PIC, tùy theo từng PIC 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 PIC thì ta sẽ chọn Bài giảng Vi xử lý 2 161 mục đó. Tổng cộng có 13 Tab để ta lựa chọn. Ở đây chỉ giới thiệu những Tab chính thường hay được sử dụng. - 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 4.23 Tab General trên CCS C + Device: Liệt kê danh sách các loại PIC 12F, 16F, 18F Ta 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ảo vệ Code, Brownout detected + Chọn kiểu con trỏ RAM là 16‐bit hay 8‐bit - Tab Communications Tab Communications liệt kê các giao tiếp nối tiếp mà một 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ừng loại giao tiếp. + Giao tiếp RS232 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 + 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. Bài giảng Vi xö lý 2 162 Hình 4.24 Tab Communications trên CCS C - 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ần cứ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 8051, không có hỗ trợ phần cứng SSP). Phần cấu hình cho LCD dành cho các chíp dòng 18F và 30F. Hình 4.25 Tab SPI and LCD trên CCS C - Tab Timer Liệt kê các bộ đếm/định thời mà các PIC dòng tầm trung có: 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 Bài giảng Vi xử lý 2 163 Hình 4.26 Tab Timer trên CCS C - 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ào từng IC cụ thể mà có các lựa chọn khác nhau, bao gồm: + Lựa chọn cổng vào tương tự + Chọn chân điện áp lấy mẫu (Vref) + Chọn độ phân giải: 8-bit = 0 ~ 255 hay 10-bit = 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à internal 2-6 us. + Khi không sử dụng bộ ADC ta chọn none Hình 4.27 Tab Analog trên CCS C - 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 - Bắt giữ + Chọn bắt giữ xung theo sườn dương (rising edge) hay sườn âm (falling edge) của xung vào Bài giảng Vi xö lý 2 164 + Chọn bắt giữ sau 1, 4 hay 16 xung (copy giá trị của TimerX vào thanh ghi lưu trữ CCCPx sau 1, 4 hay 16 xung). Compare - So sánh + Ta có các lựa chọn thực hiện lệnh khi xảy 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ện ngắt và thiết lập mức 0 Thực hiện ngắt và thiết lập mức 1 Thực hiện ngắ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à duty cycle. 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 điện áp + Lựa chọn mức điện áp so sánh Vref. 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 4.28 Tab Other trên CCS C - Tab Interrupts và Tab Driver Tab Interrupts 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 Tab Drivers đượ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, Keypad 3x4, LCD, ADC Chi tiết ta có thể xem trong thư mục Driver của chương trình: \...\PICC\Drivers Bài giảng Vi xử lý 2 165 Hình 4.29 Tab Interrupts trên CCS C Hình 4.30 Tab Driver trên CCS C 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 Files 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. Dưới đây là nội dung một files chương trình được CCS tạo ra theo các tùy chọn mà ta đã thiết lập. Chuong_trinh_mau.c #include D:\1-PIC project\chuong trinh test.HEX.h #device adc=8 #FUSES NOWDT,HS,NOPUT,NOPROTECT,NODEBUG, #use delay(clock=20000000) #define SRAM_SCL PIN_C3 #define SRAM_SDA PIN_C4 #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9) #int_EXT Bài giảng Vi xö lý 2 166 EXT_isr() { // Code here } Void Chuong_trinh_con() { // Code here } void main() { setup_adc_ports(AN0); setup_adc(ADC_CLOCK_INTERNAL); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); enable_interrupts(INT_EXT); enable_interrupts(INT_TBE); enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); // Enter your code here } d. Mẫu chƣơng trình cho vi điều khiển PIC trên CCS Phần trên ta đã tìm hiểu cách tạo một Project trong CCS, tuy nhiên theo cách đó mất khá nhiều thời gian, mặt khác mỗi người lập trình sẽ tạo ra nhưng form tài liệu theo cách riêng khác nhau, không đồng nhất. Tài liệu không được chuẩn hóa sẽ gây một số khó khăn cho người đọc, người đọc có thể không hiểu hết những gì mà người lập trình muốn diễn đạt. Với mục đích đưa ra một form tài liệu chuẩn cho việc lập trình bằng CCS, qua tham khảo các mẫu cho lập trình bằng ASM nhóm tác giả đưa ra một form tài liệu cho việc viết lập trình bằng CCS. Đi kèm văn bản này còn có các files nguồn cho văn bản mẫu, bao gồm files cho PIC16F877A, def_16f877a. Về sau khi lập trình ta chỉ việc copy tài liệu này vào thư mục chứa Project của mình. Bài giảng Vi xử lý 2 167 Khi cần thay đổi nội dung cấu hình cho PIC bạn chi việc tham khảo qua PIC Wizard, xem code và copy đưa vào Project. Mô tả nội dung chương trình. #include : Đi kèm chương trình dịch, chứa khai báo về các thanh ghi trong mỗi PIC, dùng cho việc cấu hình cho PIC. #include : Files do người lập trình tạo ra, chứa khai báo về các thanh ghi trong PIC giúp cho viêc lập trình được dễ dàng hơn #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áo về cấu hình cho PIC #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ối tiế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ính hay chương trình con Chương trình mẫu cho PIC16F877A //================================================= ======= // Ten chuong trinh : chuong trinh mau // Nguoi thuc hien : Nhom tac gia // Ngay thuc hien : 23/05/2013 // Ngay hoan thanh : 23/05/2013 // Mo ta phan cung : Dung PIC16F877A - thach anh 20MHz // LED giao tiep voi PORTB, phan cung tich cuc muc cao //================================================= ======= #include #include #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOLVP #use delay(clock=20mhz) #use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=9) #use i2c(Master,Fast,sda=PIN_B1,scl=PIN_B4) #int_xxx // Khai bao chuong trinh ngat xxx_isr() { Bài giảng Vi xö lý 2 168 // Code here } void Ten_chuong_trinh_con(Ten_Bien) { // cac lenh ma chuong trinh con can thuc hien } void main() { // cac lenh ma chuong trinh chinh can thuc hien } e. Hƣớng dẫn viết chƣơng trình trên CCS C Bước 1: Tạo dự án mới Khởi động chương trình CCS C Vào Project/new/pic wizard Hình 4.31 Tạo dự án trên CCS C - Sau đó chọn đường dẫn và đặt tên cho dự án: Bài giảng Vi xử lý 2 169 Hình 4.32 Lưu dự án trên CCS C - Khi đó chương trình sẽ đưa ra hộp thoại cho ta chọn VĐK và thiết lập một số thông số khác rồi nhấn OK. Hình 4.33 Tùy chọn cho dự án trên CCS C - Lúc này ta được: Bài giảng Vi xö lý 2 170 Hình 4.34 Dự án được tạo ra trên CCS C - Chúng ta nên xoá hết các cài đặt dựng sẵn của chương trình rồi viết từ đầu. Bước 2: Soạn thảo chương trình. - Ta tiến hành soạn thảo chương trình sau đó ghi lại. - Sau khi soạn thảo xong ta dịch bằng cách chọn: Compile hoặc chọn phím tắt là F9. - Nếu gặp lỗi cú pháp thì phần mềm sẽ báo khi đó ta đi vào dòng lỗi đó để sửa. Bước 3: Mô phỏng hoạt động của chương trình. - ( Chương trình CCS C chỉ cho phép ta soạn thảo và dịch chương trình. Về mô phỏng thì ta phải có thiết bị phần cứng đi kèm). - Ta có thể dùng Proteus để mô phỏng. 4.6 Một số ví dụ cơ bản viết cho PIC 16F877A Các chương trình viết sau đây có sử dụng file định nghĩa ―def_16f877A.h‖ do vậy khi viết theo các chương trình thì phải copy file trên vào mục device của thư mục mà đã cài PIC C. Nội dung file ―def_16f877a.h‖ được trình bày trong phụ lục của giáo trình Bài giảng Vi xử lý 2 171 4.6.1 Viết chƣơng trình cho vi điều khiển có chức năng làm đầu ra Vi điều khiển PIC có 5 port, các port này đều có thể lập trình để làm chức năng vào ra. Ví dụ 1: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển các led đơn nối với PORTB chớp tắt liên tục, các led tích cực ở mức cao. Bước 1: Vẽ lưu đồ giải thuật và sơ đồ nguyên lý Lưu đồ giải thuật: Sơ đồ nguyên lý: Sơ đồ được vẽ trên phần mềm Proteus Bước 2: Mở phần mềm CCS C theo hướng dẫn trên và viết chương trình điều khiển T¾t 8 led T¹o trÔ S¸ng 8 led T¹o trÔ KÕt thóc B¾t ®Çu Bài giảng Vi xö lý 2 172 /*chuong trinh dieu khien 8 led don noi voi port B chop tat phan cung tich cuc muc cao nguoi thuc hien: Nhom tac gia*/ #include "16f877a.h" // tien xu ly, chon VDK 16F877A #fuses hs,nowdt //su dung thach anh tan so cao, khong su dung wdt #include "def_16f877A.h" //su dung file dinh nghia da co #use delay(clock=12mhz) // su dung thach anh la 4mhz void main(void) { trisb=0x0; //gan port b lam dau ra while(true) //lap lien tuc chop tat { portb=0; // dau ra portb = 0( 8 led tat) delay_ms(100); // tao tre 100ms portb=0b11111111; // dau ra portb = 11111111( 8 led sang) delay_ms(100); // tao tre 100ms } } Bước 3: Nạp chương trình vào vi điều khiển PIC 16F877A và cho chạy thử Ví dụ 2: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 8 led đơn nối với PORTC (sắp xếp lần lượt RC0, RC1,.,RC7) theo yêu cầu 8 led sáng dần từ phải qua trái 2 lần sau đó tắt dần từ phải qua trái 3 lần. Hai quá trình trên lặp đi lặp lại, các led cho tích cực ở mức thấp. Ta vẽ sơ đồ nguyên lý: Bài giảng Vi xử lý 2 173 Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A theo yêu cầu đề bài: /*chuong trinh dieu khien 8 led don noi voi port B sang dan 2 lan sau do tat dan 3 lan, phan cung tich cuc muc thap nguoi thuc hien: Nhom tac gia*/ #include "16f877a.h" // tien xu ly, chon VDK 16F877A #fuses hs,nowdt //su dung thach anh tan so cao, khong su dung wdt #include "def_16f877A.h" //su dung file dinh nghia da co #use delay(clock=12mhz) // su dung thach anh la 4mhz //cac chuong trinh con void sangdan() //chuong trinh con sang dan { char i=0xff,j=0; for(j=0;j<=8;j++) { portc=i; i<<=1; delay_ms(100); } } void tatdan()//chuong trinh con tat dan { char i=0,j=0; for(j=0;j<=8;j++) { portc=i; i<<=1; i|=1; delay_ms(100); } } //chuong trinh chinh void main() { char i=0; trisc=0x0; //gan port b lam dau ra Bài giảng Vi xö lý 2 174 while(true) // dieu kien dung thi lam { for(i=1;i<=2;i++) //thuc hien 2 lan sang dan sangdan(); for(i=1;i<=3;i++) //thuc hien 3 lan tat dan tatdan(); } } Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 16 led đơn nối với PORTB, PORTC theo yêu cầu 16 led sáng từ giữa ra 3 lần sau đó tắt từ 2 bên vào 5 lần. Hai quá trình trên lặp đi lặp lại // chuong trinh dieu khien 16 led don noi voi port B va C sang giua ra tat 2 ben vao // pham xuan bach viet nam 2012 Bài giảng Vi xử lý 2 175 #include "16f877a.h" // tien xu ly, chon VDK 16F877A #include "def_16f877A.h" //tien xu ly cac dinh nghia co san #use delay(clock=4mhz) // su dung thach anh la 20mhz void sanggiuara(void) { char i=0xff,k=0xff,j; for(j=0;j<=8;j++) { portb=i; portc=k; delay_ms(100); i<<=1; k>>=1; } } void tatgiuara(void) { char i=0,k=0,j; for(j=0;j<=8;j++) { portb=i; portc=k; delay_ms(100); i>>=1; i|=0x80; k<<=1; k|=1; } } void main(void) { char i=0; trisb=0x0; //gan port b lam dau ra trisc=0x0; while(true) // dieu kien dung thi lam Bài giảng Vi xö lý 2 176 { for(i=1;i<=3;i++) sanggiuara(); for(i=1;i<=5;i++) tatgiuara(); } } 4.6.2 Viết chƣơng trình cho vi điều khiển có chức năng làm đầu vào Ví dụ: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho vi điều khiển PIC 16F877A thực hiện chức năng làm đầu vào điều khiển các led đơn theo yêu cầu: - Nếu RC0 = 1 điều khiển các led đơn sáng dần từ RB0 đến RB7 - Nếu RC0 = 0 điều khiển các led đơn tắt dần từ RB0 đến RB7 // chuong trinh dau vao rc0 dieu khien 8 led don noi voi port B sang dan khi rc0=1 tat dan khi rc0 =0 #include "16f877a.h" // tien xu ly, chon VDK 16F877A #include "def_16f877A.h" //tien xu ly cac dinh nghia co san Bài giảng Vi xử lý 2 177 #use delay(clock=4mhz) // su dung thach anh la 20mhz void sangdan(void) { char i=0xff,j=0; for(j=0;j<=8;j++) { portb=i; i<<=1; delay_ms(100); } } void tatdan(void) { char i=0,j=0; for(j=0;j<=8;j++) { portb=i; i<<=1; i|=1; delay_ms(100); } } void main(void) { trisb=0; //gan port b lam dau ra trisc0=1; //gan c0 lam dau vao while(true) // dieu kien dung thi lam { if(RC0==1) sangdan(); else tatdan(); } } Bài giảng Vi xö lý 2 178 4.6.3 Viết chƣơng trình cho vi điều khiển ứng dụng bộ đếm counter Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho PIC 16F877A đếm xung ngoài đưa tới chân RA4 hiển thị giá trị số đếm từ 00 đến 99 ra 2 led 7 đoạn Chương trình điều khiển cho PIC 16F877A đếm xung ngoài đưa tới chân RA4 hiển thị giá trị số đếm ra 2 led 7 đoạn // Chuong trinh dem xung ngoai dua toi chan ra4 #include"16f877a.h" #include"def_16f877A.h" #use delay(clock=20000000) const char ma7seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//tich cuc muc thap char chuc=0,dv=0; char chuc7s,dv7s; int i=0; // i la bien dem tu 0-99 void tach() { chuc=i/10; //hang chuc se bang i/10 ( tach ra) dv=i%10; //hang don vi se bang so du Bài giảng Vi xử lý 2 179 chuc7s=ma7seg[chuc]; dv7s=ma7seg[dv]; } //chuong trinh con hien thi void hienthi(chuc7s,dv7s) { PORTB=chuc7s; //hien thi hang chuc rC1=0; //cho sang led hang chuc delay_ms(2); //tao tre de mat quan sat duoc rC1=1; //chong lem PORTB=dv7s; //hien thi hang don vi rC0=0; //sang led don vi delay_ms(2); rC0=1; //chong lem } void main() { //char x=0; trisb=0; trisc0=0; trisc1=0; trisa4=1; // output_b(0xff); setup_timer_0(rtcc_ext_h_to_l|rtcc_DIV_1); // setup_timer_0(rtcc_internal|rtcc_div_1); set_timer0(0); while(true) { i=get_timer0(); tach(); hienthi(chuc7s,dv7s); // hien thi hang chuc va don vi if(i==99)set_timer0(0); } } Bài giảng Vi xö lý 2 180 4.6.4 Viết chƣơng trình cho vi điều khiển ứng dụng bộ định thời gianTimer Ví dụ 1: Dùng CCS C, viết chương trình cho PIC 16F877A tạo xung vuông tại chân RB1 có chu kỳ T = 0,1 giây. Thạch anh sử dụng có tần số 4MHZ Để viết chương trình tạo xung vuông có chu kỳ 1 giây trước hết ta đi tính toán số đếm và số lần tràn cho Timer0. Với tần số thạch anh 4Mhz thì trong môt giây có 4.000.000/4 = 1.000.000 chu kỳ lệnh Biết bộ Timer0 có hệ số chia tần lên tới 128. Ở đây tôi chọn bộ chia tần là 32, vậy số đếm của Timer0 trong một giây được tính là: 1.000.000/32 = 31250 Bộ Timer0 là bộ timer 8 bit nên giá trị tối đa thanh ghi nhận được là 28 =256. Ta sẽ tính toán hợp lý để chọn được số đếm trong một giây là 31250 như đã tính ở trên Chọn số đếm của Timer trong một lần tràn là 125, vậy số lần tràn của Timer để đếm được 1 giây là: 31020/125 = 250 Độ rỗng xung 50% thì ta cần tạo thời gian trễ 0,5 giây có nghĩa timer0 cần 125 lần tràn Như vậy ta cần phải bắt đầu số đếm ban đầu của Timer0 là 256 - 125 = 131 (hoặc ta có thể bắt đầu từ -125). Chú ý: Việc chọn lựa cần phải phù hợp để được chia hết. Bài giảng Vi xử lý 2 181 // chuong trinh tao xung vuong #include"16f877a.h" #include"def_16f877A.h" #fuses NOWDT, NOLVP,XT #bit TMR0IF=0xb.2 #use delay(clock=4000000) void delay_05ms() { int8 lantran=0; set_timer0(131); while(lantran<125) if(TMR0IF==1) { set_timer0(131); TMR0IF==0; lantran++; } } void main() { // xac lap dau ra trisb=0; setup_timer_0(rtcc_internal|rtcc_div_32); set_timer0(131); while (true) { output_toggle(PIN_B7); delay_05ms(); } Ví dụ 2: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho PIC 16F877A đếm giây hiển thị giá trị ra 2 led 7 đoạn. Sử dụng Timer0 để tính thời gian, thạch anh ngoài có giá trị 4Mhz. Bài giảng Vi xö lý 2 182 Để viết chương trình đếm giây trước tiên ta sẽ tính toán các tham số cho Timer0. Với tần số thạch anh 4Mhz thì trong môt giây có 4.000.000/4 = 1.000.000 chu kỳ lệnh Biết bộ Timer0 có hệ số chia tần lên tới 128. Ở đây tôi chọn bộ chia tần là 64, vậy số đếm của Timer0 trong một giây được tính là: 1.000.000/64 = 15.625 Bộ Timer0 là bộ timer 8 bit nên giá trị tối đa thanh ghi nhận được là 28 =256. Ta sẽ tính toán hợp lý để chọn được số đếm trong một giây là 15.625 như đã tính ở trên Chọn số đếm của Timer trong một lần tràn là 125, vậy số lần tràn của Timer là: 15.625/125 = 125 Như vậy ta cần phải bắt đầu số đếm ban đầu của Timer0 là 256 - 125 = 131. Chú ý: Việc chọn lựa cần phải phù hợp để được chia hết. // chuong trinh dem giay hien thi tren led 7 doan su dung t0 //portB noi voi cac doan a,b,c..h // port c: C0,c1 lam nhiem vu quet led #include"16f877a.h" Bài giảng Vi xử lý 2 183 #include"def_16f877A.h" #use delay(clock=4000000) //------ dinh nghia ma 7 doan trong rom trong cua vdk const int ma_7doan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; int chuc,don_vi,chuc_7doan,don_vi_7doan; char tran,giay=0; // khai bao ngat ngoai #int_TIMER0 void ngat_timer0() { tran++; set_timer0(131); if (tran==125) { tran=0; //neu bien dem lon hon hoac bang 125 thi gan bien =0 giay++; if(giay==60)giay=0; } } //chuong trinh con hien thi tren led 7 doan void tach() { chuc=giay/10; //tach ra de lay hang chuc va don vi don_vi=giay%10; chuc_7doan=ma_7doan[chuc]; don_vi_7doan=ma_7doan[don_vi]; } void hien_thi() { portb=chuc_7doan; rc0=0; delay_us(100); rc0=1; portb=don_vi_7doan; rc1=0; Bài giảng Vi xö lý 2 184 delay_us(100); rc1=1; } //---------------------------------------------- void main() { //-------dinh nghia cac dau vao ra trisb=0x00; //dat port c lam dau ra noi voi cac doan cua led 7 doan trisc0=0; //quet led trisc1=0; //khai bao cho phep ngat setup_timer_0(rtcc_internal|rtcc_div_64); set_timer0(131); enable_interrupts(int_timer0); //cho phep ngat ngoai enable_interrupts(global); //cho phep ngat toan cuc //ext_int_edge(h_to_l); //cho phep ngat o canh xuong cua xung //clear_interrupt(int_timer0); while (true) { //for(giay=0;giay<5;giay++) tach(); hien_thi(); } } Ví dụ 3: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho PIC 16F877A đếm giây, phút hiển thị giá trị ra 4 led 7 đoạn. Sử dụng Timer1 để tính thời gian, thạch anh ngoài có giá trị 8Mhz. Bài giảng Vi xử lý 2 185 Với tần số thạch anh 8Mhz thì trong môt giây có 8.000.000/4 = 2.000.000 chu kỳ lệnh Biết bộ Timer1 có hệ số chia tần tối đa =8. Ở đây tôi chọn bộ chia tần là 8, vậy số đếm của Timer1 trong một giây được tính là: 2.000.000/8 = 250.000 Bộ Timer0 là bộ timer 16 bit nên giá trị tối đa thanh ghi nhận được là 216 =65536. Chọn số đếm của Timer trong một lần tràn là 50000, vậy số lần tràn của Timer là: 250.000/50000 = 5 Số đếm ban đầu của Timer1 là 65.536 – 50.000 = 15.536 - Chương trình đếm giây phút sử dụng timer 1 // chuong trinh dem giay, phut hien thi tren led 7 doan su dung t1 //portB noi voi cac doan a,b,c..h // port c: C0,c1 lam nhiem vu quet led #include"16f877a.h" #include"def_16f877A.h" #use delay(clock=4000000) //------ dinh nghia ma 7 doan trong rom trong cua vdk const char ma_7doan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; int chuc_7doan,don_vi_7doan,nghin_7doan,tram_7doan; char tran=0,giay=0,phut=0; // khai bao ngat ngoai #int_TIMER1 Bài giảng Vi xö lý 2 186 void ngat_timer1() { tran++; set_timer1(15536); if (tran==5) { tran=0; giay++; if(giay==60) { giay=0; phut++; if(phut==60)phut=0; } } } //chuong trinh con tach hien thi tren led 7 doan void tach() { chuc_7doan=ma_7doan[giay/10]; don_vi_7doan=ma_7doan[giay%10]; nghin_7doan=ma_7doan[phut/10]; tram_7doan=ma_7doan[phut%10]; } void hien_thi() { portb=chuc_7doan; rc0=0; delay_us(100); rc0=1; portb=don_vi_7doan; rc1=0; delay_us(100); rc1=1; Bài giảng Vi xử lý 2 187 portb=nghin_7doan; rc3=0; delay_us(100); rc3=1; portb=tram_7doan; rc2=0; delay_us(100); rc2=1; } //---------------------------------------------- void main() { //-------dinh nghia cac dau vao ra trisb=0; trisc=0; setup_timer_1(T1_internal|T1_div_by_8); set_timer0(15536); enable_interrupts(int_timer1); //cho phep ngat ngoai enable_interrupts(global); //cho phep ngat toan cuc // clear_interrupt(int_timer1); while (true) { tach(); hien_thi(); } } 4.6.3 Viết chƣơng trình cho vi điều khiển ứng dụng ngắt Đếm xung ngoài sử dụng ngắt ngoài: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho PIC 16F877A đếm xung ngoài đưa tới chân RB0 hiển thị giá trị số đếm từ 00 đến 99 ra 2 led 7 đoạn - Sơ đồ phần cứng: Bài giảng Vi xö lý 2 188 RA0/AN0 2 RA1/AN1 3 RA2/AN2/VREF-/CVREF 4 RA4/T0CKI/C1OUT 6 RA5/AN4/SS/C2OUT 7 RE0/AN5/RD 8 RE1/AN6/WR 9 RE2/AN7/CS 10 OSC1/CLKIN 13 OSC2/CLKOUT 14 RC1/T1OSI/CCP2 16 RC2/CCP1 17 RC3/SCK/SCL 18 RD0/PSP0 19 RD1/PSP1 20 RB7/PGD 40 RB6/PGC 39 RB5 38 RB4 37 RB3/PGM 36 RB2 35 RB1 34 RB0/INT 33 RD7/PSP7 30 RD6/PSP6 29 RD5/PSP5 28 RD4/PSP4 27 RD3/PSP3 22 RD2/PSP2 21 RC7/RX/DT 26 RC6/TX/CK 25 RC5/SDO 24 RC4/SDI/SDA 23 RA3/AN3/VREF+ 5 RC0/T1OSO/T1CKI 15 MCLR/Vpp/THV 1 U1 PIC16F877A R2 10k U2 NOTU3 NOT - Chương trình phần mềm: // chuong trinh viet cho ngat ngoai //chan thuc hien ngat ngoai RB0/int //hien thi so lan ngat ngoai ra led 7 doan //------------------------------------------------ #include"16f877a.h" #include"def_16f877A.h" #use delay(clock=4000000) int bien_dem, bien_dem1,chuc,don_vi,chuc_7doan,don_vi_7doan; // khai bao ngat ngoai #int_ext void ngat() { bien_dem=bien_dem+1; if (bien_dem>=50) bien_dem=0; //neu bien dem lon hon hoac bang 15 thio gan bien =0 } //------ dinh nghia ma 7 doan trong rom trong cua vdk const int ma_7doan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //chuong trinh con hien thi tren led 7 doan void tach() { bien_dem1=bien_dem; chuc=bien_dem1/10; //tach ra de lay hang chuc va don vi Bài giảng Vi xử lý 2 189 don_vi=bien_dem1%10; chuc_7doan=ma_7doan[chuc]; don_vi_7doan=ma_7doan[don_vi]; } void hien_thi() { portc=chuc_7doan; rd0=1; rd1=0; delay_us(100); rd1=1; portc=don_vi_7doan; rd0=0; delay_us(100); rd0=1; } //---------------------------------------------- void main() { //-------dinh nghia cac dau vao ra trisc=0x00; //dat port c lam dau ra noi voi cac doan cua led 7 doan trisd0=0; //quet led trisd1=0; trisb0=1; //dat lam dau vao bien_dem=0; //khai bao cho phep ngat enable_interrupts(int_ext); //cho phep ngat ngoai enable_interrupts(global); //cho phep ngat toan cuc ext_int_edge(h_to_l); //cho phep ngat o canh xuong cua xung while (true) { tach(); hien_thi(); } } Bài giảng Vi xö lý 2 190 4.6.4 Viết chƣơng trình cho vi điều khiển sử dụng ADC Ví dụ 1:Đo nhiệt độ phòng sử dụng cảm biến nhiệt LM35 (với tham số cơ bản 10mV/1 độ C), hiển thị giá trị nhiệt độ trên led 7 đoạn - Sơ đồ phần cứng: - Chương trình phần mềm: //chuong trinh viet cho VDK PIC16F877A de do du lieu ADC tu kenh AN0 //cam bien nhiet su dung la lm35 (10mv/1doC) //hien thi gia tri nhiet do tren 2 led 7 doan //portB noi voi cac doan,chan c0,c1 cua portC quet led //------------------------------------------------------------------- #include"16f877a.h" #include"def_16f877A.h" #device *=16 adc=10 //chon dc 10 bit #use delay(clock=40000000) //dinh nghia ma 7 doan const int ma_7doan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; // khai bao bien int adc_read,chuc,don_vi,chuc_7doan,don_vi_7doan; //chuong trinh con hien thi void hien_thi() { Bài giảng Vi xử lý 2 191 portb=don_vi_7doan; rc0=0; rc1=1; delay_us(100); rc0=1; portb=chuc_7doan; rc1=0; delay_us(100); rc1=1; } void main() //chuong trinh chinh { //thiet lap cac dau vao ra trisb=0x00; //dat port b lam dau ra trisc0=0; trisc1=0; //dau ra quet led trisa0=1; //dau vao analog //------------------------ setup_adc_ports(an0); setup_adc(adc_clock_internal); // o day ta su dung adc 10 bit voi vref+=5V, vfef-=0v // ma 1 do C ung voi 10mv ( dung cam bien LM35) // 5000mv - - - voi - - - 1024 ( 2^10) // 10mv - - - voi x >>> x=10mv*1024/5000mv=2.048 so dem while(true) { adc_read=read_adc(); adc_read=adc_read/2.048; chuc=adc_read/10; chuc_7doan=ma_7doan[chuc]; don_vi=adc_read%10; don_vi_7doan=ma_7doan[don_vi]; hien_thi(); } } Bài giảng Vi xö lý 2 192 Ví dụ 2: Đo nhiệt độ phòng sử dụng cảm biến nhiệt LM35 (với tham số cơ bản 10mV/1 độ C), hiển thị giá trị nhiệt độ trên LCD, đo và cảnh báo theo điện áp chỉ thị trên led đơn - Sơ đồ nguyên lý: - Chương trình phần mềm /*chuong trinh do nhiet do dung VDK PIC16F877A dau ra cam bien nhiet LM35 noi voi RA0, chiet ap noi voi RA1 tan so thach anh su dung la 12mhz, hien thi gia tri nhiet do va dien ap tren LCD*/ #include #fuses HS,NOWDT //cau hinh VDK hoat dong o tan so cao, khong WDT #device *=16 ADC=10 //su dung ADC co do phan dai 10 bit #include //su dung file dinh nghia #use delay(clock=12mhz) //su dung tan so thach anh la 12mhz #define LCD_RS_PIN PIN_D0 //dinh nghia chan lua chon thanh ghi cua LCD #define LCD_RW_PIN PIN_D1 //dinh nghia chan doc/ghi cua LCD #define LCD_ENABLE_PIN PIN_D2 //dinh nghia chan cho phep LCD //su dung kieu truyen nibble (4 bit) #define LCD_DATA4 PIN_D4 //dinh nghia chan du lieu D4 cua LCD #define LCD_DATA5 PIN_D5 #define LCD_DATA6 PIN_D6 Bài giảng Vi xử lý 2 193 #define LCD_DATA7 PIN_D7 //dinh nghia chan du lieu D7 cua LCD #include //su dung file LCD.C tu thu vien cua chuong trinh //dinh nghia cac chan noi voi led don de canh bao, tich cuc muc thap #define led1 rb4 //dien ap tren 1V #define led2 rb5 //dien ap tren 2V #define led3 rb6 //dien ap tren 3V #define led4 rb7 //dien ap tren 4V /*khai bao cac bien su dung, bien value0 chua gia tri chuyen doi nhiet do tai kenh 0, bien value1 chua gia tri chuyen doi dien ap tu kenh 1*/ float value0,value1; //-----Chuong trinh chinh thuc hien----- void main() { trisb=0x0; //xac lap cong B lam dau ra led1=1, led2=1, led3=1, led4=1; //tat het cac led dau ra lcd_init(); //khoi tao lcd /*khong nhat thiet phai co 5 dong sau delay_ms(10); lcd_putc("PIC167877A+LM35\n"); //hien thi dong chu va xuong dong lcd_putc("Temprature read"); delay_ms(1000); //tre di mot khoang thoi gian de doc duoc 2 dong chu tren lcd_putc("\f"); //xoa LCD */ //khoi tao adc setup_adc(ADC_CLOCK_INTERNAL ); //chon nguon dao dong ben trong cho ADC setup_adc_ports( RA0_RA1_RA3_ANALOG ); //chon 3 dau vao RA0,1,3 la Analog, va mac dinh vfef+ =5V, vref-=0V while(true) //lap lien tuc doan chuong trinh sau { set_adc_channel(0); //chon ADC kenh 0 delay_us(10); value0 = read_adc(); //doc kenh 0 va cat vao bien value0 set_adc_channel(1); //chon ADC kenh 1 delay_us(10); value1 = read_adc(); //doc kenh 1 va cat vao hien value1 /*thuc hien chuyen tu dien ap sang nhiet do;Vref+=5V tuong ung Bài giảng Vi xö lý 2 194 voi 0-1024 >> 1 so dem ung voi xmv=5000/1024; 1deg =10mv>>>T=ADC*(5000/1024)/10=0.489 */ value0=value0*0.489; value1=value1*(5.0/1023);//*4.89; lcd_gotoxy(1,1); //di chuyen con tro toi cot 1 hang 1 printf(lcd_putc,"T1:=%3.0f\n",value0); //de 3 ky tu de ghi,khong lay sau dau phay, gia tri la so thuc, xuong dong moi printf(lcd_putc,"DA:=%3.2f",value1); //de 3 ky tu de ghi,lay 2 gia tri sau dau phay, gia tri la so thuc //tien hanh so sanh dien ap doc duoc o kenh 1 de canh bao tren led don if(value1<1){led1=1;led2=1;led3=1;led4=1;} //<1V tat cac led if(value1>=1&&value11V sang led1 if(value1>=2&&value12V sang led2 if(value1>=3&&value13V sang led3 if(value1>=4){led1=1;led2=1;led3=1;led4=0; //>4V sang led4 } } } 4.6.5 Viết chƣơng trình cho vi điều khiển sử dụng PWM Ví dụ: Thực hiện điều chế độ rộng xung ứng dụng chức năng pwm của pic16f877a, hiển thị tham số trên LCD - Sơ đồ nguyên lý: Bài giảng Vi xử lý 2 195 - Chương trình phần mềm /*chuong trinh tao xung dung chuc nang PWM Nguoi thuc hien: Nhom tac gia hien thi cac tham so tren lcd tren LCD*/ #include #fuses HS,NOWDT //cau hinh VDK hoat dong o tan so cao, khong WDT #device *=16 ADC=10 //su dung ADC co do phan dai 10 bit #include //su dung file dinh nghia #use delay(clock=12mhz) //su dung tan so thach anh la 12mhz #define LCD_RS_PIN PIN_D0 //dinh nghia chan lua chon thanh ghi cua LCD #define LCD_RW_PIN PIN_D1 //dinh nghia chan doc/ghi cua LCD #define LCD_ENABLE_PIN PIN_D2 //dinh nghia chan cho phep LCD //su dung kieu truyen nibble (4 bit) #define LCD_DATA4 PIN_D4 //dinh nghia chan du lieu D4 cua LCD #define LCD_DATA5 PIN_D5 #define LCD_DATA6 PIN_D6 #define LCD_DATA7 PIN_D7 //dinh nghia chan du lieu D7 cua LCD #include //su dung file LCD.C tu thu vien cua chuong trinh //dinh nghia cac chan noi voi led don de canh bao, tich cuc muc thap #define pwm rc2 //chan dau ra cua pwm void main() { lcd_init(); //khoi tao lcd lcd_putc("UNG DUNG PWM\n"); lcd_putc("DO RONG XUNG 50%"); setup_timer_2(T2_DIV_BY_1,255,1); setup_ccp1(CCP_PWM); //cho phep dieu che do rong xung o dau ra ccp1 set_pwm1_duty(127); //do rong xung la 50% while(TRUE) //khong lam gi nua { } } Bài giảng Vi xö lý 2 196 CÂU HỎI ÔN TẬP CHƢƠNG 4 Câu 1: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 8 led đơn nối với PORTD (sắp xếp lần lượt RD0, RD1,., RD7) theo yêu cầu 8 led sáng dần từ giữa ra 2 lần sau đó tắt dần từ giữa ra 3 lần. Hai quá trình trên lặp đi lặp lại, các led cho tích cực ở mức thấp. Câu 2: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 8 led đơn nối với PORTB (sắp xếp lần lượt RB0, RB1,.,RB7) theo yêu cầu 8 led sáng chạy từ phải qua trái 5 lần sau đó sáng dần 10 lần. Hai quá trình trên lặp đi lặp lại, các led cho tích cực ở mức thấp. Câu 3: Vi điều khiển PIC 16F877A có 8 chân của PORTB và 8 chân của PORTC nối lần lượt tới chân Anode của 16 led đơn. Các chân cathode của 16 led đơn nối qua trở hạn dòng xuống mass. Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển các led đơn nối với PORTB sáng dần, PORTC tắt dần. Hai PORT thực hiện đồng thời. Câu 4: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 16 led đơn nối với PORTB, PORTC theo yêu cầu 16 led sáng dần 3 lần sau đó tắt dần 5 lần. Hai quá trình trên lặp đi lặp lại Bài giảng Vi xử lý 2 197 Câu 5: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình điều khiển cho vi điều khiển PIC 16F877A thực hiện chức năng làm đầu vào điều khiển các led đơn theo yêu cầu: + Nếu RC0 = 0, RC1 = 0 điều khiển các led đơn sáng chạy từ RB0 đến RB7 +Các trạng thái khác của RC1 và RC0 điều khiển các led sáng dần từ 2 đầu vào. Câu 6: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển 8 led đơn nối với PORTC (sắp xếp lần lượt RC0, RC1,.,RC7) theo yêu cầu 8 led sáng chạy từ 2 đầu vào. Sử dụng Timer0 để tạo thời gian trễ giữa các lần thay đổi là 0,5 giây. Thạch anh sử dụng có tần số 4 Mhz, các led cho tích cực ở mức thấp. Câu 7: Cho sơ đồ nguyên lý như hình vẽ. Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển một trò chơi đơn giản cho 5 người chơi là: A,B,C,D,E và một người dẫn chương trình thực hiện theo yêu cầu sau: + Khi một trong 5 thí sinh nhấn phím trả lời câu hỏi thì đèn báo của thí sinh đó sáng lên và chuông kêu trong vòng 3 giây đồng thời các thí sinh còn lại bị mất quyền. + Chỉ có người dẫn chương trình mới có quyền xác lập lại từ đầu (tắt đèn và chuông ). Bài giảng Vi xö lý 2 198 Câu 8: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A thực hiện chuyển đổi điện áp tương tự sang số lần lượt tại 4 đầu vào tương tự từ RA0 đến RA3 với thời gian hiển thị cho mỗi đầu vào là 1 giây, sử dụng Timer1 để tính thời gian trễ, hiển thị kết quả dưới dạng nhị phân trên các led đơn nối với PORTB. Cho thạch anh có tần số bằng 4MHZ. Câu 9: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A đếm xung ngoài đưa tới chân RC0/T1CK1 hiển thị số đếm từ 0 – 5000 dạng nhị phân trên các led đơn nối với PORTB và PORTD, trong đó PORTD hiển thị các bit thấp còn PORTD hiển thị các bit cao. Các led cho tích cực ở mức cao. Câu 10: Dùng CCS C, viết chương trình cho vi điều khiển PIC 16F877A điều khiển đèn giao thông tại một ngã tư gồm 3 đèn xanh, đỏ, vàng theo thời gian như sau: Đèn đỏ: 20 giây, đèn xanh 16 giây. Biết tần số thạch anh sử dụng là 12MHZ. Câu 11: Thiết kế một xe tự hành ( Robốt đơn giản ) sử dụng vi điều khiển PIC 16F877A Yêu cầu: + Xe tự hành theo một vạch trắng dán sẵn. + Khi gặp vật cản xe tự động quay đầu. Câu 12: Thiết kế bộ đo nhiệt độ phòng với dải đo từ 0 độ C đến 70 độ C sử dụng vi điều khiển PIC 16F877A Yêu cầu: + Hiển thị nhiệt độ trong phòng trên led 7 đoạn. + Tạo 1 giao diện trên máy tính để hiển thị nhiệt độ đọc được từ vi điều khiển thông qua chuẩn RS232 của máy tính. Bài giảng Vi xử lý 2 199 + Cảm biến nhiệt độ sử dụng LM35 (có thông số cơ bản là 10mv/1độ C). Câu 13: Thiết kế bộ đo nhiệt độ phòng với dải đo từ 0 độ C đến 70 độ C sử dụng vi điều khiển PIC 16F877A Yêu cầu: + Hiển thị nhiệt độ trong phòng trên led 7 đoạn. + Nếu nhiệt độ trong phòng <150 thì bật lò sưởi. + Nếu nhiệt độ trong phòng >250 thì bật quạt. + Cảm biến nhiệt độ sử dụng LM35 (có thông số cơ bản là 10mv/1độ C). Câu 14: Thiết kế mạch tự động báo tiết học trong trường ĐHSPKT Nam Định sử dụng vi điều khiển PIC 16F877A. Yêu cầu: + Lịch báo giờ theo lịch của trường. + Hiển thị giờ, phút trên led 7 thanh + Khi mất điện không bị mất dữ liệu. + Tín hiệu báo giờ học bằng mạch KĐCS âm tần. Câu 15: Thiết kế mạch quang báo dùng ma trận led sử dụng vi điều khiển PIC 16F877A Yêu cầu: + Hiển thị nội dụng dòng chữ: ― Trường đại học sư phạm kỹ thuật Nam Định, + Ma trận tạo thành đơn sắc hoặc đa sắc gồm 8 hàng 64 cột Câu 16: Thiết kế mạch điều khiển hệ thống điện trong gia đình sử vi điều khiển PIC 16F877A Yêu cầu: + Hệ thống điều khiển được 6 đèn chiếu sáng và 2 quạt trần. + Các thiết bị được tắt mở độc lập. + Việc điều khiển có thể tiến hành thông qua các phím nhấn trên bảng điều khiển hoặc nhận điều khiển xa bằng hồng ngoại (Sử dụng điều khiển: Sony hoặc Philip) Câu 17: Thiết kế mạch điều khiển đèn giao thông tại một ngã tư giao thông sử dụng vi điều khiển PIC 16F877A Yêu cầu: + Mỗi luồng gồm có các đèn: Đỏ, Vàng, Xanh và hai đèn: Đỏ, Xanh cho người đi bộ. + Có bộ đếm lùi hiển thị trên led 7 đoạn để chỉ thị thời gian của các luồng. + Có phím chọn chế độ ưu tiên, phân luồng giao thông. + Có phím chọn chế độ đèn vàng chớp tắt. Câu 18: Thiết kế máy phát xung đa năng sử dụng vi điều khiển PIC 16F877A. Yêu cầu: + Tạo ra ba dạng xung: Vuông, Sin, Tam giác. Bài giảng Vi xö lý 2 200 + Có công tắc để chọn dạng xung. Chọn dải tần số. + Có núm chỉnh để thay đổi biên độ của xung. Câu 19: Thiết kế mạch đo tần số sử dụng vi điều khiển PIC 16F877A. Yêu cầu: + Đo tần số xung vuông đầu vào có tần số biến thiên từ 1Hz đến 1Khz + Hiển thị tần số đo được trên led 7 đoạn. Câu 20: Thiết kế mạch điều khiển động cơ một chiều sử dụng vi điều khiển PIC 16F877A. Yêu cầu: + Điều khiển tốc độ động cơ theo phương pháp PWM. + Kiểm soát tốc độ động cơ thông qua ENCODER và hiển thị trên led 7 đoạn + Có các phím nhấn để chọn: RUN, STOP, FF,RV,INC,DEC. Bài giảng Vi xử lý 2 201 TÀI LIỆU THAM KHẢO Tài liệu tiếng Việt: [1]. Giản Quốc Anh. Ngân hàng câu hỏi Vi xử lý 1. Trường Đại học SPKT Nam Định [2]. Đoàn Văn Ban, Nguyễn Mậu Hân(2006), Xử lý song song và phân tán, NXB Khoa học và Kỹ thuật, Hà nội [3]. Hồ Khánh Lâm. Giáo trình Kỹ thuật Vi xử lý. Tập 1,2. NXB Bưu Điện 2007 [4]. Đỗ Xuân Tiến (2003), Kỹ thuật lập trình điều khiển hệ thống, Nxb Khoa học và Kỹ thuật, Hà Nội. [5]. Đỗ Xuân Tiến. Kỹ thuật Vi xử lý và Lập trình Assembly cho hệ vi xử lý. NXB KHKT- Hà Nội, 2001 Tài liệu tiếng Anh: [6]. Barry B. Brey.The Intel Microprocessors: 8088/8086, 80186/80188, 80286, 80386, 80486, Pentium and Pentium Pro Processor: Architecture, Programming, and Interfacing. Fourth Edition, Prentice Hall, 1997 [7]. I.Scott Mackenzie. The 8051 Microcontroller. 2nd.Ed Prentice Hall 1995 [8]. Daniel tabak (1995), “Advanced Microprocessor”. McGrow Hill. [9]. Gao Q S (1996), “Approach to making supercomputer by microprocessor cellular sector computer of vertical and horizotal processing with virtual common memory”, Conf. parallel Proc. [10]. Richard J Prestopic (1995), “Microprocessorand IC families”. Walter H. [11]. Mostafa AbDelBarr, Hesham ElRewini. Fundamentals of ComputerOrganization and Architecture. Wiley Interscience. 2005 [12]. Hesham ElRewini, Mostafa AbDelBarr. Advanced Computer Architecture and Parallel Processing. Wiley Interscience. 2005 [13]. John Lovine. Pic Microcontroller project book. McGraw-Hill. 2000. [14]. Baskett, Fand Keiler (1987), An Evalusion of the CRAY 1-High speed computer and algorithm organization, New York. [15]. Daniel Tabak (1995), Advanced Microprocessor, McGrow Hill. [16]. Do Xuan Tien, Nguyen Van Hoi (1999), “Parallel algorithms to design multiprocessor systems”, Journal of science and technique, 3(88), pp. 3-9. [17]. Fand Smith (1996), Interference of multiprocessor computer system with interleaved memory, Comm of ACM. Bài giảng Vi xö lý 2 Phụ lục A Nội dung file “def_16f877a” // register definitions #define W 0 #define F 1 // register files #byte INDF =0x00 #byte TMR0 =0x01 #byte PCL =0x02 #byte STATUS =0x03 #byte FSR =0x04 #byte PORTA =0x05 #byte PORTB =0x06 #byte PORTC =0x07 #byte PORTD =0x08 #byte PORTE =0x09 #byte EEDATA =0x10C #byte EEADR =0x10D #byte EEDATH =0x10E #byte EEADRH =0x10F #byte ADCON0 =0x1F #byte ADCON1 =0x9F #byte ADRESH =0x9F #byte ADSESL =0x9F #byte PCLATH =0x0a #byte INTCON =0x0b #byte PIR1 =0x0c #byte PIR2 =0x0d #byte PIE1 =0x8c #byte PIE2 =0x8d #byte OPTION_REG =0x81 #byte TRISA =0x85 #byte TRISB =0x86 #byte TRISC =0x87 Bài giảng Vi xö lý 2 #byte TRISD =0x88 #byte TRISE =0x89 #byte EECON1 =0x18C #byte EECON2 =0x18D //DINH NGHIA BIT #bit RA5 =0x05.5 #bit RA4 =0x05.4 #bit RA3 =0x05.3 #bit RA2 =0x05.2 #bit RA1 =0x05.1 #bit RA0 =0x05.0 #bit RB7 =0x06.7 #bit RB6 =0x06.6 #bit RB5 =0x06.5 #bit RB4 =0x06.4 #bit RB3 =0x06.3 #bit RB2 =0x06.2 #bit RB1 =0x06.1 #bit RB0 =0x06.0 #bit RC7 =0x07.7 #bit RC6 =0x07.6 #bit RC5 =0x07.5 #bit RC4 =0x07.4 #bit RC3 =0x07.3 #bit RC2 =0x07.2 #bit RC1 =0x07.1 #bit RC0 =0x07.0 #bit RD7 =0x08.7 #bit RD6 =0x08.6 #bit RD5 =0x08.5 #bit RD4 =0x08.4 Bài giảng Vi xử lý 2 #bit RD3 =0x08.3 #bit RD2 =0x08.2 #bit RD1 =0x08.1 #bit RD0 =0x08.0 #bit RE2 =0x09.2 #bit RE1 =0x09.1 #bit RE0 =0x09.0 #bit TRISA5 =0x85.5 #bit TRISA4 =0x85.4 #bit TRISA3 =0x85.3 #bit TRISA2 =0x85.2 #bit TRISA1 =0x85.1 #bit TRISA0 =0x85.0 #bit TRISB7 =0x86.7 #bit TRISB6 =0x86.6 #bit TRISB5 =0x86.5 #bit TRISB4 =0x86.4 #bit TRISB3 =0x86.3 #bit TRISB2 =0x86.2 #bit TRISB1 =0x86.1 #bit TRISB0 =0x86.0 #bit TRISC7 =0x87.7 #bit TRISC6 =0x87.6 #bit TRISC5 =0x87.5 #bit TRISC4 =0x87.4 #bit TRISC3 =0x87.3 #bit TRISC2 =0x87.2 #bit TRISC1 =0x87.1 #bit TRISC0 =0x87.0 #bit TRISD7 =0x88.7 #bit TRISD6 =0x88.6 #bit TRISD5 =0x88.5 #bit TRISD4 =0x88.4 #bit TRISD3 =0x88.3 #bit TRISD2 =0x88.2 Bài giảng Vi xö lý 2 #bit TRISD1 =0x88.1 #bit TRISD0 =0x88.0 #bit TRISE2 =0x89.2 #bit TRISE1 =0x89.1 #bit TRISE0 =0x89.0 // INTCON Bits for C #bit gie = 0x0b.7 #bit peie = 0x0b.6 #bit tmr0ie = 0x0b.5 #bit int0ie = 0x0b.4 #bit rbie = 0x0b.3 #bit tmr0if = 0x0b.2 #bit int0if = 0x0b.1 #bit rbif = 0x0b.0 // PIR1 for C #bit pspif = 0x0c.7 #bit adif = 0x0c.6 #bit rcif = 0x0c.5 #bit txif = 0x0c.4 #bit sspif = 0x0c.3 #bit ccp1if = 0x0c.2 #bit tmr2if = 0x0c.1 #bit tmr1if = 0x0c.0 //PIR2 for C #bit cmif = 0x0d.6 #bit eeif = 0x0d.4 #bit bclif = 0x0d.3 #bit ccp2if = 0x0d.0 // PIE1 for C #bit adie = 0x8c.6 #bit rcie = 0x8c.5 Bài giảng Vi xử lý 2 #bit txie = 0x8c.4 #bit sspie = 0x8c.3 #bit ccp1ie = 0x8c.2 #bit tmr2ie = 0x8c.1 #bit tmr1ie = 0x8c.0 //PIE2 for C #bit osfie = 0x8d.7 #bit cmie = 0x8d.6 #bit eeie = 0x8d.4 // OPTION Bits #bit not_rbpu = 0x81.7 #bit intedg = 0x81.6 #bit t0cs = 0x81.5 #bit t0se = 0x81.4 #bit psa = 0x81.3 #bit ps2 = 0x81.2 #bit ps1 = 0x81.1 #bit ps0 = 0x81.0 // EECON1 Bits #bit eepgd = 0x18c.7 #bit free = 0x18C.4 #bit wrerr = 0x18C.3 #bit wren = 0x18C.2 #bit wr = 0x18C.1 #bit rd = 0x18C.0 //ADCON0 #bit CHS0 =0x1F.3 #bit CHS1 =0x1F.4 #bit CHS2 =0x1F.5

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

  • pdftap_bai_giang_vi_xu_ly_2.pdf