29、扩展篇5使用超声波技术测量物体的距离
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
29、扩展篇5使用超声波技术测量物体的距离
29、扩展篇5 使用超声波技术测量物体的距离
#include //器件配置文件
#include
#define RX P2_0
#define TX P2_1
#define LCM_RW P1_1 //定义LCD引脚
#define LCM_RS P1_0
#define LCM_E P2_5
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit DU = P2^6;
sbit WE = P2^7;
void cmg88()//关数码管
{
DU=1;
P0=0X00;
DU=0;
}
void LCMInit(void);//LCD初始化函数
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);//LCD 显示一个字符函数
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//LCD显示一个字符串函数void Delay5Ms(void);//延时5毫秒函数
void Delay400Ms(void);//延时400毫秒函数void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);//LCD1602写数据函数
void WriteCommandLCM(unsigned char WCLCM,BuysC);//LCD写命令函数
//unsigned char ReadDataLCM(void); unsigned char ReadStatusLCM(void); unsigned char code Range[] ="==Range Finder==";//LCD1602显示格式
unsigned char code ASCII[13] = "0123456789.-M";
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]=" Out of range";
//static unsigned char DisNum = 0; //显示用指针
unsigned int time=0;
unsigned long S=0;
bit flag =0;
unsigned char disbuff[4]={ 0,0,0,0,};
//写数据
void WriteDataLCM(unsigned char WDLCM) {
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
//读数据
/*unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}*/
//读状态
unsigned char ReadStatusLCM(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);
}
void LCMInit(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(0x0c,1); // 显示开及光标设置
}
//按指定位置显示一个字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 1); //发命令字
WriteDataLCM(DData); //发数据
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {
unsigned char ListLength;
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延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
/************************************ ********************/ void Conut(void) //超声波距离计算函数
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/10+10; //算出来是MM
if((S>=7000)||flag==1) //超出测量范围
{
flag=0;
DisplayListChar(0, 1, table1);
}
else
{
disbuff[0]=S%10;
disbuff[1]=S/10%10;
disbuff[2]=S/100%10;
disbuff[3]=S/1000;
DisplayListChar(0, 1, table);
DisplayOneChar(9, 1, ASCII[disbuff[3]]); DisplayOneChar(10, 1, ASCII[disbuff[2]]); DisplayOneChar(11, 1, ASCII[disbuff[1]]); DisplayOneChar(12, 1, ASCII[10]);
DisplayOneChar(13, 1, ASCII[disbuff[0]]);
}
}
/************************************ ********************/ void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围{
flag=1; //中断溢出标志
RX=0;
}
/************************************ ********************/
void StartModule()
//启动模块
{
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;
}
/************************************ ********************/ /*void delayms(unsigned int ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}*/
void Timer_Count(void) //超声波高电平脉冲宽度计算函数{
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
}
/************************************ *********************/ void main(void)
{
unsigned int valA;
Delay400Ms(); //启动等待,等LCM讲入工作状态
cmg88();//关数码管
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻
DisplayListChar(0, 0, Range);
DisplayListChar(0, 1, table);
//ReadDataLCM();//测试用句无意义
TMOD=0x01;//设T0为方式1,GATE=1;
EA=1; //开启总中断
TH0=0;
TL0=0;
ET0=1; //允许T0中断
while(1)
{
RX=1;
StartModule(); //启动模块
for(valA=7510;valA>0;valA--)
{
if(RX==1)
{
Timer_Count(); //超声波高电平脉冲宽度计算函数}
}
}
}。