



















Preview text:
lOMoAR cPSD| 60776878
TRƯỜNG ĐẠI HỌC KỸ THUẬT - CÔNG NGHỆ CẦN THƠ KHOA KỸ THUẬT CƠ KHÍ BÁO CÁO THỰC HÀNH Môn: VI ĐIỀU KHIỂN
Giảng viên hướng dẫn:
Sinh viên thực hiện:
ThS. Đường Khánh Sơn Võ Thành Giàu-2100406 Lớp: CDT0121
TRƯỜNG ĐẠI HỌC KỸ THUẬT - CÔNG NGHỆ CẦN THƠ KHOA KỸ THUẬT CƠ KHÍ lOMoAR cPSD| 60776878 BÁO CÁO THỰC HÀNH
Môn: VI ĐIỀU KHIỂN
Giảng viên hướng dẫn: Võ Thành Giàu-
ThS. Đường Khánh Sơn 2100406
Sinh viên thực hiện: Lớp: CDT0121 MỤC LỤC
BÀI 1: LED ĐƠN......................................................................................................1
BÀI 2: HIỂN THỊ KÝ TỰ TRÊN LCD....................................................................3
BAI 3: XỬ LÝ NGẮT..............................................................................................9
BÀI 4: XỬ LÝ ADC................................................................................................14 lOMoAR cPSD| 60776878
BÀI 5: TIMER.........................................................................................................22
BÀI 6: GIAO TIẾP I2C............................................................................................28
BÀI 7: GIAO TIẾP RS232.......................................................................................34
BÀI 8: ĐIỀU KHIỂN ĐỘNG CƠ DT.....................................................................37
BÀI 9: ĐO KHOẢNG CÁCH BẰNG CẢM BIẾN SIÊU ÂM SRF0K..................39 lOMoAR cPSD| 60776878 BÀI 1: LED ĐƠN I.Giới Thiệu 1.1 Yêu cầu
Điều kiển các chân I/0 của pic 16F887 với chức năng output thông qua chớt tắt các
LED được nối với PORT E của vi điều khiển. 1.2 LED
LED là diode có khả năng phát ra ánh sáng hay tia hồng ngoại, tia tử ngoại. Có
điện thế phân cực thuận từ 1.5÷3V, đến 3 V. Nhưng điện thế phân cực nghịch ở LED
thì không cao. Do đó, LED rất dễ bị h hỏng do điện thế ngược gây ra.ƣ
Sơ đồ: Mạch điều kiển nối với PORT E
1.4 Cách điều kiển các chân xuất nhập số
PORT E có chức năng nhập số I/0 và chắc năng chuyển đổng ADC. *Cách điều kiển:
Xác định các chân của PORT E là chân INPUT hay là OUTPUT, ta có thể
dùng lệnh: TRISB,TRISC, TRISD hoặc TRISE, nhưng đang điều kiển PORT E nên ta dùng TRISE. -
Mỗi chân sẽ có một trạng thái là 0 (chân OUTPUT) hoặc 1 (chân INPUT). -
Cả ba chân RE2, RE1, RE0 là chân OUTPUT thì: TRISE = 0b00 = 0x00
thứtự bit là RE2-RE1-RE0. -
Chúng ta có thể khai báo mã ở dạng nhị phân 0b… hoặc khai báo mã ở
dạng thập lục phân 0x…(mã hex).
Nếu là chân OUTPUT thì dùng 0 (mức thấp) hoặc 1 (mức cao) để hiển thị
trạng thái của một chân.
Nếu là chân INPUT thì phải đọc tín hiệu của chân đó. lOMoAR cPSD| 60776878
Một số hàm hổ trợ: delay_ms(số mili giây) hoặc delay_us(số micro dây) và các
cấu trúc lập trình for, while, if, if…else,… II.Bài Tập Bài tập 1.1
Yêu cầu viết chương trình chớp tắt LED ở PORT E với thời gian delay 250ms: Chương trình 1.1:
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz void main(){
TRISE = 0x00; //Tat ca cac chan o PORT E la chan xuat (output) while (true){
PORTE = 0x00; //Tat ca cac chan o muc thap --> LED tat
delay_ms(250); //Duy tri trang thai cu trong 250ms
PORTE = 0x07; //Chan RE2, RE1, REO o muc cao-->LED D3, D4, D5 sang delay_ms(250); } } Bài tập 1.2
Yêu cầu viết chương trình chớp tắt LED ở PORT E với thời gian delay 1000: Chương trình 1.2:
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz void main(){
TRISE = 0x00; //Tat ca cac chan o PORT E la chan xuat (output) while (true){
PORTE = 0x00; //Tat ca cac chan o muc thap --> LED tat
delay_ms(1000); //Duy tri trang thai cu trong 250ms
PORTE = 0x07; //Chan RE2, RE1, REO o muc cao-->LED D3, D4, D5 sang delay_ms(1000); } } Bài tập 1.3
Yêu cầu viết chương trình chớp tắt LED ở chân RE1 với thời gian delay 1s và ở
chân RE2 với thời gian delay là 0.5s: Chương trình 1.3: lOMoAR cPSD| 60776878
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz void main(){
TRISE = 0x00; //Tat ca cac chan o PORT E la chan xuat (output) while (True){ PORTE = 0x06; // 0b110; delay_ms(500); PORTE = 0x02; // 0b010; delay_ms(500); PORTE = 0x04; // 0b100; delay_ms(500); PORTE = 0x00; // 0b000; delay_ms(500); } }
BÀI 2: HIỂN THỊ KÝ TỰ TRÊN LCD I.Giới Thiệu 1.1 Yêu cầu
Viết chương trình hiển thị ký tự trên LCD. 1.2 LCD
Chức năng của các chân của LCD: STT Ký hiệu Mô tả Giá Trị 1 VSS GND 0V 2 VCC 5V 3 VEE
Tùy chỉnh độ tương phản 4 RS Lựa chọn thanh ghi RS=0: ghi lệnh RS=1: ghi dữ liệu 5 R/W
Chọn thanh ghi đọc/viết dữ R/W=0: viết dữ liệu liệu R/W=1: đọc dữ liệu 6 E Enable 7 – 10 11-14 BD0 – Chân chuyền dữ liêu 8 bit từ BD0 đến BD7 BD3 BD4 – BD7 15 A Cực dương của LED nền 0 đến 5V 16 K Cực âm của LED nền 0V
*Ngoài sử dụng LCD ta còn có thể sử dụng LED 7 đoạn, LED ma trận để hiển thị dữ liệu 1.3 Sơ dồ mạch lOMoAR cPSD| 60776878
Sơ đồ: Mạch điều kiển LCD
1.4 Cách lệch cơ bản để sử dụng LCD
Sử dụng thư viện LCD_LIB_4BIT.C để điều kiển LCD.
Các bước cơ bản để bắt đầu làm việc với LCD:
Thêm thư viện LCD vào chương trình: #include
Dùng LCD ở chế độ ghi ta dùng lệnh: OUTPUT_LOW(LCD_RW);
Khởi tạo LCD, dùng hàm: LCD_Init();
Chức năng một số hàm trong thư viện được sử dụng: -
void LCD_Init ( void );// ham khoi tao LCD -
void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro -
void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD -
void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD -
void LCD_PulseEnable ( void );// Xung kich hoat -
void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data. Cách sử dụng hàm printf:
-xuất chuỗi, ký tự:printf (“chuỗi, ký tự cần xuất”);
-xuất nguyên số:printf (“N,=%d”,n); -
xuất số thực: printf (“ A,= %.2f”,a); * %.f:
quy định số chữ số sau dấu phẩy. Các cấu
trúc: while, for, if, if…else,… II. Bài Tập Bài tập 2.1
Yêu Cầu viết chương trình hiển thị các ký tự sau lên LCD: DAI HOC KTCN CAN THO Chương trình 2.1: lOMoAR cPSD| 60776878 #include<16f887.h> #include
#fuses HS,NOWDT, NOPROTECT, NOLVP
#use delay(clock=20000000) //Tan so thach anh 20MHz
#include //Them thu vien LCD vao void main(){
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh
LCD_SetPosition(0x05); //Cot 6 dong 1 LCD_PutChar("DAI HOC");
LCD_SetPosition(0x42); //Cot 3 dong 2 LCD_PutChar("KTCN CAN THO"); } Kết Quả
Kết quả hiển thị ký tự lên LCD bài tập 2.1 Bài tập 2.2
Yêu cầu viết chương trình hiển thị LCD theo thứ tự sau: Hàng thứ nhất hiển thị họ và
tên sinh viên; hàng thứ 2 hiển thị mã số sinh viên: Chương trình 2.2: #include<16f887.h> #include
#fuses HS,NOWDT, NOPROTECT, NOLVP lOMoAR cPSD| 60776878
#use delay(clock=20000000) //Tan so thach anh 20MHz #include
//Them thu vien LCD vao void main(){
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh
LCD_SetPosition(0x01); //Cot 2 dong 1 LCD_PutChar("VO THANH GIAU");
LCD_SetPosition(0x44); //Cot 5 dong 2 LCD_PutChar("2100406"); } Kết quả
Kết quả hiển thị ký tự họ tên và mã số sinh viên lên LCD Bài tập2.3
Yêu cầu viết chương trình đếm số từ 0 đếm 999 hiển thị trên LCD: Chương trình 2.3
#include<16f887.h> // Khai bao ten PIC #include
#fuses HS,NOWDT, NOPROTECT, NOLVP #use delay(clock=20000000) //Tan so thach anh 20MHz
#include //Them thu vien LCD vao void main(){ lOMoAR cPSD| 60776878
unsigned long count,i, N_max = 999; //Gia tri dem gioi han int16 sleep = 200; //Thoi gian delay (ms)
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh
LCD_SetPosition(0x00); //Cot 1 dong 1 LCD_PutChar("Dem so:"); while (True){ count = 0;
for (i = 0; i<= N_max; i++)
{ LCD_SetPosition(0x07); //Cot 8 dong
1 printf(LCD_PutChar,"%lu",count); delay_ms(sleep); count++;
if (count > N_max){ //Reset lai bien count count = 0; //Thong bao Reset
LCD_SetPosition(0x46); //Cot 7 dong 2
LCD_PutChar("Reset!"); //Xoa man
hinh delay_ms(2000); //Reset man hanh
LCD_PutCmd(0x01); //Xoa man hinh
LCD_SetPosition(0x00); //Cot 1 dong 1
LCD_PutChar("Dem so:");//xuat ra man hinh } } } } Kết quả lOMoAR cPSD| 60776878 BAI 3: XỬ LÝ NGẮT I.Giới Thiệu 1.1 Yêu Cầu
Viết chương trình xử lý ngắt và nút nhấn 1.2 Hoạt động ngắt
Ngắt là tín hiệu điều khiển bắt vi điều khiển tạm ngưng công việc đang thực
hiện để tiến hành các thao tác khác do ngắt quy định qua chương trình ngắt.
Khi phát hiện ngắt vi điều khiên sẽ hoạt động chương trình động lập với
chương trình gọi là chương trình ngắt.
Cấu trúc của chương trình:
Để viết một hàm phục vụ ngắt ta chỉ việc thêm khai báo #INT_tên_ngắt vào trước
hàm phục vụ cho ngắt đó. Khi đó trình dịch sẽ hiểu đó là địa chỉ hàm cho ngắt, khi
có ngắt tương ứng xảy ra thì nó sẽ nhảy đến vị trí đó.
1.3 Thiếp lập hoạt động ngắt Sử dụng các lệch sau:
ENABLE_INTERRUPTS (level); với level là INT_tên_ngắt hoặc GLOBAL
( ngắt toàn cục): cho phép ngắt.
DISABLE_INTERRUPTS (level); với level giống như trên: vô hiệu quá ngắt.
CLEAR_INTERRUPTS (level); với level không có GLOBAL: xóa cờ ngắt.
EXT_INT_EDGE (soure, edge); với:
Soure = 0,1,2: nguồn ngắt ( ứng với EXT0, EXT1, EXT2).
Edge= L_TO_H, H_TO_L:cạnh kính ngắt
Thiết kế chương trình có dùng ngắt
Trong hàm main(): cho phép ngắt cụ thể (tên_ngắt), ngắt toàn cục (GLOBAL)
và đợi ngắt (EXT_INT_EDGE).
Chương trình xử lý ngắt (đặt trước hàm main ()): xóa cờ ngắt
(CLEAR_INTERRUPTS), cấm ngắt toàn cục (DISABLE_INTERRUPTS
(GLOBAL);), xứ lý ngắt xong rồi cho phép ngắt toàn cục (ENABLE_INTERRUPTS(GLOBAL);). II. Bài Tập Bài tập 3.1
Yêu cầu viết chương trình nhận nút nhấn ở chân B0 của PICf887, cứ mỗi lần nhấn
phím sẽ đảo trạng thái các LED ở PORT E: Sơ đồ mạch: lOMoAR cPSD| 60776878
Mạch đảo trạng thái LED ở PORT E với ngắt ngoài Chương trình bài 3.1
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG,
NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz
#INT_EXT //Ngat ngoai - chan B0 void NgatNgoai()
{ CLEAR_INTERRUPT(INT_EXT); //Xoa co ngat
DISABLE_INTERRUPTS(GLOBAL); //vo hieu hoa ngat toan cuc //Xu ly chuong trinh ngat
PORTE = ~PORTE; //Dao trang thai PORT
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc } void main(){ TRISB = 0XFF; //Chan INPUT TRISE = 0x00; //Chan OUTPUT
PORT_B_PULLUPS(0x01); //Noi dien tro len nguon cho B0
PORTE = 0x00; //Set gia tri ban dau la muc 0
ENABLE_INTERRUPTS(INT_EXT); //Kich hoat ngat ngoai
EXT_INT_EDGE(H_TO_L); //Chon canh ngat, cao xuong thap
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc while
(True){ //Duy tri hoat dong cua vi dieu khien }} Bài tập 3.2
Yêu cầu viết chương trình hiển thị số lần nhấn phím ở chân B0 của
PIC16F887 lên màn hình LCD Sơ đồ mạch: lOMoAR cPSD| 60776878
Mạch đọc số lần nhất nút ở chân B0 hiển thị lên LCD Chương trình 3.2:
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG,
NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz
#include //Them thu vien LCD vao unsigned long count = 0;
#INT_EXT //Ngat ngoai - chan B0 lOMoAR cPSD| 60776878 void NgatNgoai(){
CLEAR_INTERRUPT(INT_EXT); //Xoa co ngat
DISABLE_INTERRUPTS(GLOBAL); //vo hieu hoa ngat toan cuc //Xu ly chuong trinh ngat
delay_ms(20); //Chong nhieu if (INPUT(PIN_B0) == 0){
count++; //Tang gia tri bien dem }
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc } void main(){ TRISB = 0xFF; //Chan INPUT
PORT_B_PULLUPS(0x01); //Noi dien tro len nguon
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh LCD_SetPosition(0x00); LCD_PutChar("Count= ");
ENABLE_INTERRUPTS(INT_EXT); //Kich hoat ngat ngoai
EXT_INT_EDGE(H_TO_L); //Chon canh ngat, cao xuong thap
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc
while (True){ //Duy tri hoat dong cua vi dieu khien LCD_SetPosition(0x06);
printf(LCD_PutChar,"%lu",count); }} Bìa tập 3.3
Yêu cầu viết chương trình nhấn nút của chân B3-B5 của PIC16F887, hiển thị lên màn hình LCD. Sơ đồ mạch: lOMoAR cPSD| 60776878
Mạch đọc số lần nhất nút ở chân B3-B5 hiển thị lên LCD Bài tập 3.4
Yêu cầu Yêu cầu viết chương trình hiển thị số lần nhấn phím ở chân B0 của
PIC16F887 có xử lý chống nhiễu. Chương trình 3.4
#include<16F887.h> //Khai bao ten PIC
#include //Thu vien do nguoi dung dinh nghia
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock = 20000000) //Tan so thach anh 20MHz
#INT_EXT //Ngat ngoai - chan B0 void NgatNgoai()
{ CLEAR_INTERRUPT(INT_EXT); //Xoa co ngat
DISABLE_INTERRUPTS(GLOBAL); //vo hieu hoa ngat toan cuc //Xu ly chuong trinh ngat delay_ms(20); if (INPUT(PIN_B0) == 0){
PORTE = ~PORTE; //Dao trang thai PORT E }
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc } void main(){ TRISB = 0XFF; //Chan INPUT TRISE = 0x00; //Chan OUTPUT
PORT_B_PULLUPS(0x01); //Noi dien tro len nguồn
PORTE = 0x00; //Set gia tri ban dau la muc 0
ENABLE_INTERRUPTS(INT_EXT); //Kich hoat ngat ngoai EXT_INT_EDGE(H_TO_L); //Chon canh ngat, cao xuong thap
ENABLE_INTERRUPTS(GLOBAL); //Cho phep ngat toan cuc while (True){ //Duy tri
hoat dong cua vi dieu khien }} Bài 4 XỬ LÝ ADC I.Giới Thiệu 1.1 Yêu cầu
Đọc giá trị ADC từ biến trở. lOMoAR cPSD| 60776878 1.2 ADC
PIC 16F887 có 2 PORT hổ trợ tính năng ADC là: PORT A và PORT E. Có thể đọc ADC
ở chế độ 10bit (0-1023) hoặc 8bit (0-255) tùy mục đính sử dụng. Điện áp tham chiếu của bộ ADC thường 5V. 1.3 Sơ đồ mạch 1.4 cấu hình ADC
Khai báo chế độ đọc ADC 10bit hay 8bit:
#DEVICE*= 16 ADC 10 hoặc #DEVICE*= 16 ADC 8
Xác định cách thức hoạt động của bộ biến đổi ADC: SETUP_ADC(mode); xác định
trưng lấy tín hiệu ADC và điện thế sử dụng: SETUP_ADC_PORTS(value); chọn
chân để đọc Analog với lệnh READ_ADC, ta khai báo:
SET_ADC_CHANNEL(channel); với channel có giá trị từ 0 – 7 theo thứ tự A0 - A5;
E0 – E2. Sau hàm này chúng ta dùng hàm delay_us(10) để cho kết quả đúng.
Đọc giá trị ADC tù chân đã khai báo ở hàm SET_ADC_CHANNEL với lệnh
READ_ADC(mode); với mode không bắt buộc. II.Bài Tập Bài tập 4.1
Yêu cầu viết chương trình đọc giá trị từ biến trở R7 và hiển thị lên LCD. Chương trình 4.1 #include<16f887.h> #include #device *= 16 ADC = 10
#fuses HS,NOWDT, NOPROTECT, NOLVP lOMoAR cPSD| 60776878
#use delay(clock=20000000) //Tan so thach anh 20MHz
#include //Them thu vien LCD vao void main(){ int16 adc;
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh
//Xac dinh cach thuc hoat dong cua bo ADC
//Thoi gian lay mau bang xung clock
SETUP_ADC(ADC_CLOCK_INTERNAL);
SET_ADC_CHANNEL(3); //Su dung chan A3 doc ADC
delay_us(10); //Dam bao doc gia gia ADC chinh xac while (True){
LCD_PutCmd(0x01); adc = READ_ADC(); //Doc ADC tu chan A3
LCD_SetPosition(0x00); //Cot 1 dong 1 LCD_PutChar("Read ADC:");
printf(LCD_PutChar,"%lu",adc); //Hien thi len LCD delay_ms(1000); }} Kết quả lOMoAR cPSD| 60776878 Bài tập 4.2
Yêu cầu viết chương trình đọc giá trị từ biến trở R7 và xuất ra các giá trị ở các LED ở PORT E Sơ đồ mạch:
Mạch đọc ADC từ biến trở xuất giá trị ra LED Chương trình 4.2 #include<16f887.h> #include lOMoAR cPSD| 60776878 #device *= 16 ADC = 10
#fuses HS,NOWDT, NOPROTECT, NOLVP
#use delay(clock=20000000) //Tan so thach anh 20MHz #include
//Them thu vien LCD vao void main(){ int16 adc, a[10]; int count, i, pos; TRISE = 0x00;
OUTPUT_LOW(LCD_RW); //Che do ghi LCD_Init(); //Khoi tao LCD
LCD_PutCmd(0x01); //Xoa man hinh
//Xac dinh cach thuc hoat dong cua bo ADC lOMoAR cPSD| 60776878
SETUP_ADC(ADC_CLOCK_INTERNAL);
SET_ADC_CHANNEL(3); //Su dung chan A3 doc ADC
delay_us(10); //Dam bao doc gia gia ADC chinh xac while (True){
adc = READ_ADC(); //Doc ADC tu chan A3 OUTPUT_E(adc); //Dua gia tri ADC vao cong E
LCD_SetPosition(0x00); //Cot 1 dong 1 LCD_PutChar("Read ADC:");
LCD_SetPosition(0x09); //Cot 10 dong 1 printf(LCD_PutChar,"%lu",adc); //Hien thi len LCD
//Chuyen sang nhi phan hien thi LCD count = 0; //Chuyen sang ma nhi phan
while (adc > 0){ //Con chia duoc a[count] = adc%2; adc = adc/2; count++; } //Hien len LCD LCD_SetPosition(0x40);
LCD_PutChar("Bin:"); //Gia tri nhi
phan LCD_SetPosition(0x44); pos = 68;
//0x44 = 64 for (i = count - 1; i>=0; i--)
{ printf(LCD_PutChar,"%lu",a[i ]); pos++; LCD_SetPosition(pos); if (i == 0){ break;
//Thoi gian lay mau bang xung clock