--超声波测距模块--测距--最简单的C代码

?/*本人是电子专业的大一学生,因为学校这学期还没开设相关的专业课程,所有现在是自学单片机,技术有限,没有加入温度补偿,数码管显示也没有用锁存芯片,凭着对C语言的一点掌握写出了这个最容易看懂并且能够有效运行的单片机程序,写的是自己想出来的最简单的代码,希望大家不要见笑。O(∩_∩)O*/

/*因为一直都很想尝试超声波测距,所以前些天买了个HC-R4的超声波模块,网上找了一下原理(原理很简单的),然后就自己尝试着写代码,下面的代码基本上都是自己想出来的,没有参照过别人的,并不是说我不想去参照别人的,而是因为网上高手很多但是他们写的代码我基本上还有很多看不懂呵,所以下面的程序应该还有很多可以改进的地方。*/

/*超声波模块基本工作原理(资料由网上分享而来):
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
使用方法很简单,一个控制口发一个10us以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以达到移动测量的值。*/

/****************************************************************************************************************************************************/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit kongzhi=P1^0; //控制端(即TRIG)接P1.0引脚
sbit jieshou=P1^1; //接收端(即ECHO)接P1.1引脚
sbit LED1=P1^2; //数码管位显示,m位
sbit LED2=P1^3; //数码管位显示,dm位
sbit LED3=P1^4; //数码管位显示,cm位
sbit xiaoshudian=P2^0; //初始化控制数码管的小数点的位
uint m=1; //为了测试数码管显示是否正常
uint dm=2;
uint cm=3;
uint juli; //距离
uint s=0; //s初始值为0
uint smguanmo[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //数码管字模,分别对应1-9
/****************************************************************************************************************************************************/
void yanshi(uint x) //延时函数
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
/****************************************************************************************************************************************************/
void time0() interrupt 1 //定时器0
{
TH0=0xff; //60us后s加1,声速定为340m/s,用的是12m晶振,则每60us为1.02cm

(所测的距离)
TL0=0xc4;
s=s++;
}
/****************************************************************************************************************************************************/
void xianshi() //数码管显示,没有用锁存器,用的是动态显示
{
P2=smguanmo[m]; //P2引脚作为数码管的段显示
xiaoshudian=0; //点亮数码管m位的小数点
LED1=1;yanshi(2); //点亮m位,延时数毫秒后再熄灭m位显示,下面同样的道理
LED1=0;
P2=smguanmo[dm];
LED2=1;yanshi(2);
LED2=0;
P2=smguanmo[cm];
LED3=1;yanshi(2);
LED3=0;
}
/****************************************************************************************************************************************************/
void shujuchuli() //数据的处理
{
if(juli<1000&&juli>=100){m=juli/100;dm=juli/10%10;cm=juli%10;}
if(juli<100&&juli>=10){m=0;dm=juli/10;cm=juli%10;}
if(juli<10){m=0;dm=0;cm=juli;}
}
/****************************************************************************************************************************************************/
void main()
{
TMOD=0x01; //设定定时器0的工作模式
ET0=1; //定时器0的中断允许位
EA=1; //中断总允许位
TR0=0; //定时器0的控制位
kongzhi=0; //控制端初始化为低电平
jieshou=0; //接收端初始化为低电平
while(1)
{
kongzhi=1; //控制端输出高电平
yanshi(1); //延时
kongzhi=0; //控制端输出低电平
while(jieshou==0); //等待接收端转为高电平
TR0=1; //当接收端转为高电平后打开定时器0的控制位,定时器0开始计时
while(jieshou==1); //等待接收端转为低电平
TR0=0; //当接收端转为低电平后关闭定时器0的控制位,定时器0停止计时
juli=s; //将s的值赋给变量juli
s=0; //s值清零
TH0=0xff; //重新设定定时器初值
TL0=0xc4;
shujuchuli(); //处理上面得出的距离
xianshi(); //数码管显示函数
}
}



/*待改进的地方:数码管显示亮度以及当测量距离较大时的闪烁问题,温度补偿以得到高精度的测量距离,*/
/*仅以此献给所有热爱单片机的初学者们!希望对所有初学单片机的朋友有所帮助!同时希望结交更多有志之士!*/






相关文档
最新文档