超声波模块单片机程序.docx
- 文档编号:9721740
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:40
- 大小:23.84KB
超声波模块单片机程序.docx
《超声波模块单片机程序.docx》由会员分享,可在线阅读,更多相关《超声波模块单片机程序.docx(40页珍藏版)》请在冰豆网上搜索。
超声波模块单片机程序
1.超声波测距
//晶振=8M
//MCU=STC10F04XE
//P0.0-P0.6共阳数码管引脚
//Trig=P1^0
//Echo=P3^2
#include
#defineucharunsignedchar//定义一下方便使用
#defineuintunsignedint
#defineulongunsignedlong
//***********************************************
sfrCLK_DIV=0x97;//为STC单片机定义,系统时钟分频
//为STC单片机的IO口设置地址定义
sfrP0M1=0X93;
sfrP0M0=0X94;
sfrP1M1=0X91;
sfrP1M0=0X92;
sfrP2M1=0X95;
sfrP2M0=0X96;
//***********************************************
sbitTrig=P1^0;//产生脉冲引脚
sbitEcho=P3^2;//回波引脚
sbittest=P1^1;//测试用引脚
ucharcodeSEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0-9
uintdistance[4];//测距接收缓冲区
ucharge,shi,bai,temp,flag,outcomeH,outcomeL,i;//自定义寄存器
bitsucceed_flag;//测量成功标志
//********函数声明
voidconversion(uinttemp_data);
voiddelay_20us();
//voidpai_xu();
voidmain(void)//主程序
{uintdistance_data,a,b;
ucharCONT_1;
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();
Trig=0;//产生一个20us的脉冲,在Trig引脚
while(Echo==0);//等待Echo回波引脚变高电平
succeed_flag=0;//清测量成功标志
EX0=1;//打开外部中断
TH1=0;//定时器1清零
TL1=0;//定时器1清零
TF1=0;//
TR1=1;//启动定时器1
EA=1;
while(TH1<30);//等待测量的结果,周期65.535毫秒(可用中断实现)
TR1=0;//关闭定时器1
EX0=0;//关闭外部中断
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;//至成功测量的标志
EX0=0;//关闭外部中断
}
//****************************************************************
//定时器0中断,用做显示
timer0()interrupt1//定时器0中断是1号
{
TH0=0xfd;//写入定时器0初始值
TL0=0x77;
switch(flag)
{case0x00:
P0=ge;P2=0xfd;flag++;break;
case0x01:
P0=shi;P2=0xfe;flag++;break;
case0x02:
P0=bai;P2=0xfb;flag=0;break;
}
}
//*****************************************************************
/*
//定时器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];
EA=0;
bai=bai_data;
shi=shi_data;
ge=ge_data;
EA=1;
}
//******************************************************************
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]>distance[2])
{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]
=============================================================*/
#include
#include
#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=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCM();//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=0;
LCM_E=1;
}
//读数据
unsignedcharReadDataLCM(void)
{
LCM_RS=1;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
return(LCM_Data);
}
//读状态
unsignedcharReadStatusLCM(void)
{
LCM_Data=0xFF;
LCM_RS=0;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
while(LCM_Data&Busy);//检测忙信号
return(LCM_Data);
}
voidLCMInit(void)//LCM初始化
{
LCM_Data=0;
WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
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;
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
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)//超出测量范围显示“-”
{
flag=0;
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(1,1,ASCII[10]);//显示点
DisplayOneChar(2,1,ASCII[disbuff[1]]);
DisplayOneChar(3,1,ASCII[disbuff[2]]);
DisplayOneChar(4,1,ASCII[disbuff[3]]);
DisplayOneChar(5,1,ASCII[12]);//显示M
}
}
/********************************************************/
voidzd0()interrupt1//T0中断用来计数器溢出,超过测距范围
{
flag=1;//中断溢出标志
RX=0;
}
/********************************************************/
voidStartModule()//启动模块
{
TX=1;//启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_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初始化
Delay5Ms();//延时片刻(可不要)
DisplayListChar(0,0,mcustudio);
DisplayListChar(0,1,email);
ReadDataLCM();//测试用句无意义
for(TempCyc=0;TempCyc<10;TempCyc++)
Delay400Ms();//延时
DisplayListChar(0,1,Cls);
TMOD=0x01;//设T0为方式1,GATE=1;
TH0=0;
TL0=0;
ET0=1;//允许T0中断
EA=1;//开启总中断
while
(1)
{
delayms(60);
RX=1;
StartModule();
for(valA=7510;valA>0;valA--)
{
if(RX==1)
{
Timer_Count();
}
}
}
}
3.超声波测距LCD12864显示
/******************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 超声波 模块 单片机 程序