超声波模块单片机程序Word文件下载.docx
《超声波模块单片机程序Word文件下载.docx》由会员分享,可在线阅读,更多相关《超声波模块单片机程序Word文件下载.docx(40页珍藏版)》请在冰豆网上搜索。
CLK_DIV=0X03;
//系统时钟为1/8晶振(pdf-45页)
P0M1=0;
//将io口设置为推挽输出
P1M1=0;
P2M1=0;
P0M0=0XFF;
P1M0=0XFF;
P2M0=0XFF;
i=0;
flag=0;
test=0;
Trig=0;
//首先拉低脉冲输入引脚
TMOD=0x11;
//定时器0,定时器1,16位工作方式
TR0=1;
//启动定时器0
IT0=0;
//由高电平变低电平,触发外部中断
ET0=1;
//打开定时器0中断
//ET1=1;
//打开定时器1中断
EX0=0;
//关闭外部中断
EA=1;
//打开总中断0
while
(1)//程序循环
{
EA=0;
Trig=1;
delay_20us();
//产生一个20us的脉冲,在Trig引脚
while(Echo==0);
//等待Echo回波引脚变高电平
succeed_flag=0;
//清测量成功标志
EX0=1;
//打开外部中断
TH1=0;
//定时器1清零
TL1=0;
TF1=0;
//
TR1=1;
//启动定时器1
while(TH1<
30);
//等待测量的结果,周期65.535毫秒(可用中断实现)
TR1=0;
//关闭定时器1
if(succeed_flag==1)
{
distance_data=outcomeH;
//测量结果的高8位
distance_data<
<
=8;
//放入16位的高8位
distance_data=distance_data|outcomeL;
//与低8位合并成为16位结果数据
distance_data*=12;
//因为定时器默认为12分频
distance_data/=58;
//微秒的单位除以58等于厘米
}//为什么除以58等于厘米,Y米=(X秒*344)/2
//X秒=(2*Y米)/344==》X秒=0.0058*Y米==》厘米=微秒/58
if(succeed_flag==0)
{
distance_data=0;
//没有回波则清零
test=!
test;
//测试灯变化
}
///distance[i]=distance_data;
//将测量结果的数据放入缓冲区
///i++;
///if(i==3)
///{
///distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
///pai_xu();
///distance_data=distance[1];
a=distance_data;
if(b==a)CONT_1=0;
if(b!
=a)CONT_1++;
if(CONT_1>
=3)
{CONT_1=0;
b=a;
conversion(b);
}
///i=0;
///}
}
//***************************************************************
//外部中断0,用做判断回波电平
INTO_()interrupt0//外部中断是0号
{
outcomeH=TH1;
//取出定时器的值
outcomeL=TL1;
succeed_flag=1;
//至成功测量的标志
//****************************************************************
//定时器0中断,用做显示
timer0()interrupt1//定时器0中断是1号
TH0=0xfd;
//写入定时器0初始值
TL0=0x77;
switch(flag)
{case0x00:
P0=ge;
P2=0xfd;
flag++;
break;
case0x01:
P0=shi;
P2=0xfe;
case0x02:
P0=bai;
P2=0xfb;
flag=0;
//*****************************************************************
/*
//定时器1中断,用做超声波测距计时
timer1()interrupt3//定时器0中断是1号
TH1=0;
TL1=0;
*/
//******************************************************************
//显示数据转换程序
voidconversion(uinttemp_data)
ucharge_data,shi_data,bai_data;
bai_data=temp_data/100;
temp_data=temp_data%100;
//取余运算
shi_data=temp_data/10;
temp_data=temp_data%10;
ge_data=temp_data;
bai_data=SEG7[bai_data];
shi_data=SEG7[shi_data];
ge_data=SEG7[ge_data];
bai=bai_data;
shi=shi_data;
ge=ge_data;
voiddelay_20us()
{ucharbt;
for(bt=0;
bt<
100;
bt++);
voidpai_xu()
{uintt;
if(distance[0]>
distance[1])
{t=distance[0];
distance[0]=distance[1];
distance[1]=t;
}/*交换值
if(distance[0]>
distance[2])
{t=distance[2];
distance[2]=distance[0];
distance[0]=t;
if(distance[1]>
{t=distance[1];
distance[1]=distance[2];
distance[2]=t;
}/*交换值
2.超声波测距LCD1602显示
SMC1602A(16*2)模拟口线接线方式
连接线图:
---------------------------------------------------
|LCM-----51|LCM-----51|LCM------51|
--------------------------------------------------|
|DB0-----P1.0|DB4-----P1.4|RW-------P3.4|
|DB1-----P1.1|DB5-----P1.5|RS-------P3.3|
|DB2-----P1.2|DB6-----P1.6|E--------P3.5|
|DB3-----P1.3|DB7-----P1.7|VLCD接1K电阻到GND|
接线:
模块TRIG接P3.7ECH0接P3.6
本程序源码只供学习参考,不得应用于商业用途,如有需要请联系作者。
[注:
stc89c52使用12M或11.0592M晶振,实测使用11.0592M]
=============================================================*/
AT89x51.H>
//器件配置文件
intrins.h>
#defineRXP3_6
#defineTXP3_7
#defineLCM_RWP2_3//定义LCD引脚
#defineLCM_RSP2_4
#defineLCM_EP2_2
#defineLCM_DataP1
#defineKey_DataP3_3//定义Keyboard引脚
#defineKey_CLKP3_2
#defineBusy0x80//用于检测LCM状态字中的Busy标识
voidLCMInit(void);
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);
voidDelay5Ms(void);
voidDelay400Ms(void);
voidDecode(unsignedcharScanCode);
voidWriteDataLCM(unsignedcharWDLCM);
voidWriteCommandLCM(unsignedcharWCLCM,BuysC);
unsignedcharReadDataLCM(void);
unsignedcharReadStatusLCM(void);
unsignedcharcodemcustudio[]={"
==RangeFinder=="
};
unsignedcharcodeemail[]={"
heyaodz@"
unsignedcharcodeCls[]={"
"
unsignedcharcodeASCII[15]={'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
.'
-'
M'
staticunsignedcharDisNum=0;
//显示用指针
unsignedinttime=0;
unsignedlongS=0;
bitflag=0;
unsignedchardisbuff[4]={0,0,0,0,};
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();
//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;
//若晶振速度太高可以在这后加小的延时
//延时
LCM_E=1;
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
if(BuysC)ReadStatusLCM();
//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
//读数据
unsignedcharReadDataLCM(void)
LCM_RW=1;
return(LCM_Data);
//读状态
unsignedcharReadStatusLCM(void)
LCM_Data=0xFF;
while(LCM_Data&
Busy);
//检测忙信号
voidLCMInit(void)//LCM初始化
LCM_Data=0;
WriteCommandLCM(0x38,0);
//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,1);
//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);
//关闭显示
WriteCommandLCM(0x01,1);
//显示清屏
WriteCommandLCM(0x06,1);
//显示光标移动设置
WriteCommandLCM(0x0F,1);
//显示开及光标设置
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
Y&
=0x1;
X&
=0xF;
//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;
//当要显示第二行时地址码+0x40;
X|=0x80;
//算出指令码
WriteCommandLCM(X,1);
//发命令字
WriteDataLCM(DData);
//发数据
//按指定位置显示一串字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)
unsignedcharListLength;
ListLength=0;
while(DData[ListLength]>
0x19)//若到达字串尾则退出
if(X<
=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);
//显示单个字符
ListLength++;
X++;
}
}
//5ms延时
voidDelay5Ms(void)
unsignedintTempCyc=5552;
while(TempCyc--);
//400ms延时
voidDelay400Ms(void)
unsignedcharTempCycA=5;
unsignedintTempCycB;
while(TempCycA--)
TempCycB=7269;
while(TempCycB--);
};
/********************************************************/
voidConut(void)
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.8)/10;
//算出来是MM
if((S>
=7000)||flag==1)//超出测量范围显示“-”
DisplayOneChar(0,1,ASCII[11]);
DisplayOneChar(1,1,ASCII[10]);
//显示点
DisplayOneChar(2,1,ASCII[11]);
DisplayOneChar(3,1,ASCII[11]);
DisplayOneChar(4,1,ASCII[11]);
DisplayOneChar(5,1,ASCII[12]);
//显示M
else
disbuff[0]=S/1000;
disbuff[1]=S/100%10;
disbuff[2]=S/10%10;
disbuff[3]=S%10;
DisplayOneChar(0,1,ASCII[disbuff[0]]);
DisplayOneChar(2,1,ASCII[disbuff[1]]);
DisplayOneChar(3,1,ASCII[disbuff[2]]);
DisplayOneChar(4,1,ASCII[disbuff[3]]);
voidzd0()interrupt1//T0中断用来计数器溢出,超过测距范围
flag=1;
//中断溢出标志
RX=0;
voidStartModule()//启动模块
TX=1;
//启动一次模块
_nop_();
TX=0;
voidTimer_Count(void)
TR0=1;
//开启计数
while(RX);
//当RX为1计数并等待
TR0=0;
//关闭计数
Conut();
//计算
/********************************************************/
voiddelayms(unsignedintms)
unsignedchari=100,j;
for(;
ms;
ms--)
while(--i)
j=10;
while(--j);
/*********************************************************/
voidmain(void)
unsignedintvalA;
unsignedcharTempCyc;
Delay400Ms();
//启动等待,等LCM讲入工作状态
LCMInit();
//LCM初始化
//延时片刻(可不要)
DisplayListChar(0,0,mcustudio);
DisplayListChar(0,1,email);
ReadDataLCM();
//测试用句无意义
for(TempCyc=0;
TempCyc<
10;
TempCyc++)
DisplayListChar(0,1,Cls);
TMOD=0x01;
//设T0为方式1,GATE=1;
//允许T0中断
//开启总中断
while
(1)
delayms(60);
RX=1;
StartModule();
for(valA=7510;
valA>
0;
valA--)
if(RX==1)
Timer_Count();
3.超声波测距LCD12864显示
/******************