超声波模块单片机程序.docx

上传人:b****8 文档编号:9721740 上传时间:2023-02-06 格式:DOCX 页数:40 大小:23.84KB
下载 相关 举报
超声波模块单片机程序.docx_第1页
第1页 / 共40页
超声波模块单片机程序.docx_第2页
第2页 / 共40页
超声波模块单片机程序.docx_第3页
第3页 / 共40页
超声波模块单片机程序.docx_第4页
第4页 / 共40页
超声波模块单片机程序.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

超声波模块单片机程序.docx

《超声波模块单片机程序.docx》由会员分享,可在线阅读,更多相关《超声波模块单片机程序.docx(40页珍藏版)》请在冰豆网上搜索。

超声波模块单片机程序.docx

超声波模块单片机程序

1.超声波测距

//晶振=8M

//MCU=STC10F04XE

//P0.0-P0.6共阳数码管引脚

//Trig=P1^0

//Echo=P3^2

#include//包括一个52标准内核的头文件

#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显示

/******************

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 畜牧兽医

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1