You are on page 1of 37

YÊU CẦU:

• Dùng PIC 16F877A điều khiển 1


động cơ DC quay thuận, quay
nghịch, dùng nút nhấn điều khiển,
có thể thay đổi tốc độ dùng
phương pháp điều khiển độ rộng
xung, dùng ngôn ngữ C.
PP ĐIỀU KHIỂN PWM:
• Để điều khiển tốc độ động cơ DC người ta
có thể dùng nhiều phương pháp khác
nhau trong đó có một phương pháp hết
sức quan trọng và thông dụng là phương
pháp điều chế độ rộng xung kích (PWM),
có nghĩa là thay đổi độ rộng xung kích để
điều khiển linh kiện đóng ngắt (SCR hay
Transistor), từ đó điều khiển tốc độ động
cơ. Bộ PWM có thể tạo ra từ các linh kiện
điện tử.
• Với yêu cầu dùng PIC16F877A điều khiển
động cơ quay thuận-nghịch và thay đổi tốc
độ, ta sử dụng bộ điều chế độ rộng xung
(PWM) tích hợp sẵn bên trong PIC với 2 ngõ
ra xung tại hai chân CCP1(17) và CCP2 (16)
. Tại các chân này khi hoạt động sẽ xuất
chuỗi xung vuông , độ rộng điều chỉnh được
dễ dàng. Xung ra này dùng để tạo tín hiệu
đóng ngắt Trasistor trong mạch động lực,
với độ rộng xác định sẽ tạo ra một điện áp
trung bình xác định. Thay đổi độ rộng xung
sẽ thay đổi điện áp trung bình và do đó thay
đổi được tốc độ động cơ.
• Để có thể sử dụng được bộ PWM trước
hết nó phải được khởi tạo chế độ PWM
bằng lệnh:
setup_ccpx (CCP_PWM) với x = 1,2
Bộ PWM hoạt động phải được sự hỗ trợ
của Timer 2 , đây là Timer 8-bit có bộ chia
trước. Ngõ vào xung Clock (=fosc/4) có
tuỳ chọn hệ số chia trước là: “1:1”, “1:4”,
“1:16” được lựa chọn bằng các bit điều
khiển T2CKPS1:T2CKPS2.
• Lệnh để khởi tạo Timer2 và cũng là tạo chu kỳ
xung cho bộ PWM là:
setup_timer_2(mode,period,postscale)
với:
- Mode có thể chọn một trong các hình thức sau:
T2_DISABLED, T2_DIV_BY_1 T2_DIV_BY_4,
T2_DIV_BY_16
- Period là một số nguyên (0 255) để xác định
khi nào thì xung clock reset.
- Postscale là số (116) để xác định có bao
nhiêu lần reset trước một ngắt: 1 có nghĩa là 1
lần, 2 nghĩa là 2 lần…
Chức năng của lệnh này là tạo ra chu kỳ xung và
được tính như sau:
T = (1/fosc)*4*t2_div*(period+1)
• Xét ví dụ:
Lệnh: setup_timer_2(T2_div_by_4,0xc0,2)
với thạch anh 10MHz , Timer2 sẽ tăng mỗi 1.6us
( 4*4*1/10e6), sẽ bị tràn mỗi 307.2us (1.6*192),
và sẽ bị ngắt mỗi 714.4us ( 307.2*2).
Ở đây chu kỳ xung là T = (1/10e6)*4*4*(192+1)
= 153.6us.
Cụ thể trong bài, muốn tạo chu kỳ xung 1ms ta
khởi tạo Timer2 như sau:
setup_timer_2(T2_div_by_16,154,1)
Khi ấy T= (1/10e6)*4*16*(154+1) = 0.992ms =
1ms.
• Tiếp theo, tạo xung bằng lệnh:
set_pwmx_duty(value) với x = 1, 2
- value là biến hoặc hằng ,giá trị 8 hoặc 16 bit.
Lệnh này dùng để set duty trong chế độ PWM
.Nó ghi 10 bit giá trị vào thanh ghi CCPx. Nếu
giá trị chỉ là 8 bit thì nó tự dịch lên với 2 bit zero
ở vị trí LSB để đủ 10 bit nạp vào CCPx . Giá trị
này để xác định lượng thời gian tín hiệu PWM ở
mức cao trong suốt mỗi chu kỳ xung. Thời gian
duty được xác định là:
value*(1/clock)*t2_div
với t2_div là số chia đặt trước của Timer2.
• Xét ví dụ trong bài:
duty = 620;
set_pwm1_duty(duty);
với thạch anh 10MHz,giả sử t2_div_16, ta có
thời gian duty là: 620*16*(1/10e6) = 0.992ms.
Giải thích thêm: Thời gian duty là thời gian xung
(mức cao) của chu kỳ xung, minh hoạ:
Như vậy, trong bài ta có chu kỳ xung là
0.992ms, để động cơ quay với tốc độ cực đại thì
thời gian duty = chu kỳ xung bởi vì khi ấy gần
như ngõ ra bộ PWM chỉ là mức 1.
Minh hoạ:

Thời gian duty

