Professional Documents
Culture Documents
Đại Học Công Nghiệp Tp.Hcm: Giáo Trình Thực Hành Kỹ Thuật Vi Điều Khiển
Đại Học Công Nghiệp Tp.Hcm: Giáo Trình Thực Hành Kỹ Thuật Vi Điều Khiển
i
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
MỤC LỤC
CHƯƠNG 1 . MÔ HÌNH THÍ NGHIỆM VI ĐIỀU KHIỂN PIC16F877A ....................... 1
1.2.1.1 Cách cài đặt driver phần mềm nạp PICKIT2: ............................................. 6
1.2.3 HƯỚNG DẪN CÀI ĐẶT VÀ SỬ DỤNG PHẦN MỀM PROTEUS. ............. 15
Sơ đồ mạch: .............................................................................................................. 40
iii
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.6 ĐIỀU KHIỂN KHỐI ĐỘNG CƠ BƯỚC: ............................................................ 55
2.8.1.2 Cấu tạo và hoạt động của ma trận LED 8x8 .............................................. 67
iv
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.9.1 Sơ đồ mạch. ...................................................................................................... 78
v
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.1.1 Khối BEEP:
Sơ đồ nguyên lí:
2
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.1.3 Khối led đơn:
300
3
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
4
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.1.6 Khối động cơ bước
5
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.2 GIỚI THIỆU PHẦN MỀM LIÊN QUAN:
1.2.1 Phần mềm nạp PICKIT2:
Có rất nhiều cách để nạp chương trình vào vi điều khiển có thể trực tiếp hay gián tiếp.
Hình 1.9 File cài đặt phần mềm nạp chương trình cho PICKIT2
6
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 3: Nhấn next và tiếp tục
8
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 6: nhấn close để kết thúc cài đặt
9
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.2.1.2 Cách sử dụng phần mềm nạp PICKIT2:
Bước 1: Mở phần mềm giao diện PICKIT2
10
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
11
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.2.2 Phần mềm viết trương trình PIC C
1.2.2.1 Cách cài đặt phần mềm:
Bước 1: kích chuột vào pcwhdupd_5015 để khởi động cài đặt
12
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 2: Nhấn vào file -> new -> Project Wizard để tạo một Project mới khởi tạo
chương trình cần viết.
Bước 3: Đặt tên và chọn thư mục để lưu Project trên giao diện Save As
13
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 4: Trên giao diện mới xuất hiện ( Device Selection), chúng ta lựa chọn VĐK Pic
mình đang muốn lập trình, tần số thạch anh tương thích …
14
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 6: Sau khi viết xong chương trình, ấn nút Rebuild để dịch chương trình, tạo file
hex.
15
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
16
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bước 4: chờ quá trình cài đặt hoàn tất.
17
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
1.2.3.2 Cách sử dụng phần mềm PROTEUS
Kích chuột vào Shorcut của Proterus 8.6, để khởi động phần mềm.
Kích chuột vào để vào giao diện vẽ mạch nguyên lý và mô phỏng. Màn hình giao
diện được hiển thị như hình vẽ
18
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chứa một số lệnh ở dạng Shortcut như New, Save, Open … và các nút thường sử dụng sau:
Undo/ Redo
Các lệnh tác động lên đối tượng ( đã được chọn trước)
b) Thanh công cụ
Junction Dot – Đánh dấu điểm nối, nơi giao nhau của đường dây
19
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Sub Circuit – Mạch phụ ( Thiết kế mạch phụ được dùng trong trường hợp
một mạch lặp đi lặp lại nhiều lần trong các hệ thống khác nhau)
Inter – sheet Terminal – Các đầu cực ( như tín hiệu nguồn, đất của mạch,
đầu vào, đầu ra …)
Device Pin – Vẽ chân linh kiện ( Khi thiết kế tạo linh kiện mới, không có
trong thư viện)
Voltage Probe – Đầu đo ( gồm đầu đo như điện áp, dòng điện …)
Hiển thị khái quát vùng làm việc hiện hành, khung màu xanh dương biểu thị cho toàn bản
vẽ, khung màu xanh lá biểu thị cho phần bản vẽ đang hiển thị trên vùng làm việc chính. Khi
chúng ta chọn linh kiện, ký hiệu nguyên lý của linh kiện cũng được hiển thị lên vùng này.
e) Vùng làm việc chính:
Vùng này là nơi thực hiện các thao tác để thiết kế bản vẽ mạch điện.
20
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
f) Cách thiết kế một bản vẽ.
Sau khi khời động ta có màn hình giao diện với vùng làm việc chính trống, không có linh
kiện, thiết bị. Để vẽ một mạch điện, ta phải chọn được các linh kiện, hay thiết bị cần thiết của
mạch và kết nối chúng lại với nhau theo đúng yêu cầu thiết kế.
Cách chọn các linh kiện, thiết bị từ thư viện thiết bị:
Bước 1: Chọn nút Component.
Bước 2: Nhấp nút P ( Pick Device).
Bước 1
Khi đó màn hình chọn thiết bị xuất hiện.
Bước 2
21
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
22
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2 RB0/AN12/INT 33
RA0/AN0/ULP/C12INO- 34
3
RB1/AN10/C12IN3- 35
RA1/AN1/C12IN1- RB2/AN8
RB3/AN9/PGM/C12IN2- 36
4 RA2/AN2/VREF-/CVREF/C2IN+ RB4/AN11 37
RB5/AN13/T1G 38
5 RA3/AN3/VREF+/C1IN+ RB6/ICSPCLK 39
RB7/ICSPDAT 40
6 RA4/T0CKI/C1OUT
Y1
7 RA5/AN4/C2OUT/SS
C1
14 RA6/OSC2/CLKOUT
VCC
C2 13 RA7/OSC1/CLKIN RC0/T1OSO/T1CKI 15
GND W1 RC1/T1OSI/CCP2 16
RC2/T1OSI/CCP1 17
RC3/SCK/SCL 18
1 8 RE0/AN5 RC4/SDI/SDA 23
2
VCC RC5/SDO 24
3
GND 9 RE1/AN6 RC6/TX/CK 25
RST
4
RB7 RC7/RX/DT 26
5 RB6 10 RE2/AN7
1 RE3/VPP/MCLR
31
RA0/AN0/ULP/C12INO- RD0 19
12 RA0/AN0/ULP/C12INO- RD1 20
GND RD2 21
RD3 22
RD4 27
VCC 11 RA0/AN0/ULP/C12INO- RD5/P1B 28
RD6/P1C 29
32 RA0/AN0/ULP/C12INO- RD7/P1D 30
23
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.2.1 Sơ đồ mạch
Mạch dùng chân RC0 kết nối với ULN2803 để đóng mở relay RL.
2.2.2 Lưu đồ
START
KHỞI TẠO
PORT C
KÍCH HOẠT
CHÂN RC0
ĐỢI NGẮT
#include<16f877a.h>
#include<def_877a.h>
#usedelay(clock=4000000)
void main(void)
{
TRISB=0xFE;
relay=1;
while(1)
{
}
}
25
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.3 ĐIỀU KHIỂN KHỐI LED ĐƠN:
Dùng vi điều khiển 16F887 điều khiển 8 led đơn sáng tắt.
2.3.1 Sơ đồ mạch
26
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.3.2 Lưu đồ chớp tắt đèn
START
KHỞI TẠO
PORT D
BẬT ĐÈN
(PORT D =0xFF)
TẮT ĐÈN
(PORT D =0x00)
Hình 2.5 Lưu đồ thuật giải điều khiển chớp tắt đèn LED đơn
27
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.3.3 Chương trình chớp tắt led
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP,
void main()
{
Trisd=0x00;
while(true)
{
Portd=0xFF;
delay_ms(500);
Portd=0x00;
delay_ms(500);
}
}
28
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình chính gồm: Lệnh “TRISD=0x00;” có chức năng khởi tạo portD là port xuất
dữ liệu. Lệnh “portD=0xFF;” có chức năng xuất dữ liệu 0xFF ra portD làm 8 led sáng, tiến hành
gọi hàm delay, sau đó xuất dữ liệu 0x00 ra portD làm 8 led tắt, gọi hàm delay và lặp lại.
Các thông số cấu hình: “NOWDT” là không sử dụng bộ định thời giám sát (No watchdog timer),
“NOPUT” là không sử dụng bộ định thời kéo dài thêm thời gian reset vi điều khiển (chờ nguồn
điện ổn định, thời gian kéo dài thêm 72ms - Power up timer), “HS” là sử dụng bộ dao động tần
số cao từ 4MHz đến 20MHz (High Speed), “NOPROTECT” là không sử dụng bảo vệ mã code
nạp vào bộ nhớ flash bên trong, “NOLVP” là không sử dụng chế độ nạp code dùng nguồn điện
áp thấp 5V mà dùng nguồn 12,5V.
29
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Lưu đồ:
START
Gán kq =0x00
Gán i =8
YES
j<i
NO
Gán kq = Port D
i = i-1
NO YES
i >= 1
Hình 2.6 Lưu đồ thuật giải điều khiển LED đơn sáng dồn
30
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
signed int i,j;
int kq,xoay;
void main()
{
Trisd=0x00;
while(true)
{
kq=0x00;
for(i=8;i>=1;i--)
{
xoay=0x01;
Portd=xoay|kq;
delay_ms(500);
for(j=1;j<i;j++)
{
xoay=xoay<<1;
Portd=kq|xoay;
delay_ms(500);
}
kq=portD;
}
}
}
31
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bài 2: Điều khiển led sang dịch:
NO
YES
i<1
Chương trình:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
signed int i;
void main()
{ trisd=0x00;
while(true)
{ portd=0x01;
delay_ms(500);
for(i=8;i>1;i--)
{ portd=portd<<1;
delay_ms(500);
}
}
}
32
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bài 3: điều khiển led sáng dần và tắt dần:
Lưu đồ:
START
YES
i>1
NO
Vòng lặp Gán i = 8
while
NO YES
i >= 1
Hình 2.8 Lưu đồ thuật giải điều khiển LED đơn sáng dần và tắt dần
33
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
signed int i;
void main()
{
trisd=0x00;
while(true)
{
portd=0x01;
delay_ms(500);
for(i=8;i>1;i--)
{
portd=portd<<1|0x01;
delay_ms(500);
}
for(i=8;i>=1;i--)
{
portd=portd>>1;
delay_ms(500);
}
}
}
34
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Bài 4: Chương trình điều khiển led sáng dồn có nút nhấn. Nút nhấn (nối với chân RB1)
dùng để reset lại chu kỳ sáng dồn.
Sơ đồ mạch:
Hình 2.9 Sơ đồ nguyên lý mạch điều khiển LED đơn bằng một phím
Về thuật toán giống như bài 2 tuy nhiên, hàm delay_ms(500) được thay thế bằng vòng lặp
for:
for(cho=0;cho<25000;cho++)
{
if(!RB1)
goto kiem_tra;
}
vòng lặp trên vừa để kiểm tra phím nối với RB1 có được ấn không, vừa để tạo trễ (nếu phím
RB1 không được ấn).
35
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình:
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
#use delay(clock=4000000)
signed int8 i,j;
byte xoay,kq;
long cho;
void main()
{ trisB=0xff;
trisD=0x00;
kiem_tra:
portD=0x00;
sang_don:
kq=0x00;
for(i=8;i>0;i--)
{ xoay=0x01;
portD=kq|xoay;
for(cho=0;cho<25000;cho++)
{ if(!RB1)
goto kiem_tra;
}
for(j=1;j<i;j++)
{ xoay=xoay<<1;
portD=kq|xoay;
for(cho=0;cho<25000;cho++)
{ if(!RB1)
goto kiem_tra;
}
}
kq=portD;
}
goto sang_don;
}
36
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.4 ĐIỀU KHIỂN KHỐI LED 7 ĐOẠN:
Dùng vi điều khiển 16F877A kết nối với 1 led 7 đoạn anode chung và viết chương trình
đếm từ 0 đến 9 với thời gian trễ tuỳ chọn.
2.4.1 Sơ đồ mạch:
37
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.4.2 Lưu đồ
START
NO YES
i >=9
Hình 2.11 Lưu đồ thuật giải sử dụng LED 7 đoạn hiển thị số 0-9
38
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.4.3 Chương trình
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
const unsigned char LED[10]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main()
{
unsigned int i;
TRISD=0x00;
PORTD=0x00;
while(true)
{
for(i=0;i<=9;i++)
{
PORTD=LED[i];
delay_ms(500);
}
}
}
39
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.4.5 Một số ví dụ về dùng VĐK điều khiển led 7 đoạn:
Bài 1: điều khiển LED 7 đoạn đếm từ 0 →9999:
Sơ đồ mạch:
40
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
const unsigned char LED[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main()
{
unsigned long a; unsigned char b;
unsigned char c; unsigned long d=0;
TRISB=0xF0;
TRISD=0x00;
PORTD=0x00;
while(1)
{
if(++a>500)
{
a=0;
if(++c>50)
{ c=0;
if(++d>9999) d=0;
}
if(++b>3) b=0;
switch(b)
{
case 0: PORTD=LED[d/1000]; break;
case 1: PORTD=LED[(d%1000)/100]; break;
case 2: PORTD=LED[(d%100)/10]; break;
case 3: PORTD=LED[d%10]; break;
}
PORTB =b;
}
}
}
41
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.5 ĐIỀU KHIỂN KHỐI MA TRẬN PHÍM:
Dùng ma trận phím điều khiển hiển thị led từ 0 → 9:
2.5.1 Sơ đồ mạch
Hình 2.13 Sơ đồ nguyên lý kết nối khối ma trận phím với LED 7 đoạn
42
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.5.2 Lưu đồ
Quét mã phím:
Bắt đầu
MAQUETHANG
HÀNG=0, CỘT=FF,
MAPHIM=FF
Đ
O1=0 CỘT=0
S
Đ
O2=0 CỘT=1
S
Đ
O3=0 CỘT=2
Đ
O4=0 CỘT=3
CỘT=FF
Đ
MAPHIM=HANG*4+COT
Return
MAPHIM
Hình 2.14 Lưu đồ thuật giải chương trình con quét ma trận phím
43
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Kiểm tra mã phím và xuất ra led:
begin
S
Có nhấn
Hình 2.15 Lưu đồ thuật giải kiểm tra mã phím được nhấn và xuất ra LED 7 đoạn
44
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.5.3 Chương trình
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
#define keyO1 RC0
#define keyO2 RC1
#define keyO3 RC2
#define keyO4 RC3
#define keyI1 RC4
#define keyI2 RC5
#define keyI3 RC6
#define keyI4 RC7
const unsigned char LED[16]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void main(void)
{ unsigned char nutnhan;
TRISD=0x00; TRISC=0xF0; PORTD=0xFF;
while(1)
{ nutnhan=key();
if(nutnhan==1) PORTD=LED[0];
else if(nutnhan==2) PORTD=LED[1];
else if(nutnhan==3) PORTD=LED[2];
else if(nutnhan==4) PORTD=LED[3];
else if(nutnhan==5) PORTD=LED[4];
else if(nutnhan==6) PORTD=LED[5];
else if(nutnhan==7) PORTD=LED[6];
else if(nutnhan==8) PORTD=LED[7];
else if(nutnhan==9) PORTD=LED[8];
else if(nutnhan==10) PORTD=LED[9];
else if(nutnhan==11) PORTD=LED[10];
else if(nutnhan==12) PORTD=LED[11];
else if(nutnhan==13) PORTD=LED[12];
else if(nutnhan==14) PORTD=LED[13];
else if(nutnhan==13) PORTD=LED[12];
else if(nutnhan==14) PORTD=LED[13];
else if(nutnhan==15) PORTD=LED[14];
else if(nutnhan==16) PORTD=LED[15];
}
}
45
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
unsigned char key(void)
{ keyO1=0; keyO2=1; keyO3=1; keyO4=1;
if(keyI1==0)
{return 1; }
else if(keyI2==0)
{return 2; }
else if(keyI3==0)
{return 3; }
else if(keyI4==0)
{return 4;}
keyO1=1; keyO2=0; keyO3=1; keyO4=1;
if(keyI1==0)
{ return 5;}
else if(keyI2==0)
{return 6;}
else if(keyI3==0)
{ return 7;}
else if(keyI4==0)
{return 8;}
keyO1=1; keyO2=1; keyO3=0; keyO4=1;
if(keyI1==0) { return 9; }
else if(keyI2==0)
{return 10;}
else if(keyI3==0)
{return 11;}
else if(keyI4==0)
{return 12;}
keyO1=1; keyO2=1; keyO3=1; keyO4=0;
if(keyI1==0) { return 13;}
else if(keyI2==0)
{return 14;}
else if(keyI3==0)
{return 15;}
else if(keyI4==0)
{return 16;}
return 0;
}
46
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.5.4 Một số bài tập ví dụ về ma trận phím:
2.5.4.1 Bài1: dùng ma trận phím để điều khiển beef;
Yêu cầu: Sinh viên phân tích đoạn chương trình dưới đây, thiết kế phần cứng phù hợp để
khi ấn mỗi nút trong ma trận phím, thì loa sẽ kêu.
void main(void)
{
unsigned char keybuf;
TRISD=0B11111011;
TRISC=0B11110000;
while(True)
{
keybuf=key();
if(keybuf==1) beep=1;
else if(keybuf==2) beep=1;
else if(keybuf==3) beep=1;
else if(keybuf==4) beep=1;
else if(keybuf==5) beep=1;
else if(keybuf==6) beep=1;
else if(keybuf==7) beep=1;
else if(keybuf==8) beep=1;
else if(keybuf==9) beep=1;
else if(keybuf==10) beep=1;
else if(keybuf==11) beep=1;
else if(keybuf==12) beep=1;
else if(keybuf==13) beep=1;
else if(keybuf==14) beep=1;
else if(keybuf==15) beep=1;
else beep=0;
}
}
47
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.5.4.2 Sử dụng các phím điều khiển relay:
Sơ đồ kết nối:
Nối 8 phím với cổng RC, Relay với chân RD0 như hình vẽ
48
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình 1:
Khi bấm phím nối với RC0 thì tiếp điểm của Relay sẽ đổi trạng thái.
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
#define P1 RC0
#define relay RD0
void main(void)
{
TRISD=0B11111110;
TRISC=0B11111111;
PORTD=0x00;
while(true)
{
if (P1==0)
{
relay=!relay;
delay_ms(100);
}
}
}
Yêu cầu: Sinh viên thực hành, phân tích chương trình, viết lại lưu đồ thuật giải.
49
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
chương trình 2:
Khi bấm phím nối với RC0 thì tiếp điểm của Relay đóng, khi bấm phím nối với RC1 thì
tiếp điểm của Relay mở.
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=4000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
#define mo_relay RC0
#define tat_relay RC1
#define relay RD0
void main(void)
{
TRISD=0xFE;
TRISC=0xFF;
portd=0x00;
while(true)
{
if(mo_relay==0)
{ relay=1;
delay_ms(100);
}
if(tat_relay==0)
{ relay=0;
delay_ms(100);
}
}
}
Yêu cầu: Sinh viên thực hành, phân tích chương trình, viết lại lưu đồ thuật giải.
50
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình 3:
Kết nối VĐK với các phím và 8 LED đơn như hình vẽ. Sử dụng các phím nối với RC0,
RC1, RC2 điều khiển các LED đơn như sau:
- Phím RC0 được nhấn, chế độ sáng dồn được thực hiện.
- Phím RC1 được nhấn, chế độ chớp – tắt được thực hiện.
- Phím RC2 được nhấn, chế độ sáng dịch được thực hiện
51
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP
#use delay(clock=4000000)
signed int8 i,j;
byte xoay,kq;
long cho;
void main()
{
trisc=0xff; trisD=0x00;
portD=0x00;
kiem_tra:
if(!RC0) goto sang_don;
if(!RC1) goto chop_tat;
if(!RC2) goto sang_dan;
goto kiem_tra;
//chuong trinh sang don
sang_don:
kq=0x00;
for(i=8;i>0;i--)
{
xoay=0x01;
portD=kq|xoay;
for(cho=0;cho<25000;cho++)
{
if(!RC1) goto chop_tat;
if(!RC2) goto sang_dan;
}
for(j=1;j<i;j++)
{
xoay=xoay<<1;
Portd=kq|xoay;
for(cho=0;cho<25000;cho++)
{
if(!RC1) goto chop_tat;
if(!RC2) goto sang_dan;
}
}
kq=portD;
}
goto sang_don;
52
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
53
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Lưu ý:
Khi hiển thị đèn LED, cần có khoảng thời gian trễ để đèn sáng. Trong các chương trình
ở mục 2.3 thường sử dụng hàm delay_ms(500) để tạo khoảng trễ 500ms. Tuy nhiên khi
sử dụng các phím để điều khiển LED, VĐK cần kiểm tra xem phim có được nhấn
không. Để tránh phím được nhấn trong khoảng thời trễ VĐK không kiểm tra được thì
hàm delay_ms(500) được thay thế bằng vòng lặp for với biến cho, trong vòng lặp có
kiểm tra phím nhấn, ví dụ:
for(cho=0;cho<25000;cho++)
{
if(!RC0) goto sang_don;
if(!RC1) goto chop_tat;
}
Yêu cầu:
Sinh viên phân tích và viết lưu đồ thuật giải của đoạn chương trình trên.
54
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.6 ĐIỀU KHIỂN KHỐI ĐỘNG CƠ BƯỚC:
2.6.1 Điều khiển động cơ bước quay:
2.6.1.1 Sơ đồ mạch:
55
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.6.1.2 Lưu đồ:
START
NO YES
i<4
Hình 2.19 Lưu đồ thuật giải phát xung điều khiển động cơ bước
2.6.1.3 Chương trình:
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
#use delay(clock=4000000)
unsigned int i;
void main()
{ TRISC=0B11000011;
PORTC=0B00000000;
while(true)
{ portc=0B00100000;
delay_us(2500);
for(i=0;i<4;i++)
{ portc=portc>>1;
delay_us(2500);
}
}
}
56
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình đã sử dụng câu lệnh dịch bít cho PORTC để tại một thời điểm chỉ có một
cuộn dây được cấp nguồn.
57
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.6.2.2 Lưu đồ:
START
YES
Phím RD0=0?
NO
YES
NO Quay_ngược
Phím RD1=0?
Quay_thuận
Dừng động cơ
NO YES
i<4
Hình 2.21 Lưu đồ thuật giải điều khiển động cơ bước bằng phím
58
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.6.2.3 Chương trình
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG,
NOBROWNOUT, NOLVP,
#use delay(clock=4000000)
unsigned int i;
unsigned long cho;
void main()
{
TRISC=0B11000011;
PORTC=0B00000000;
TRISD=0xFF;
kiem_tra:
if(!RD0) goto quay_thuan;
if(!RD1) goto quay_nguoc;
goto kiem_tra;
quay_thuan:
portc=0B00000000;
delay_us(2500);
quay_thuantt:
portc=0B00100000;
//delay_us(2500);
for(cho=0;cho<300;cho++)
{
if(!RD1) goto quay_nguoc;
}
portc=0B00010000;
for(cho=0;cho<300;cho++)
{
if(!RD1) goto quay_nguoc;
}
portc=0B00001000;
for(cho=0;cho<300;cho++)
{
if(!RD1) goto quay_nguoc;
}
59
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
portc=0B00000100;
for(cho=0;cho<300;cho++)
{
if(!RD1) goto quay_nguoc;
}
goto quay_thuantt;
quay_nguoc:
portc=0B00000000;
delay_us(2500);
quay_nguoctt:
portc=0B00000100;
//delay_us(2500);
for(cho=0;cho<500;cho++)
{
if(!RD0) goto quay_thuan;
}
portc=0B00001000;
for(cho=0;cho<500;cho++)
{
if(!RD0) goto quay_thuan;
}
portc=0B00010000;
for(cho=0;cho<500;cho++)
{
if(!RD0) goto quay_thuan;
}
portc=0B00100000;
for(cho=0;cho<500;cho++)
{
if(!RD0) goto quay_thuan;
}
goto quay_nguoctt;
}
Lưu ý: : Nên điều khiển đồng cơ đổi chiều khi đã dừng động cơ. Không nên đảo liền
lập tức vì là motor step nên rất dể hỏng khi thức hiện đảo chiều trực tiếp như vậy.
Bài tập: Sinh viên tự thiết kế bổ xung thêm nút nhấn dừng động cơ.
60
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.7 ĐIỀU KHIỂN KHỐI LCD:
2.7.1 Điều khiển hiển thị LCD:
2.7.1.1 Sơ đồ mạch:
START
Hình 2.23 Lưu đồ thuật giải hiển thị 2 dòng trên màn hình LCD
61
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.7.1.3 Chương trình:
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
#use delay(clock=4000000)
#define LCD_ENABLE_PIN PIN_B3 // chan E noi voi B3
#define LCD_RS_PIN PIN_B5 // RS noi voi B5
#define LCD_RW_PIN PIN_B4
#define LCD_DATA4 PIN_D4 //D4 noi voi D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c> // su dung thu vien lcd.c
void main()
{
lcd_init();
lcd_gotoxy(1,1);
lcd_putc("DAI HOC CONG NGHIEP");
lcd_gotoxy(1,2);
lcd_putc(" TP HO CHI MINH");
while(TRUE)
{
;
}
}
62
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.7.2 Bài tập:
Chương trình sau hiển thị trên LCD hai màn hình như Hình 2.24 và Hình 2.25
Ở màn hình trạng thái 1, thông số phần trăm (%) sẽ thay đổi tương ứng với ô trống được
bôi đen. Khi thông số phần trăm đạt 100%, màn hình trạng thái 2 được hiển thị.
Yêu cầu: Sinh viên thực hành, phân tích chương trình từ đó viết lưu đồ thuật giải của
chương trình.
63
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
#include <16f877.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP,
#use delay(clock=4000000)
#define LCD_ENABLE_PIN PIN_B3 // chan E noi voi B3
#define LCD_RS_PIN PIN_B5 // RS noi voi B5
#define LCD_RW_PIN PIN_B4
#define LCD_DATA4 PIN_D4 //D4 noi voi D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c> // su dung thu vien lcd.c
void clear_lcd(void);
void main()
{
//khai bao bien cuc bo
unsigned char TrangThai=0;
float SoThuc=0;
lcd_init();//khoi dong ket noi LCD
clear_lcd();
TrangThai=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"LOADING.... %03u",TrangThai); lcd_putc('%');
lcd_gotoxy(1,2);
for(TrangThai=1;TrangThai<=16;TrangThai++)
{
lcd_putc(219);
}
delay_ms(500);
for(TrangThai=1;TrangThai<=16;TrangThai++)
{
lcd_gotoxy(12,1);
SoThuc=SoThuc+6.25f;
printf(lcd_putc,"%03.1f",SoThuc);lcd_putc('%');
lcd_gotoxy(TrangThai,2);
lcd_putc(255);
delay_ms(500);
}
64
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
clear_lcd();
while(TRUE)
{
//TODO: User Code
lcd_gotoxy(1,1);
printf(lcd_putc," LAP TRINH CCS ");
lcd_gotoxy(1,2);
printf(lcd_putc," HELLO 16F877A!");
}
}
void clear_lcd(void)
{
lcd_send_byte(0,1);//lay trong thu vien lcd.c
delay_ms(2);
}
65
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.8 ĐIỀU KHIỂN KHỐI MA TRẬN LED:
2.8.1 Điều khiển ma trận LED bằng IC138
2.8.1.1 Sơ đồ mạch
67
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
68
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.8.1.3 Chương trình
Chương trình hiển thị chữ A
#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
void delay(unsigned int t)
{
unsigned int x,y;
for(x=0;x<t;x++)
for(y=0;y<123;y++);
}
void main()
{
TRISB=0B11100000;
PORTB=0X00;
TRISD=0X00;
PORTD=0X00;
TRISC=0X00;
PORTC=0X00;
while(1)
{
PORTB = 0x18; //tat toan bo LED
PORTD = 0x18; //xuat ma led dong 1
PORTC = 0x18;
PORTB=0x18; //bat sang dong 1
delay(1);
//---------Hien thi xong dong thu 2--------//
PORTB = 0x18; //tat toan bo LED
PORTD = 0x3C; //xuat ma led dong 2
PORTC = 0x3C;
PORTB=0x19; //bat sang dong 2
delay(1);
//---------Hien thi xong dong thu 3--------//
PORTB = 0x18; //tat toan bo LED
PORTD = 0x66; //xuat ma led dong 3
PORTC = 0x66;
PORTB=0x1A; //bat sang dong 3
delay(1);
69
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
70
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình hiển thị chữ A viết ngắn gọn:
#include <16F877A.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
unsigned char maled[8]={0x18,0x3C,0x66,0x66,0x7E,0x7E,0x66,0x66};
unsigned char maquet[8]={0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
void delay(unsigned int t) //hàm delay
{
unsigned int x,y;
for(x=0;x<t;x++)
{
for(y=0;y<123;y++);
}
}
void main()
{
int i;
TRISB=0B11100000;
PORTB=0X00;
TRISD=0X00;
PORTD=0X00;
TRISC=0X00;
PORTC=0X00;
while(1)
{
for(i=0;i<8;i++)
{
PORTD = maled[i]; //xuat ma led dong i
PORTC = maled[i];
PORTB = maquet[i]; //bat sang dong i
delay(1); //delay de mat kip nhin
}
}
}
72
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình hiển thị dòng chữ chạy trên ma trận LED
Ví dụ dòng chữ chạy trên ma trận LED là : K14A
Khi đó mảng một chiều maled gồm 32 phần tử, mỗi một chữ hiển thị gồm 8 phần tử trong
mảng một chiều.
#include <16F877A.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, PUT,XT,
unsigned char maled[32]={0x22,0x24,0x28,0x30,0x30,0x28,0x24,0x22, //K
0x08,0x18,0x28,0x48,0x08,0x08,0x08,0x08,//1
0x08,0x18,0x28,0x48,0x7E,0x08,0x08,0x08,//4
0x18,0x3C,0x66,0x66,0x7E,0x7E,0x66,0x66};//A
unsigned char
maquet[16]={0x10,0x08,0x11,0x09,0x12,0x0A,0x13,0x0B,0x14,0x0C,0x15,0x0D,0x1
6,0x0E,0x17,0x0F};
void delay(unsigned int t) //hàm delay
{
unsigned int x,y;
for(x=0;x<t;x++)
for(y=0;y<123;y++);
}
void main()
{
int i,k=0,n;
TRISB=0B11100000;
PORTB=0X00;
TRISD=0X00;
PORTD=0X00;
TRISC=0X00;
PORTC=0X00;
while(1)
{
for(n=0;n<4;n++,k=0)
{
while(k<50)
{
for(i=0;i<8;i++)
{
PORTD = maled[(n*8)+i];
73
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Yêu cầu:
1. Từ chương trình hiển thị dòng chữ chạy trên ma trận LED, sinh viên viết lại lưu đồ thuật
giải cho chương trình.
2. Viết chương trình để ma trận LED chạy dòng chữ : KHOA ĐIEN
74
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.8.2 Chương trình sử dụng IC595:
2.8.2.1 Sơ đồ mạch
75
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
#include <16F877A.h>
#include <def_877a.h>
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG,
NOBROWNOUT, NOLVP, NOCPD, NOWRT
/* Dinh nghia cac chan cua IC74HC595 */
#define SHCP_PIN PIN_C2
#define DS_PIN PIN_C4
#define STCP_PIN PIN_C3 // Chan chot gia tri ra dau ra
unsigned char maled[8]={0x18,0x3C,0x66,0x66,0x7E,0x7E,0x66,0x66};
unsigned char maquet[8]={0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
void ShiftIn_hc595(int data)
{ int i;
output_low(SHCP_PIN);
for(i=0;i<=7;i++)
{ if((data & 0x80)==0)
output_low(DS_PIN);
else
output_high(DS_PIN);
data=data<<1;
output_high(SHCP_PIN);
output_low(SHCP_PIN);
}
}
void LatchOut_HC595()
{ output_low(STCP_PIN);
delay_us(5);
output_high(STCP_PIN);
output_low(STCP_PIN);
}
void delay(unsigned int t) //hàm delay
{ unsigned int x,y;
for(x=0;x<t;x++)
for(y=0;y<123;y++);
}
76
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
void main(void)
{
int i;
TRISB=0B11100000;
PORTB=0X00;
TRISD=0X00;
PORTD=0X00;
TRISC=0X00;
PORTC=0X00;
while(1)
{
for(i=0;i<8;i++)
{
PORTB = 0x18; //tat toan bo LED
ShiftIn_hc595(maled[i]); //xuat ma led dong i
LatchOut_HC595();
PORTB = maquet[i]; //bat sang dong i
delay(1); //delay de mat kip nhin
}
}
}
Để đẩy 8 bit dữ liệu ra IC595, có thể sử dụng hàm được xây dựng sẵn trong thư viện CCS
như hàm output_bit(), và hàm shift_left(). Hàm ShiftIn_hc595(int data) được viết lại như sau:
void ShiftIn_hc595(int data)
{
int i;
output_low(SHCP_PIN);
for(i=0;i<=7;i++)
{
77
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
output_bit(DS_PIN,shift_left(&data,1,0));
output_high(SHCP_PIN);
output_low(SHCP_PIN);
}
Yêu cầu: Dựa trên chương trình hiển thị chữ A, sinh viên viết chương trình hiển thị dòng
chữ chạy trên ma trận LED: K14A
Hình 2.30 Sơ đồ kết nối với cảm biến nhiệt độ DS18B20 và LCD
78
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.9.2 Chương trình
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8MHz)
#include <lcd.c>
#define DS18B20_PIN PIN_A4 //Chân Data của DS18B20 được nối với A4
// Định nghĩa chân kết nối với LCD
#define LCD_RS_PIN PIN_B5
#define LCD_RW_PIN PIN_B4
#define LCD_ENABLE_PIN PIN_B3
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
signed int16 raw_temp;
float temp;
int1 ds18b20_start()
{
output_low(DS18B20_PIN); // gửi xung reset tới DS18B20
output_drive(DS18B20_PIN); // đặt chân DS18B20_PIN là đầu ra
delay_us(500); // đợi 500 us
output_float(DS18B20_PIN); // đặt chân DS18B20_PIN là đầu vào
delay_us(100); // trễ đợi DS18B20 đáp ứng
if (!input(DS18B20_PIN))
{
delay_us(400); // đợi 400 us
return TRUE; // DS18B20 sẵn sàng giao tiếp với PIC
}
return FALSE;
}
void ds18b20_write_bit(int1 value)
{
output_low(DS18B20_PIN);
output_drive(DS18B20_PIN);
delay_us(2);
output_bit(DS18B20_PIN, value);
delay_us(80);
output_float(DS18B20_PIN);
delay_us(2);
}
79
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
void ds18b20_write_byte(int8 value)
{
int8 i;
for(i = 0; i < 8; i++)
ds18b20_write_bit(bit_test(value, i));
}
int1 ds18b20_read_bit(void)
{
int1 value;
output_low(DS18B20_PIN);
output_drive(DS18B20_PIN);
delay_us(2);
output_float(DS18B20_PIN);
delay_us(5);
value = input(DS18B20_PIN);
delay_us(100);
return value;
}
int8 ds18b20_read_byte(void)
{
int8 i, value = 0;
for(i = 0; i < 8; i++)
shift_right(&value, 1, ds18b20_read_bit());
return value;
}
int1 ds18b20_read(int16 *raw_temp_value)
{
ds18b20_start();
ds18b20_write_byte(0xCC); // gửi câu lệnh định địa chỉ các thiết bị trên bus
ds18b20_write_byte(0x44); // gửi lệnh để DS18B20 chuyển đổi nhiệt độ
ds18b20_start();
ds18b20_write_byte(0xCC); //
ds18b20_write_byte(0xBE); // gửi lệnh đọc dữ liệu
*raw_temp_value = ds18b20_read_byte(); //đọc byte thấp
*raw_temp_value |= (int16)(ds18b20_read_byte()) << 8; // đọc byte cao
return TRUE; // OK --> return 1
}
80
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
void main() {
lcd_init(); // Initialize LCD module
lcd_putc('\f'); // Clear LCD
lcd_gotoxy(3, 1); // Go to column 3 row 1
printf(lcd_putc, "Temperature:");
while(TRUE) {
if(ds18b20_read(&raw_temp))
{
temp = (float)raw_temp / 16;
lcd_gotoxy(5, 2);
printf(lcd_putc, "%f", temp);
lcd_putc(223); // symbol ( ° )
lcd_putc("C ");
}
else {
lcd_gotoxy(5, 2);
printf(lcd_putc, " Error! ");
}
delay_ms(100);
}
}
Giải thích các hàm chức năng giao tiếp với DS18B20:
hàm ds18b20_start(): được sử dụng để kiểm tra xem cảm biến DS18B20 đã được
kết nối và sẵn sàng giao tiếp hay chưa, giá trị trả về của hàm là TRUE(1) là đã sẵn
sàng, FALSE(0) là lỗi, chưa thực hiện được giao tiếp.
hàm ds18b20_write_bit(int1 value): viết (gửi) 1 bit xuống sensor DS18B20, giá trị
của bit có thể là 1 hoặc 0.
hàm ds18b20_write_byte(int8 value): viết (gửi) 1 byte (8 bits) tới DS18B20, hàm
này được xây dựng dựa trên hàm ds18b20_write_bit và bit LSB được viết đầu tiên.
hàm ds18b20_read_bit(void): đọc một bit từ DS18B20, hàm trả về giá trị đọc được
(1 or 0).
hàm ds18b20_read_byte(void): đọc 1 byte (8 bits) từ DS18B20, hàm này được xây
dựng dựa trên hàm ds18b20_read_bit(void), bit LSB được đọc đầu tiên.
hàm ds18b20_read(int16 *raw_temp_value): đọc dữ liệu nhiệt độ 16 bit (2 thanh ghi
8 bit), dữ liệu được lưu ở biến raw_temp_value.
81
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.10 MỘT SỐ CHƯƠNG TRÌNH SỬ DỤNG NGẮT:
2.10.1 Sử dụng ngắt ngoài:
2.10.1.1 Sơ đồ mạch
82
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.10.1.2 Chương trình
#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming
#use delay(crystal=4000000)
//khai bao ket noi led don
#define LED PIN_B1
#INT_EXT
void NgatINT0(void) // ham phuc vu ngat ngoai
{
output_toggle(LED); //ham dao gia tri logic của bien LED
}
void main()
{
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT_H2L);
enable_interrupts(GLOBAL);
output_bit(LED,0);
while(TRUE)
{
;
}
}
83
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.10.2 Ngắt RB:
2.10.2.1 Sơ đồ mạch
84
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.10.2.2 Lưu đồ:
START
INT_RB
(hàm main)
Xóa cờ báo ngắt(RBIF)
YES
Cho phép ngắt RB(RBIE) RB4=0?
Cho phép ngắt toàn cục(GIE) Đợi đến khi RB4=1
NO
Tắt các đèn LED1LED4 Đảo trạng thái LED1
YES
RB5=0?
Đợi ngắt Đợi đến khi RB5=1
NO
Đảo trạng thái LED2
YES
RB6=0?
Đợi đến khi RB6=1
NO
Đảo trạng thái LED3
YES
RB7=0?
Đợi đến khi RB7=1
NO
Đảo trạng thái LED4
Trở về từ ngắt
85
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
2.10.2.3 Chương trình
#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=4000000)
//khai bao ket noi cac led don
#define LED_1 PIN_C0
#define LED_2 PIN_C1
#define LED_3 PIN_C2
#define LED_4 PIN_C3
//khai bao ket noi cac nut nhan
#define NUT_NHAN_1 input(PIN_B4)
#define NUT_NHAN_2 input(PIN_B5)
#define NUT_NHAN_3 input(PIN_B6)
#define NUT_NHAN_4 input(PIN_B7)
#byte CoNgatRB = 6
int1 TrangThai[]={0,0,0,0};
#INT_RB
void NgatRB(void)
{
if(NUT_NHAN_1==0)
{
while(NUT_NHAN_1==0);
switch(TrangThai[0])
{
case 0:
{ output_bit(LED_1,1);
TrangThai[0]=1;
break;
}
case 1:
{ output_bit(LED_1,0);
TrangThai[0]=0;
break;
}
}
}
86
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
else if(NUT_NHAN_2==0)
{
while(NUT_NHAN_2==0);
switch(TrangThai[1])
{
case 0:
{
output_bit(LED_2,1);
TrangThai[1]=1;
break;
}
case 1:
{
output_bit(LED_2,0);
TrangThai[1]=0;
break;
}
}
}
else if(NUT_NHAN_3==0)
{
while(NUT_NHAN_3==0);
switch(TrangThai[2])
{
case 0:
{ output_bit(LED_3,1);
TrangThai[2]=1;
break;
}
case 1:
{
output_bit(LED_3,0);
TrangThai[2]=0;
break;
}
}
}
87
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
else if(NUT_NHAN_4==0)
{
while(NUT_NHAN_4==0);
switch(TrangThai[3])
{
case 0:
{ output_bit(LED_4,1);
TrangThai[3]=1;
break;
}
case 1:
{ output_bit(LED_4,0);
TrangThai[3]=0;
break;
}
}
}
//clear_interrupt(INT_RB);
Clear = CoNgatRB;
}
void main()
{
//khai bao bien cuc bo o day nay
clear_interrupt(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
output_bit(LED_1,0);
output_bit(LED_2,0);
output_bit(LED_3,0);
output_bit(LED_4,0);
while(TRUE)
{
;
}
}
88
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
KIT VĐK MỚI PIC 18F
Mô tả các thiết bị có trong kit thực hành PIC 16f877a
Bộ kit bao gồm:
- Vỏ và hộp đựng kit
- Kit thực tập PICKIT2-16f877a(HL-k18)
- Cáp nạp sử dụng cổng COM
- Cáp RS232
- Động cơ bước 5v
- Động cơ DC 5v
- Màn hình LCD 16x2
C
á
c
Figure 1. Kit VDK PIC 16f877a ứng
dụng
thường gặp khi thực hành với kit PIC 16f877a
89
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
- Sử dụng PIC 16f877a điều khiển hiển thị lên lCD 16x2
- Sử dụng PIC 16f877a điều khiển bật tắt Buzzy
90
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Sơ đồ nguyên lí các cấu trúc kết nối của PIC 16f877a với một số thiết bị trên kit thực hành:
Điều khiển led 7 đoạn bằng PIC 16f877a
91
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
I.1 Nguyên lý IC ULN2003A trên kit thực hành:
Sơ lược về ULN2003a là một vi mạch đệm, bản chất cấu tạo là các mảng darlington chịu
được dòng điện lớn và điện áp cao, trong đó có chứa 7 cặp transistor NPN ghép darlington gực
góp hở với các cực phát chung. Mỗi kênh của ULN2003a có một diode chặn có thể sử dụng
trong trường hợp tải có tính cảm ứng. ULN2003a có khả năng điều khiển 7 kênh riêng biệt , có
thể kết nối trực tiếp với vi điều khiển 5v. Bên cạnh đó, mỗi kênh có thể chịu được dòng điện lên
tới 500Ma.
92
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
- Với led 7 đoạn kathot chung, các đầu ra ULN2003a với vai trò cổng đảo vì vậy cần kích
mức 1 đối với các chân điều khiển.
Chương trình test led cơ bản xuất số ‘1 2 3 4’ lên 4 led 7 đoạn đầu tiên
bằng phương pháp quét led
#include <testled7seg.h>
#include<def_877a.h>
#fuses nowdt,hs,put,noprotect
#use delay(crystal=4000000)
Tiếp theo sẽ là chương trình nâng cao hơn với led 7 đoạn, nhấn SW0
xuất số đếm từ 1-9999 trên 4 led cuối
#include <7segment.h>
#include<def_877a.h>
#fuses nowdt,hs,put,noprotect
#use delay(crystal=4000000)
const unsigned char
maled[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0
x71,0x40};
int dem,chuc,donvi,tram,ngan;
int16 d;
void main(void)
{
set_tris_d(0);
set_tris_a(0);
set_tris_a(1);
tram=ngan= 0;
while(true)
{
ra2=0; ra3=0; ra5=0;
lapphim:
ra1=1;
94
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
rc1=0;
if(rb0==0)
{
lap1:
if(rb0==1) goto ct;
else goto lap1;
}
delay_ms(1);
ct:
if(++d>400)
{
d=0;
if(++dem>99)
{
tram++;
dem=0;
}
if(tram>9)
{
tram= 0;
ngan++;
}
if(ngan>9)
ngan=0;
}
output_d(maled[ngan]);
ra5=1;
delay_us(500);
//
ra5=0;
95
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
output_d(maled[tram]);
ra3=1;
//
ra3=0;
chuc=dem/10;
donvi=dem%10;
output_d(maled[chuc]);
ra2=1;
delay_us(500);
ra2=0;
output_d(maled[donvi]);
ra1=1;
delay_us(500);
ra1=0;
goto ct;
}
}
I.2 Sử dụng pic 16f877a điều khiển hiển thị led ma trận 8x8
Cấu trúc led ma trận 1088BS:
96
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Sơ đồ mạch nguyên lý pic 16f877a kết nối với led ma trận 8x8
97
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
TRISD=0;
TRISB=0;
TRISA=0;
TRISE=0;
trisc=0;
while(TRUE)
{
portd=0b01000000; //! RD6=1;
RE2=1;
RE1=1;
RA5=1;
RA3=1;
rc0=0; re0=0;ra2=0; ra1=0;
DELAY_mS(3);
portd=0b00100000;// RD5=1;
RC0=1;
98
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
RE2=1;
RE1=1;
re0=1;
RA5=1;
RA3=1;
RA2=1;
ra1=0;
DELAY_mS(3);
portd=0b00010000;//RD4=1;
RC0=1;
RE2=1;
RE1=1;
re0=1;
RA5=1;
RA3=1;
RA2=1;
ra1=0;
DELAY_mS(3);
portd=0b00001000; // RD3=1;
RE2=1;
RE1=1;
RE0=1;
RA5=1;
RA3=1;
rc0=0; ra2=0;ra1=0;
DELAY_mS(3);
portd=0b00000100; //RD2=1;
RE1=1;
RE0=1;
RA5=1;
99
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
rc0=0; re2=0;ra3=0; ra2=0;ra1=0;
DELAY_mS(3);
portd=0b00000010;// RD1=1;
RE0=1;
rc0=0; re2=0;ra3=0; ra2=0;ra1=0; re1=0; ra5=0;
DELAY_mS(3);
////
}
}
Tiếp theo là nháy chữ luân phiên, ví dụ ở đây sẽ là hiển thị hình trái tim sau 0.5s sẽ hiện
chữ T
#include <testledmatrix.h>
#include<def_877a.h>
#fuses nowdt,hs,put,noprotect
#use delay(crystal=4000000)
int32 i;
void main()
{
TRISD=0;
TRISB=0;
TRISA=0;
TRISE=0;
trisc=0;
while(TRUE)
{
100
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
for (i=0;i<80;i++)
{
portd=0b01000000; //! RD6=0;
RE2=1;
RE1=1;
RA5=1;
RA3=1;
rc0=0; re0=0;ra2=0; ra1=0;
DELAY_mS(3);
portd=0b00100000;// RD5=0;
RC0=1;
RE2=1;
RE1=1;
re0=1;
RA5=1;
RA3=1;
RA2=1;
ra1=0;
DELAY_mS(3);
portd=0b00010000;//RD4=0;
RC0=1;
RE2=1;
RE1=1;
re0=1;
RA5=1;
RA3=1;
RA2=1;
ra1=0;
DELAY_mS(3);
portd=0b00001000; // RD3=0;
101
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
RE2=1;
RE1=1;
RE0=1;
RA5=1;
RA3=1;
rc0=0; ra2=0;ra1=0;
DELAY_mS(3);
portd=0b00000100; //RD2=0;
RE1=1;
RE0=1;
RA5=1;
rc0=0; re2=0;ra3=0; ra2=0;ra1=0;
DELAY_mS(3);
portd=0b00000010;// RD1=0;
RE0=1;
rc0=0; re2=0;ra3=0; ra2=0;ra1=0; re1=0; ra5=0;
DELAY_mS(3);
}
for(i=0;i<100;i++)
{
portd=0b000111100;
RE0=1;
rc0=0; re2=0;ra3=0; ra2=0;ra1=0; re1=0; ra5=0;
delay_ms(3);
portd=0b00100000;
RE0=1; re1=1; ra5=1;
rc0=0; re2=0;ra3=0; ra2=0;ra1=0;
delay_ms(3);
}
102
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
}
}
103
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
K
ết
nối
chân
1,2,
3,4
của
độn
g cơ
bước lần lượt với chân RC0,RE2,RE1,RE0
Lập trình điều khiển động cơ bước chạy đơn giản
Nhấn nút SW0 động cơ chạy, nhấn lại SW0 động cơ dừng
#include <testdieukhiendongcobuoc.h>
#include <def_877a.h>
#use delay(crystal=4000000)
#fuses nowdt,hs,put,noprotect
//re0,re1,re2,rc0
void main()
{
set_tris_e(0x00);
trisa=0x00;
trisb=0x0f;
while(TRUE)
{
lapphim:
ra1=1;
if(rb0==0)
{
lap1:
104
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
if(rb0==1) goto ct;
else goto lap1;
}
delay_ms(1);
goto lapphim;
ct:
output_low(PIN_e0); output_high(PIN_e1);
output_low(PIN_e2); output_high(PIN_c0);
delay_us(3500);
output_high(PIN_e0); output_low(PIN_e1);
output_low(PIN_e2); output_high(PIN_c0);
delay_us(3500);
output_high(PIN_e0); output_low(PIN_e1);
output_high(PIN_e2); output_low(PIN_c0);
delay_us(3500);
output_low(PIN_e0); output_high(PIN_e1);
output_high(PIN_e2); output_low(PIN_c0);
delay_us(3500);
lap:
ra1=1;
if(rb0==0)
{
lap2:
if(rb0==1) goto lapphim;
else goto lap2;
delay_us(500);
}
goto ct;
105
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
}
}
Để điều khiển mỗi nút bàn phím 4x4 bằng 2 chân khác nhau phải bật off Switch S3
Một chương trình đơn giản cho pic 16f877a sử dụng nguyên lí quét phím ma trận.
Nhấn nút SW0 còi kêu luân phiên 0.25 giây
#include <testbanphim.h>
#include <def_877a.h>
#use delay(crystal=4000000)
#fuses nowdt,hs,put,noprotect
int32 i;
106
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
void main()
{
trisa=0x00;
trisc=0x00;
trisb=0x0f;
while(TRUE)
{
ra2=0; ra3=0; ra5=0;
lapphim:
ra1=1;
rc1=0;
if(rb0==0)
{
lap1:
if(rb0==1) goto ct;
else goto lap1;
}
delay_ms(1);
goto lapphim;
ct:
rc1=1;
for(i=1; i<5000;i++)
{
lap2:
if(rb0==0)
{
delay_ms(1);
if(rb0==1) goto lapphim;
else goto lap2;
107
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
}
}
rc1=0;
for(i=1; i<5000;i++)
{
lap3:
if(rb0==0)
{
delay_ms(1);
if(rb0==1) goto lapphim;
else goto lap3;
}
}
goto ct;
}
}
Sử dụng PIC 16f877a điều khiển hiển thị lên lCD 16x2
108
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
I.5 Sơ đồ nguyên lí kết nối LCD 16X2 với piC 16f877a
P
hần
này
hãy
để ý
jump
cắm
màu
đỏ
trên
KIT
rút ra
và
cắm ngược lại trên các chân EN,RS,RW để sử dụng được LCD
Viết chương trình cơ bản hiển thị trên LCD, ví dụ chương trình dùng để hiển thị chữ và
thời gian on display LCD.
#include <16f877a.h>
#include <def_877a.h>
#use delay(crystal=4000000)
#fuses nowdt,put,hs,noprotect
109
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
// e...........ra5
//rw...........ra3
//rs............ra2
//d4-d7...........rd4-rd7
#define lcd_enable_pin pin_a5
#define lcd_rw_pin pin_a3
#define lcd_rs_pin pin_a2
113
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
Chương trình điều khiển BUZZY bằng pic 16f877a
Sử dụng bài quét bàn phím, nhấn nút SW0 còi báo 5s rồi tự tắt, hoặc nhấn lại SW0 lại lần
nữa còi sẽ tắt
#include <testbanphim.h>
#include <def_877a.h>
#use delay(crystal=4000000)
#fuses nowdt,hs,put,noprotect
int32 i;
int32 j;
void main()
{
trisa=0x00;
trisc=0x00;
trisb=0x0f;
while(TRUE)
{
}
}
rc1=0;
goto lapphim;
}
Phần mở rộng
Ngoài những bài học trên còn một số thứ có thể lập trình với PIC trên kit 16f877a như
đồng hồ thời gian thực, truy xuất dữ liệu thẻ SD, điều khiển thiết bị bằng hồng ngoại dùng PIC,
Đọc giá trị nhiệt độ bằng cảm biến DS18B20.
115
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
116
Thực hành PIC16F877A BỘ MÔN TỰ ĐỘNG HÓA
- Bài tập phần mở rộng:…
117