|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机PWM直流电机调速程序 0到20级的调速; b" p! l' p: X# a G
# C0 r. j6 \2 N4 a E. W! Y) Q
( L7 J- k. X3 b1 @; ^6 b# W2 J5 m- o" O k! q+ z
/*******************************************************************/) r1 b& Z; S: ]' z R
/* 程序名:PWM直流电机调速 */3 |- W; m. Q: y) J1 M% _$ k7 e
/* 晶振:11.00592 MHz CPU型号:AT89C51 */
7 p* l. G% Q0 Z' W/* 直流电机的PWM波控制,可以直接的调速从0到20级的调速 */ `6 L8 K- `6 Q/ |
+ n9 n' Q; Q7 T* z7 |9 a
/*****************************************************************/
! f. L0 `. }3 W
7 c9 q- n5 ^% `/ E7 c6 ^#include<reg51.h>3 C8 r% s) i% e k; y. q
#define TH0_TL0 (65536-1000)//设定中断的间隔时长3 V7 P" ]4 V* U
unsigned char count0 = 50;//低电平的占空比
5 u0 {8 c8 O$ r5 Y6 R+ b# f, Uunsigned char count1 = 0;//高电平的占空比
0 ~' t/ V$ c1 ~! s3 d+ L
. W' H, F& i0 m- q4 s. A& e6 x. ubit Flag = 1;//电机正反转标志位,1正转,0反转* s2 r" W' Q( b( ^( L; I
* { z9 O, e, ^$ Y% C
sbit Key_add=P2 ^ 0; //电机减速
4 ^2 _* u ^# R) m# Nsbit Key_dec=P2 ^ 1; //电机加速
6 L6 S7 v% g. g/ B6 B" m8 u' _sbit Key_turn=P2 ^ 2; //电机换向" o6 P% W1 S5 i7 J' \; i) Q
7 _7 H6 P9 B" b# H- asbit PWM1=P2^6;//PWM 通道 1,反转脉冲1 R/ ?$ t4 F# T3 j9 t
sbit PWM2=P2^7;//PWM 通道 2,正转脉冲
# l$ v# w4 l5 p" |8 Q6 a6 u6 N0 E
) c: C0 U7 l7 M- y7 V2 u/ [7 Eunsigned char Time_delay;% e+ `7 D# p; D1 |: m" o: I4 }/ n
6 n8 m v. ?) U: r# ]
/************函数声明**************/
$ Y' @! @& z( o* K! m" G. Gvoid Delay(unsigned char x);
2 V) X* \$ i2 Y' C$ k, q p, p" Lvoid Motor_speed_high(void);. s( M+ I3 R6 ?
void Motor_speed_low(void);
/ F6 ^( g2 \7 L1 c o+ `6 }void Motor_turn(void);4 T$ r! b* B4 R. @
void Timer0_init(void);
) Z7 w# _$ B) ~7 K0 S
: ]; N0 [% ?/ D9 x( ~/****************延时处理**********************/9 B" c' w7 Y+ U4 d
void Delay(unsigned char x), ~& T- w, ^! f, D! o* {! h5 b; k
{
; G2 Z7 R/ G/ z% h9 r4 J5 ?0 i# p' m Time_delay = x;
5 z0 b; ?- f0 N! F5 g3 O while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔
. W) ~3 ^! F, _# b; ~ a! B7 Z* z}
G/ Y: D q. D9 U; ~, q& A! `
# m- h; `- `( w3 w u$ _5 z/*******按键处理加pwm占空比,电机加速**********/
% e6 G* N/ E5 x: h$ Y- k: Gvoid Motor_speed_high(void)
- j7 h0 T6 u1 Y* A{& N! m& I: I3 g1 a% F" {; k
if(Key_add==0)
6 F! n# o$ c& h# J" Q# n {; b7 T" A- s4 M1 S: \4 A
Delay(10);! m. I& o& E8 j0 t/ a% d
if(Key_add==0)% J9 {+ f* M6 a
{; B! S& i8 k9 S$ o
count0 += 5;
Z, Z! F( ~8 T) a N
2 O3 J; v# V3 F4 W if(count0 >= 100)* F) y3 e- E) D! z7 r/ Z& B1 W
{/ h4 u& M- h# p C! s
count0 = 100;+ f; z& z/ {3 y" L
}
( x3 j+ B' M8 I. l8 g+ z }
1 p+ h1 J# r9 m. e; l3 y6 U% S' \* t, x while(!Key_add);//等待键松开. R% @6 H4 k% `. x& M. @
}+ ]3 R! ^; S2 p; W, | d
}* z: S u6 J2 X/ ^% p8 D
% d/ f2 U4 y! j# M) ~4 e
/******按键处理减pwm占空比,电机减速*****/# B$ S" l. B$ U' w1 B% y J& G
void Motor_speed_low(void)& a9 f3 r. _: Z: `9 I- K- v
{) f4 l# C1 ~% X( h
if(Key_dec==0)
$ }0 r" o. `: q* R8 g# x2 u {
0 F6 J* D( o( [6 @ Delay(10);
6 I: q7 y- R' j. V8 r+ H* P if(Key_dec==0)
: y# L% H+ D/ n! a5 S7 f {
4 `- L- p- }. S; E, K count0 -= 5;
( r& u" D4 S I, {
( T* A2 ?: d9 y if(count0 <= 0): g) [9 M3 X% m: c
{2 N @& F! O+ F/ u6 ]1 r: O
count0 = 0;
* F: f( }" [. N( A+ Z ] }
( M; L) j# m1 m5 }; \3 X, m }: V! z, U1 n! R3 ?( o' v/ {
while(!Key_dec );+ x7 J4 l: b/ `- w; R- i
}
/ p' q! V- \# b0 F& z7 m8 t8 G" d}
0 f; Z) j6 V0 r! N: }# m% i" b& D
, f+ ^( N. K. ~! I$ O/************电机正反向控制**************/
1 t* A4 U7 I9 f/ }9 h! `void Motor_turn(void)4 A9 W6 Z# D8 H* \$ ~
{
2 M/ X V2 L- F7 M {$ a n if(Key_turn == 0)
* g' ^/ J3 g: [! K \- F$ S {
3 }7 _% S0 N+ X Delay(10);
. U( ^$ g) V$ _ if(Key_turn == 0)& T& C3 L2 w4 R0 ~* T# i3 f
{( T5 E5 E9 R5 p" d, S2 g5 l/ l! K
Flag = ~Flag;# Z& c6 O/ U4 d- t
}3 ]. q! _) e1 F& c0 W
while(!Key_turn);" M+ h1 k1 p% V
}# z W# N9 D# ?; [2 w6 B9 L, P
}, s" |! W) D& j5 S) Q7 F
& {5 K! A! R2 o7 Q ^
/***********定时器0初始化***********/( ~$ }2 ]& H( Q9 O' `" _* K$ Y
void Timer0_init(void)
0 V. b" E: O" b( ^2 B$ |{" B7 k& t$ O( i. ^3 E$ g9 l
TMOD=0x01; //定时器0工作于方式1
# i& k" Y: G4 v% s4 m: I* YTH0=TH0_TL0/256;1 }0 [$ N. U- ]' z9 ?& V' ?* u
TL0=TH0_TL0%256;
! t& K% x: _! B: BTR0=1;+ f0 S" k2 z! w6 y4 k
ET0=1;8 z$ n0 n1 X% s2 \* f
EA=1;
4 s, |, [9 n" ]: J, j Y) b7 s) U}
9 N5 @7 a7 C1 a. P( i' D$ B/ s8 T Y9 A& d2 g& v
/*********主函数********************/
: P1 w% I9 y$ s; n/ Zvoid main(void)
% A' C- k! U, l; v{
8 J9 S& b! a: f) M Timer0_init();
! f Z1 |* w3 l: ]! o* d0 N+ k- s- \0 y
0 b2 O7 c- ?. f; m while(1)
/ g. b: |* q8 m. o! I {
0 B' ~. u4 Y/ K p- U. n" |0 T Motor_turn(); L7 u% n% U5 Q- a& u
Motor_speed_high(); g$ g# n0 N$ v8 x
Motor_speed_low();) A5 d. f/ ^7 y- y S
}: W* k/ Z9 A0 K4 N
}
' @& d) O. C; d3 O
7 O8 E7 R4 b3 h' D/**************定时0中断处理******************/
! @9 T2 k0 g1 O9 n% M5 \9 M9 w( {+ Dvoid Timer0_int(void) interrupt 1 using 1
7 I' O8 J; T7 \+ S{
) O" _4 H) W: m9 e; q* `- _% o) fTR0 = 0;//设置定时器初值期间,关闭定时器
" K+ S7 o6 _/ N, y5 N+ J) a3 }9 O( ETL0 = TH0_TL0 % 256;
* j4 o1 h! n8 H* W6 GTH0 = TH0_TL0 / 256 ;//定时器装初值
1 S$ A2 Y i3 k- V4 k1 TTR0 = 1;' Z/ g9 c7 f6 K
6 D+ p* U) V; xif(Time_delay != 0)//延时函数用
6 y! V2 N- F! h+ |0 \{
1 W7 Q; O7 p# {$ G b) [4 X Time_delay--;
- O3 k( |$ O4 g$ p4 B& N8 w$ p}
2 S2 a9 N& N/ h7 i5 `0 K! b' Q$ P% M) v
if(Flag == 1)//电机正转3 X! J8 W3 g8 R6 K8 l1 |
{
. x$ U5 N1 Q+ t5 r PWM1 = 0; - l% m3 V* _" |) L
0 t5 j* I* ^* c" a3 }7 {) ` if(++count1 < count0)# N7 ]: |5 _: L8 C- w% I# e) X
{
6 B# R0 Q8 A- c0 Q& ` PWM2 = 1;1 v; u' ^* L" B
}8 T; C: Y. \+ y, F
else
6 ], X# \: S% g; b PWM2 = 0;+ r! s: D: w& Q: K0 T
; ~3 U; r6 O; M5 f$ _+ s. s9 j if(count1 >= 100)6 h. C' m0 e( Y; A! y; f" F
{* H; C" H: ?( z \+ J/ a4 q
count1=0;
; [) {8 ?# V& ]1 e* Q }
: r' B% k; _8 _ O! U6 e}4 U) g6 A, v9 T* ^- W! w
else //电机反转6 T& y# k) y, T* Y
{
+ W- d+ C! l8 E( `) u* m7 V- D PWM2 = 0; * Z2 p& @7 D/ i0 [3 R; L
0 i b6 ~8 V9 ^" y, X! ` if(++count1 < count0)& s, A( y5 ]+ e6 m8 A( I4 D
{4 L* h) `/ [; d1 k0 q
PWM1 = 1;
# A) z H) |/ q) s/ y2 o0 f; v% v }
. x: F1 C+ `1 N8 N else
" c: _1 y# B; c& I PWM1 = 0;' M. ], `/ y4 u1 T! K
1 ?! J# U( N/ k0 ]1 Y3 k if(count1 >= 100)
2 p* ], V( a9 P C+ e9 s {% M+ b2 r) i6 |* e' T8 t/ q
count1=0;
) W; H2 p+ d9 T7 I: J }
+ m, x3 G& Q+ g# I }
+ q- C M4 j% ^; c3 R7 Z}
+ h, C( [ A M! o& G+ M$ z/************************************************5 Q* ~0 V+ Q7 [# o/ x* ^4 `% Q! R
2 o+ D4 J, `1 j; kvoid Delay(unsigned char x)
( n% x$ s& F6 \3 G& r5 h{
% b5 H# r: @/ n; T4 ]7 V9 hTime_delay = x;
" _' w# }$ w8 ], r# X0 d( Q, ^& f# R( u0 C3 O% Y: n+ u* U
while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔3 }% K6 Q* i2 i/ K
}5 @' }' S; G4 g& c# U0 F T
4 J* G" m$ J+ R* ?. ^* eDelay(10);
8 Z& U+ ?. Y' @+ G& F0 P- L
. J* o' ]2 _/ K k/ V) Gif(Time_delay != 0)//延时函数用; ~3 d: J' n- }8 E
{) h) k# [8 k0 X R
Time_delay--; : d+ h$ H) E1 I
}9 |' Z* {6 s! ]) i/ u
+ f; `" v: Q: M" F0 n其实这三个部分是相关联的。/ x0 a: P1 c# m" ^# r
Delay(10)这是延时防抖的这是毫无疑问的,但这个消抖在消抖的同时将一开始只是声明了下的Time-
d; N Q3 _5 M) P+ t4 B! L8 U' \% l K0 Q K+ B
delay赋值了,赋值还不算他还牵扯到定时器里去了。你看在赋值后Time-delay变成了10,看第二个部分
- K, b, h" T, q/ s
# O& Q4 B, f; D# d! v, ^的while(Time-delay!=10);这个语句正如注释所说的等待中断,当等来了中断后你可以看第三个部
7 ?+ I5 t" h% i2 ^) U
, {4 r! j9 l3 P9 p) `2 Q分了,看见了吧终端中有将Time-delay减一,每中断一次就减一次直到等于0之后。也就是说延时的时长! X( t, G+ B1 V+ E, q
& I: N' I5 q5 K: p1 Q0 t
是十个中断的时长。注释中:可减少PWM输出时间间隔 也就可想而知了。" X" v/ }( X% U, `2 A
*****************************************************/
9 [6 C4 x* q' l1 y$ u+ D% [+ s7 y- i
- K% h6 n2 `0 U' E7 u8 h+ J
|
|