| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 7357 人关注过本帖
标题:一个超声波测距的程序源码
取消只看楼主 加入收藏
hlmzrdongdong
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:湖北武汉
等 级:版主
威 望:1
帖 子:99
专家分:145
注 册:2008-10-24
结帖率:100%
收藏
 问题点数:0 回复次数:1 
一个超声波测距的程序源码
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。
超声波的接收电路包含一块CD40106处理芯片。
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
#include<reg51.h>
#include <intrins.h>
#define Busy    0x80  //用于检测LCM状态字中的Busy标识
#define LCM_Data  P0
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long


extern void cs_t(void);
extern void delay(uint);



void LCMInit(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void DisplayListChar(uchar X, uchar Y, uchar  *DData);
void Delay5Ms(void);
void Delay100Ms(void);

void WriteDataLCM(uchar WDLCM);
void WriteCommandLCM(uchar WCLCM,BuysC);


data float distant=0.0;
uchar ReadDataLCM(void);
uchar ReadStatusLCM(void);
uchar  cdle_net[] = {"--Daoche_Leida--"};
uchar  email[] = {"Juli:"};
uchar  cls[]={"         "};
uchar DIS[7];
data ulong time;
float distant;
sbit LCM_RS=P1^1;  //定义LCD引脚
sbit LCM_RW=P1^2;
sbit LCM_E=P1^3;
sbit P10=P1^0;


data uchar flag;

void zhuanhuan(float juli)
{
 unsigned long juli1;
 juli1=juli*100;
 DIS[6]=juli1%10+0x30;
 juli1=juli1/10;
 DIS[5]=juli1%10+0x30;
 juli1=juli1/10;
 DIS[4]='.';
 DIS[3]=juli1%10+0x30;
 juli1=juli1/10;
 DIS[2]=juli1%10+0x30;
 juli1=juli1/10;
 DIS[1]=juli1%10+0x30;
 DIS[0]=juli1/10+0x30;
 
}

void main(void)
{
   
    Delay100Ms(); //启动等待,等LCM讲入工作状态
    P10=1;    
    TMOD=0x01;             //计数器0工作在方式1
    TH0=0;
    TL0=0;                  //计数值初始化
    IT1=0;                 //低电平触发中断
    EA=1;                //开总中断
    //IP=0x04;             //设置外部中断1为高优先级中断
    flag=0;
    LCMInit(); //LCM初始化
    
    
    while(1)
    {
     cs_t();
     Delay5Ms();        
     ET0=1;         //打开计数器0中断
     EX1=1;         //打开外部中断1
     TR0=1;
     while(!flag)
     {
      DisplayListChar(0, 0, cdle_net);
      DisplayListChar(0, 1, email);
     }
     if(flag==1)
     {
      time=TH0;
      time=(time<<8)|TL0;
      distant=time*1.72/100;
      zhuanhuan(distant);
      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');
      else   DisplayOneChar(5,1,DIS[0]);
      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');
      else   DisplayOneChar(6,1,DIS[1]);
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
      else   DisplayOneChar(7,1,DIS[2]);
      DisplayOneChar(8,1,DIS[3]);
      DisplayOneChar(9,1,DIS[4]);
      DisplayOneChar(10,1,DIS[5]);
      DisplayOneChar(11,1,DIS[6]);
      DisplayOneChar(12,1,'c');
      DisplayOneChar(13,1,'m');
      flag=0;
      }
     else
     {
      DisplayListChar(5,1,"error!      ");
      flag=0;
     }
     TH0=0;
     TL0=0;
    Delay100Ms();
    }
}



void cs_r(void) interrupt 2
{
 TR0=0;
 EX1=0;
 ET0=0;
 flag=1;
}


void overtime(void) interrupt 1
{
 EX1=0;
 TR0=0;
 ET0=0;
 flag=2;
}


//写数据
void WriteDataLCM(uchar WDLCM)
{
    ReadStatusLCM(); //检测忙
    LCM_Data=WDLCM;
    LCM_RS=1;
    LCM_RW=0;
    LCM_E=0; //若晶振速度太高可以在这后加小的延时
    LCM_E=0; //延时
    LCM_E=1;
}

//写指令
void WriteCommandLCM(uchar 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;    
}

//读数据
uchar ReadDataLCM(void)
{
    LCM_RS = 1;
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    return(LCM_Data);
}

//读状态
uchar 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(0x0F,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
    X |= 0x80; //算出指令码
    WriteCommandLCM(X, 1); //发命令字
    WriteDataLCM(DData); //发数据
}

//按指定位置显示一串字符
void DisplayListChar(uchar X, uchar Y, uchar  *DData)
{
    uchar ListLength;

  ListLength = 0;
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    while (DData[ListLength]>0x20) //若到达字串尾则退出
        {
            if (X <= 0xF) //X坐标应小于0xF
                {
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                    ListLength++;
                    X++;
                }
        }
}

//5ms延时
void Delay5Ms(void)
{
    uint TempCyc = 200;
    while(TempCyc--);
}

//400ms延时
void Delay100Ms(void)
{
    uchar TempCycA = 1;
    uint TempCycB;
    while(TempCycA--)
        {
            TempCycB=7269;
            while(TempCycB--);
        
}
收到的鲜花
  • WSY3792008-11-11 13:23 送鲜花  10朵   附言:好文章
搜索更多相关主题的帖子: 超声波 源码 测距 
2008-10-25 22:14
hlmzrdongdong
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:湖北武汉
等 级:版主
威 望:1
帖 子:99
专家分:145
注 册:2008-10-24
收藏
得分:0 
回复 3# 的帖子
是的啊
2008-11-12 17:26
快速回复:一个超声波测距的程序源码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018013 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved