51单片机+L293D控制直流电机起保停和PWM调速

51单片机+L293D控制直流电机起保停和PWM调速

  • 仿真演示
    在这里插入图片描述

*程序源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include"reg51.h"
#define uint unsigned int
#define uchar unsigned char
sbit IN0=P2^0;//电机驱动引脚1
sbit IN1=P2^1;//电机驱动引脚2
sbit E=P2^2;//电机使能引脚
sbit key0=P1^0;//pwm增调节引脚
sbit key1=P1^1;//pwm减调节引脚
sbit key_stop=P1^2;
sbit key_star=P1^3;
uint T1_H,T1_L,T0_H,T0_L;
uchar a=50 ;
uchar fr; //a表示占空比:0-100,fr\*100后为PWM频率值调节范围:1-255。
uchar flag=0;
uchar flag0=0;
uchar flag_stop=0;
uchar flag_star=0;
void chuzhi();
void motor()
{
IN0=1;
if(a==100)
{
a=100;
}
}

void inittimer()
{

TMOD=0x01;
ET0=1;
EA=1;
TR0=1;
IN1=0;
}

void datdeal()
{
if(key0==0&&flag==0)
{
flag=1;
}
if(flag==1&&key0==1)
{
a=((a==0)?0:(a-10));
flag=0;
}
if(key1==0&&flag0==0)
{
flag0=1;
}
if(flag0==1&&key1==1)
{
a=((a==100)?100:(a+10));
flag0=0;
}
if(flag_stop==0&&key_stop==0)
{
flag_stop=1;
}
if(flag_stop==1&&key_stop==1)
{
ET0=0;//停止,关闭Timer0溢出中断
EA=0;//停止,关闭中断
TR0=0;
IE=0;
E=0;

flag_stop=0;
}
if(flag_star==0&&key_star==0)
{
flag_star=1;
}
if(flag_star==1&&key_star==1)
{
a=50;
ET0=1; //启用Timer0溢出中断
EA=1;//启用中断
TR0=1;
E=1;

flag_star=0;
}
}

void main()
{ fr=5;
inittimer();
while(1)
{
chuzhi();
datdeal();
motor();

}
}

void timer\_isr() interrupt 1
{
IN0=~IN0;
if(IN0==1) { TH0=T1_H;TL0=T1_L; }//若正在供电,赋供电初值,使供电维持对应时间;
if(IN0==0) { TH0=T0_H;TL0=T0_L; }//若正在断电,赋断电初值;使断电维持对应时间;

}
void chuzhi() //注意此处不可写为65536,
//否则当a为0或100时,产生溢出,造成错乱。
//这样也造成实际定时产生的占空比,与a%相比存在轻微偏差。
{
T0_H=(65535-10000/fr+a\*100/fr)/256;
T0_L=(65535-10000/fr+a\*100/fr)%256;
//断电时间初值;

T1_H=(65535-a\*100/fr)/256;
T1_L=(65535-a\*100/fr)%256;
//供电时间初值;
}