|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机PWM直流电机调速程序 0到20级的调速
6 M% O: }/ O3 W$ @3 k* K
9 H2 z' n9 V) n* o; u
; a' z! }, P1 i* O6 |* U- P" n9 g! v# H# P) n0 M$ w/ t
/*******************************************************************/
+ I* l8 I& X( B9 K/* 程序名:PWM直流电机调速 */! ?$ W5 J# M; f; B: X& t
/* 晶振:11.00592 MHz CPU型号:AT89C51 */' n- N" p$ ?- X& P5 t
/* 直流电机的PWM波控制,可以直接的调速从0到20级的调速 */ : J$ s: `+ ^7 y$ e! t. O4 V$ G
0 v; `+ x0 U: N1 t0 @1 K9 {
/*****************************************************************/ 1 o7 o+ Y/ `% F+ z" G$ d- [5 o
5 X" w! f2 q7 c7 X#include<reg51.h>
) e/ p9 j+ b; ?% b7 q#define TH0_TL0 (65536-1000)//设定中断的间隔时长
, e( h! E- a ]$ nunsigned char count0 = 50;//低电平的占空比3 r; C/ O' Z8 r$ K- Y7 }' H5 r
unsigned char count1 = 0;//高电平的占空比
; g+ i, ~4 k; h" [/ d* a: [$ R, Z
bit Flag = 1;//电机正反转标志位,1正转,0反转0 I# [: P' m; H' D
9 T9 X5 F! [. hsbit Key_add=P2 ^ 0; //电机减速1 ]8 O: k+ X ~0 e4 W
sbit Key_dec=P2 ^ 1; //电机加速
* {+ }* u. Z& Ksbit Key_turn=P2 ^ 2; //电机换向
2 r; n% C. i' x, E( \
, T) |# t1 u3 I8 N: Csbit PWM1=P2^6;//PWM 通道 1,反转脉冲) u" h1 @: ~! i3 o5 Q9 t, J
sbit PWM2=P2^7;//PWM 通道 2,正转脉冲* `: @4 u* w3 Q/ g9 X# k$ N; H0 s6 H
- p0 {3 Q3 @2 \7 p; l1 p( [
unsigned char Time_delay;
( j" s5 D* X7 K0 C- J& G: y5 i4 b8 G! r v
/************函数声明**************/
8 g% l' n/ X5 d- Ivoid Delay(unsigned char x);
5 ~+ ]+ O( g6 p% _' Pvoid Motor_speed_high(void);: [4 d& j: E9 d3 s
void Motor_speed_low(void);
, E4 Q; E8 I2 q# H( W4 t1 bvoid Motor_turn(void);! I! p8 D! E, M$ h9 Y6 U- A- ]
void Timer0_init(void);; d( t- }0 H- z q- d2 {6 z6 I9 |
: O# c g) @8 b+ b' o* T y
/****************延时处理**********************/
: D0 ]5 q8 T+ [- K' B6 ^- ?4 xvoid Delay(unsigned char x)" d& ^. W% G) H9 {
{) }) Y1 p/ y" u2 E( i
Time_delay = x;
9 e( F5 G7 H _6 O' O$ F# a/ A5 d while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔9 w) h V* L6 n9 t/ |' X
}
$ v8 Z! N3 U2 M( Q" I k
' v- T9 R L+ n: V, s/*******按键处理加pwm占空比,电机加速**********/8 U5 b/ p [7 G# ~4 i5 i$ X
void Motor_speed_high(void)
$ ~4 \+ m9 Y4 ~! I- l6 j{
) z+ e8 F# C: T0 e" u# d9 I7 n if(Key_add==0)/ ^* R8 s2 s& ]) i5 `( F- C9 N
{9 r+ m O5 R* o7 T
Delay(10);
6 G# E4 U; \9 v+ l if(Key_add==0)
* b4 U" ?# b4 D& i {
: z; W# B5 N6 m2 r, B8 e' [ count0 += 5;
; ]! h& [" J- L+ @, |: j' A% P r% y I/ k. Z
if(count0 >= 100)+ }* y& _4 y% E: {% [
{$ l7 a4 c8 A. ?2 G
count0 = 100;! i5 Z" ?/ s0 s6 E! e5 D
} 9 p& U! Z, i) G! K. I
}
- n' o1 k- y6 H# O while(!Key_add);//等待键松开
" g# b4 C) P, p& F5 Z }
8 F9 D! D+ J$ i6 L3 Q# B}" ~' W1 k7 u. M
1 x0 p+ M) R6 I! }% n/ @
/******按键处理减pwm占空比,电机减速*****/
1 H: O" ^8 o) E, q' n2 Z! g8 ]void Motor_speed_low(void)
- ?. A$ a5 ]8 V4 j. R{+ E9 ]3 g0 y9 n# H, d3 J( \
if(Key_dec==0)
9 g# u; W9 u; p4 w# ? {# U% S9 L$ Q- Q; a& Y7 Y& a; S
Delay(10);
3 Z9 I7 G6 G: x8 n if(Key_dec==0)" N9 B, u+ q8 A
{
7 P6 m5 N9 h @6 e7 P7 O, ?4 Z2 c count0 -= 5;, [4 c1 ^- P# h( s7 |8 Y; U
+ d0 `$ ^* B9 o( X4 M$ ? if(count0 <= 0): k! `' j% p- P5 J+ u
{
# h! ~& v# x s& P9 y2 T count0 = 0;! P& H E! R( A: t) T
}
0 i+ m9 k; p: k/ q7 l( p8 Z- o }
. s9 E( P! m ], K( \+ d* ?. J5 ~7 D) N while(!Key_dec );
8 L, F {$ x3 L9 \3 v } ' {2 @( ?0 ?# Y
}
, m- E& `! ^' a4 H( I! a1 r7 Y4 e/ i! e2 s
/************电机正反向控制**************/- I6 f8 O: K% F# y. Z
void Motor_turn(void)9 y1 b9 f$ ` N, X ?: t2 P
{6 ^9 j7 |. @; w& C P) X
if(Key_turn == 0)
3 n j% N0 p& u' ~, F- d/ p0 T; M {
U$ ~) t9 ?+ H% ~ Delay(10);
! p( I+ O5 J' e% R4 x; M* T, Q if(Key_turn == 0)0 r) w5 x9 t6 C v
{3 q3 j7 ^+ b+ A
Flag = ~Flag;9 W. }: b7 L1 O5 N/ F( y C0 y
}: B# N$ D: ^+ Y- B
while(!Key_turn);
% M$ ` R* x, H% { }
' }7 ]8 P- i- C+ W/ K}" f1 r0 r5 i# y0 A* h& j; x
* H7 `' e M8 c8 k- l# G/***********定时器0初始化***********/! T9 E* e2 |) E2 k
void Timer0_init(void)
u7 I% v( I Y3 [1 {; o6 j{
6 e6 N2 s7 G$ w nTMOD=0x01; //定时器0工作于方式1
! B2 p/ }9 `0 P% y- o3 NTH0=TH0_TL0/256;0 d6 F$ x9 \6 c) v3 v9 Q* i1 J
TL0=TH0_TL0%256;- C6 Q" Q/ V/ E0 U$ D
TR0=1;- V% b3 {% P H6 D+ ]6 m0 y
ET0=1;
( V+ F# V3 S9 N4 l0 j3 h- dEA=1;
. B& ?* E6 K. ?. F" K}
' g4 a6 k6 n4 c, x9 n/ j' E2 v5 @7 b( O+ ~
/*********主函数********************/
- h3 b' J4 V* q8 V$ b, e& m' mvoid main(void)% }! ^1 K; r: n' @0 V
{
0 J7 O# W& L8 K+ h3 L Timer0_init();
; h% ^0 I! V8 C% W4 a8 k1 Q/ E. m6 K9 g/ J/ G7 Y
while(1)
8 L6 d1 D& K9 K. r9 ], d" Y {( ^" B& C+ F; a0 G; s4 k
Motor_turn();9 [; B% M. H( M' i( u% f( }
Motor_speed_high();3 w7 P& K5 {6 ]4 _3 ~; [
Motor_speed_low();
* Q$ E. H, d* W8 _( g3 s' ` }& S, C# w' P V4 D! J5 [. L
}- D& r/ E4 g+ Y
) E" H' M1 M* }3 V' R5 ?. S3 g) X0 z7 o/**************定时0中断处理******************/
' h9 p6 `5 J; }- q. G) evoid Timer0_int(void) interrupt 1 using 1
$ J _4 I: X% a2 y6 Y3 w" h{
* p0 h1 O3 F6 X3 b% v! ZTR0 = 0;//设置定时器初值期间,关闭定时器
+ u# b( R& v1 q2 bTL0 = TH0_TL0 % 256;6 t0 v3 X" S. o+ |; R$ m1 `
TH0 = TH0_TL0 / 256 ;//定时器装初值( _: N3 U" a' G: m, i& g/ x- x
TR0 = 1;
5 G+ ^- o! t2 U, ]% O5 M/ X/ H& [9 |$ A. C9 r ~ v1 `& @5 j S: U
if(Time_delay != 0)//延时函数用7 T) Y0 }, ?' A6 n& h% U
{9 p) L; c- P& x {8 D
Time_delay--; % Q& N& }+ z5 n" G G' |
}
% J' x9 N0 {( y* |: I+ j" T" n
* k, g: X- a+ G$ P3 wif(Flag == 1)//电机正转
' ]! d' L7 z5 Q' q, ?{% B- Z: l: G! Q* ^8 _7 I
PWM1 = 0; # Q: }! E* n2 F& K W
4 g# Z8 C- b! k) B if(++count1 < count0)
: _ N8 n% ~& J- `' `% x( } {
' g3 V. P" f5 Y4 Y3 k' z3 e9 t9 X PWM2 = 1;" T$ P) K- E# J- j. L$ \$ j: z
}) w9 r+ S& o4 u: |9 L
else
( C1 P/ k/ z& n6 D PWM2 = 0;
p3 z5 s. O/ q( u2 t( w
0 I% ?+ ^: Z0 t0 r0 V# l( Q if(count1 >= 100); o" h/ o$ a$ t! u6 z3 \
{& {: n9 O" `& e f& ~
count1=0;
2 P0 ^$ ~- z% j/ T, O5 p/ U }
$ `4 b/ b! i* e% G" h3 F' S' I, Q}! ~7 @5 l s6 R9 n4 n
else //电机反转$ f5 A$ p5 ^; m4 _5 D+ Z! }3 }
{0 }" b: z/ M& E% B( ]8 G
PWM2 = 0; + d+ Q, g- t9 m1 t" B* A
; p' l1 U, f& c8 T
if(++count1 < count0)2 J+ u' Y5 B a1 g( V
{
6 j% G3 Z, T9 @( g7 K+ m& w PWM1 = 1;
* e2 w x( D6 G) f0 q7 R5 x }
7 G& V. ?6 p, q) G1 a/ [& e. F else
& @- X& U) o; r' P PWM1 = 0;+ H/ r: J0 O7 H7 G
. h- j1 X `; Y3 j& x& J ]
if(count1 >= 100)
$ U. `6 a7 v- l8 s# `2 v {. v( l; m: g, L7 Y7 _
count1=0;* Q5 G$ b$ K, W
}4 \; s; K* M, y( b; D1 r
} i$ C5 x' `, F: O) R6 h! V# c+ N
}& y8 {$ I! q/ e: m
/************************************************
- e6 e: O0 H6 y e* ^. G9 O5 ^' V- x/ c$ G
void Delay(unsigned char x)
2 n. U. X; N% R% z3 v2 d0 c{
# d& O4 z8 J& Z( ATime_delay = x;5 c3 @; C+ r% P8 u1 J8 H
% [7 Y6 M3 c" N
while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔- J; R. \( j! b4 D7 p \) w
}/ w; |4 Z+ {+ v0 J% h& Y
$ [) P, i# w9 A6 [2 n
Delay(10);$ n* E5 e: C$ P5 D6 ]- }+ C4 \
+ ]$ l% t* H4 V5 n4 N* z! f
if(Time_delay != 0)//延时函数用
9 v% K( v( a# ]/ _{1 f" S6 |9 r: o
Time_delay--;
( f7 f7 e8 X+ g; g" x9 ?4 |}: s" Q% B8 M( S1 ? o
; C1 `6 ]+ D( j0 L2 \
其实这三个部分是相关联的。
* {0 O" ?' {$ c/ a. MDelay(10)这是延时防抖的这是毫无疑问的,但这个消抖在消抖的同时将一开始只是声明了下的Time-- S6 z1 @2 t5 Q, d; s
2 |. }; L! j+ w4 Gdelay赋值了,赋值还不算他还牵扯到定时器里去了。你看在赋值后Time-delay变成了10,看第二个部分2 S, u: X, `8 N7 k4 N; {. S4 |: l) f
) U8 z; b& t8 N& a% }1 ~/ k的while(Time-delay!=10);这个语句正如注释所说的等待中断,当等来了中断后你可以看第三个部
2 ^# i: q4 L1 Z" ~1 W2 R/ d$ ?) f; e7 ]1 _2 K# @8 {
分了,看见了吧终端中有将Time-delay减一,每中断一次就减一次直到等于0之后。也就是说延时的时长- ~: h) r9 T! f0 N/ z
: \7 A1 d5 ^: G" Q7 L
是十个中断的时长。注释中:可减少PWM输出时间间隔 也就可想而知了。: t" e: D4 ~6 s% ^% a
*****************************************************/
" N' Q M6 q" X* P- e! J& W1 X' \+ f( M0 {
, F4 [, F: S9 L- B6 s6 s& Q
|
|