一、元器件需求
两节干电池、一个小马达和风扇、超声波模块、直流电机驱动板。
二、项目所达到的效果
靠近超声波时,风扇转速变快,远离超声波时,风扇转速变慢,距离太远风扇则不转。
三、程序设计
超声波初始化:
h04.c
#include<h04.h>
#include<reg52.h>
#include<delay.h>
void Time1Init()
{
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10;
TH1=0;
TL1=0;
}
//设置定时器0工作模块1,初始值设定0开始数数,不着急启动定时器
void startHC()
{
Trig=0;
Trig=1;
Delay10us() ;
Trig=0;
}
double get_distance()
{
double time;
TH1=0;
TL1=0;
//1.Trig给Trig端口至少10us的高电平
startHC();
//2.echo由低电平跳转到高电平,表示开始发送波
while(Echo==0);
//波发出的那一下,我们开始启定时器
TR1=1;
while(Echo==1);
//波回来的那一下,我们开始停止计时下
TR1=0;
//4.计算出中间经过多少时间
time=(TH1*256+TL1)*1.085;//单位为us
//5.距离=340m/s(速度)*时间/2
return time*0.017;
}
h04.h
#include<reg52.h>
sbit Trig =P1^5;
sbit Echo =P1^6;
void Time1Init();
void startHC();
double get_distance();
利用PWM波的控制原理,可以设定任意周期。
pwmbo.c
#include<reg52.h>
#include<pwmbo.h>
int jd;
int cnt =0;
void stop()
{
Leftcon1A=0;
Leftcon1B=0;
}
void Time0Init()
{
//1.配置定时器0工作模式位16位计时
TMOD =0x01;
//2.给初值,定一个0.5出来
TL0=0x33;
TH0=0xfe;
//3.开始计时
TR0=1;
TF0=0;
//4.打开定时器0中断
ET0=1;
//5.打开总中断EA
EA=1;
}
void Time0Handler() interrupt 1
{
cnt++;//统计爆表的次数,cnt=1的时候,报表了1
//重新给初值
TL0=0x33;
TH0=0xFE;
//控制PWM波
if(cnt<jd)
{
//导通开关p
Leftcon1A=0;
Leftcon1B=1;
}
else{
//关闭开关
Leftcon1A=0;
Leftcon1B=0;
}
if(cnt==40)//爆表40次,经过了20ms
{
cnt=0;//当40次表示1s,重新让cnt从0开始,计算下一次的20ms
}
}
pwmbo.h
void Time0Init();
sbit switcher=P1^1;
sbit Leftcon1A=P3^3;
sbit Leftcon1B=P3^4;
void stop();
delay.c
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
void Delay100ms() //@11.0592MHz
{
unsigned char i, j;
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
void Delay300ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
delay.h
void Delay1000ms() ; //@11.0592MHz
void Delay10us(); //@11.0592MHz
void Delay100ms() ; //@11.0592MHz
void Delay300ms() ; //@11.0592MHz
main.c
#include "reg52.h"
#include <h04.h>
#include <pwmbo.h>
#include <delay.h>
#define m 2
#define Right 1
extern int jd;
extern int cnt;
double dis;
int dir=0;
void main()
{
Time0Init();
Time1Init();
stop();
while(1)
{
dis=get_distance();
if(dis<10)
{
jd=40;
Delay300ms();
}else if(dis>=10&&dis<20)
{
jd=25;
Delay300ms();
}
else if(dis>=20)
{
jd=1;
Delay300ms();
}
}
}
四、总结
通过这个简单的小项目,可以把所学的PWM原理用在实践中,还用到了分文件处理,可以把各个模块独立起来,主函数代码变少,看的不杂乱无章,在编译出错时也便于改错。在写这个项目时,也遇到一个问题,就是在main函数最后一个else中把jd=1换成
Leftcon1A=0;
Leftcon1B=0;
直接写停,会出现一直转和刚开始都不会动起来,这是因为会被定时器中断打断,所以在用中断时要仔细。