Chu kỳ xung
PHẦN CỨNG:
VI ĐIỀU KHIỂN PIC16F877A:
• Các nút nhấn bao gồm :
- OFF : kết nối với chân : 33 RBO/INT
- FOR : kết nối với chân : 34 RB1
- REV : kết nối với chân : 35 RB2
- T1 : kết nối với chân : 36 RB3/PG
- T2 : kết nối với chân : 37 RB4
- T3 : kết nối với chân : 38 RB5
- T4 : kết nối với chân : 39 RB6/PGC
- T5 : kết nối với chân : 40 RB7/PGD
Nguồn 5V, thạch anh 20MHz.
MẠCH ĐIỀU KHIỂN ĐỘNG CƠ DC:
• Mạch gồm các Transistor, điện trở và Diode.
Nguyên lý như sau :
- Khi A, B cùng ở mức 1 : Q1, Q2 dẫn làm cho
Q5, Q6 dẫn, Q3, Q4 không dẫn, điện áp ở 2 cực
động cơ bằng nhau nên động cơ đứng yên.
- khi A, B cùng ở mức thấp : Q1, Q2 không dẫn
làm cho Q3, Q4 dẫn, Q5, Q6 không dẫn, động
cơ đứng yên.
- Khi A ở mức cao, B ở mức thấp : Q4, Q5 dẫn,
động cơ quay.
- Khi B ở mức cao, A ở mức thấp : Q3, Q6
dẫn, động cơ quay theo chiểu ngược lại.
LƯU ĐỒ:

Begin

Khởi tạo cấu hình 2 bộ


PWM

Đ Xử lý biến
Nhấn nút
chạy thuận
chạy
thuận
S

Đ Xử lý biến
Nhấn nút
chạy nghịch
chạy
nghịch
S
Nhấn nút Đ Xử lý biến tốc
tốc độ 1 độ

Nhấn nút Đ
tốc độ 2

Nhấn nút Đ
tốc độ 3

Nhấn nút Đ
tốc độ 4

S
Nhấn nút Đ
tốc độ 5

Nhấn nút Đ
OFF

S
Điều khiển động Ngừng động
cơ quay cơ

End
Chương trình:

#include <16F877A.h>
#include <def_16f877a.h>
#fuses
NOWDT,PUT,HS,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use fast_io(b)
#define tocdo0 0 //toc do bang 0
#define td_macdinh 80 //toc do mac dinh
#define tocdo1 124 //1/5 toc do cuc dai
#define tocdo2 248 //2/5 toc do cuc dai
#define tocdo3 372 //3/5 toc do cuc dai
#define tocdo4 496 //4/5 toc do cuc dai
#define tocdo5 620 //toc do cuc dai
int16 duty1=0;
int16 duty2=0;
int8 bientocdo=0;
int1 bienthuan=0;
int1 biennghich=0;
void main() //bo PMW1 dk
dco quay thuan
{ //bo PMW2 dk dco
quay nghich
set_tris_b(0x0ff);//khoi tao port B la
port nhap
setup_ccp1(CCP_PWM); //khoi tao
bo PWM1
setup_ccp2(CCP_PWM); //khoi tao
bo PWM2
setup_timer_2(T2_div_by_16,154,1);
//tao chu ky xung 1ms
//(1/clock)*4*t2div*(period+1)
//(1/10e6)*4*16*(154+1)=1e-3=1ms

set_pwm1_duty(duty1);
set_pwm2_duty(duty2);
//gia tri duty cua PWM duoc tinh
theo cong thuc duty1*t2div/clock
//khoi tao duty=0 -> tat
dong co
while(true)
{

if (!bit_test(portb,1)) //neu nhan phim


FO : chay thuan
{
duty1=tocdo0;
duty2=tocdo0;
set_pwm1_duty(duty1); //cho duty cua 2
bo PMW=0 de
set_pwm2_duty(duty2); //tat dong co
delay_ms(1000); //delay 1s de giam
quan tinh dong co
bienthuan=1;
biennghich=0;
goto next;
}
if (!bit_test(portb,2)) //neu nhan phim
RE :
chay nghich
{
duty1=tocdo0;
duty2=tocdo0;
set_pwm1_duty(duty1); //cho duty cua 2
bo PMW=0 de
set_pwm2_duty(duty2); //tat dong co
delay_ms(1000); //delay 1s de giam
quan tinh dco
bienthuan=0;
biennghich=1;
goto next;
}
if (!bit_test(portb,3)) //nhan phim toc do 1
{
bientocdo=1;
goto next;
}
if (!bit_test(portb,4)) //nhan phim toc do 2
{
bientocdo=2;
goto next;
}
if (!bit_test(portb,5)) //nhan phim toc do 3
{
bientocdo=3;
goto next;
}
if (!bit_test(portb,6)) //nhan phim toc do 4
{
bientocdo=4;
goto next;
}
if (!bit_test(portb,7)) //nhan phim toc do 5

bientocdo=5;

next:
if (!bit_test(portb,0)) //neu nhan
phim OFF
{
duty1=tocdo0;
duty2=tocdo0;
set_pwm1_duty(duty1); //cho duty cua 2
bo PMW=0 de
set_pwm2_duty(duty2); //tat dong co
bienthuan=0;
biennghich=0;
bientocdo=0; //xoa bien toc do
}
if (bienthuan)
{
duty2 = tocdo0;
switch (bientocdo)
{
case 1: duty1= tocdo1;
break;
case 2: duty1= tocdo2;
break;
case 3: duty1= tocdo3;
break;
case 4: duty1= tocdo4;
break;
case 5: duty1= tocdo5;
break;
default : duty1 = td_macdinh;
break;
}
set_pwm1_duty(duty1); //cho dco chay
thuan
set_pwm2_duty(duty2);
}

if (biennghich)
{
duty1 = tocdo0;
switch (bientocdo)
{
case 1: duty2= tocdo1;
break;
case 2: duty2= tocdo2;
break;
case 3: duty2= tocdo3;
break;
case 4: duty2= tocdo4;
break;
case 5: duty2= tocdo5;
break;
default : duty2 = td_macdinh;
break;
}
set_pwm1_duty(duty1); //cho dco
chay nghich
set_pwm2_duty(duty2);
}
}
}
Mô phỏng:

You might also like