找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2835|回复: 2
打印 上一主题 下一主题
收起左侧

3310LCD制作的超声波波测距仪

[复制链接]
跳转到指定楼层
楼主
ID:76686 发表于 2015-4-12 02:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   本人喜欢制作超声波测距仪,在网上看到了这款用CX20106做接收电路、单片机用AT89C52、显示用若基亚手机3310LCD制作的超声波测距仪,供电电压DC5V,作者:babytaomail ,感觉制作的比较好,特此转贴,让多多的爱好者进行仿制。该超声波测距仪测距范围4.5cm~230cm,理论误差可以达到2mm左右,资料比较齐全,很方便仿制。



#include "stdio.h"
#include "math.h"
#include "regx52.h"
#include "binary.h"
#include "intrins.h"
#define  VOUT P3_7  //脉冲产生端口
#define  DQ  P1_0 //ds18b20 端口
/******************系统全局变量***************/
typedef  unsigned char uchar;
typedef  unsigned int uint;
bit Success;   //测量成功标志位
bit Done;    //测量完成标志位
bit Mode;  //测量模式:0--近距离,1---远距离
uint nCount;
uint nResult;
/******************18B20相关函数及变量***************/
bit SignedFlag=0;   //符号标志位  ,负为1,正为0
uchar TempInt;  //整数部分温度
uint TempDot;  //小数部分温度
void ReadTemperature(void);      //在程序中调用此函数
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void delayx(unsigned int i);
#include "18b20.h"
/******************LCD相关函数******************/
sbit SCLK = P2^0;  // 串行时钟
sbit SDIN = P2^1;  // 串行数据输入
sbit LCD_DC = P2^2;  // 数据/命令 选择端
sbit LCD_CE = P2^3;  // 片选
sbit LCD_RST = P2^4; // 外部复位
#include "Nokia5110.c"
/***********超声波测量相关函数定义***************/
void StartInit();
void Delay_us(uint i);     //微秒级延时:T=7+2*(X-1) us
void StartMeasure();
void DisplayResult();
void ConvertCount();
void Delay_ms(uint x);
////////////////////////主函数////////////////////////////////
void main()
{
unsigned long Sum;
uchar i;
uchar num;
bit bOK;
uchar
TCON=B00000000; //INT0电平触发
TMOD=0X01;      //T0作为计数输入
IP=B00000001; //置INT0优先级最高
LCD_init();  //液晶初始化
LCD_clear(); //清屏显示
DisplayChinese(0,0,13,16,3,0,0,WORD);   //在LCD上显示“温度:”
DisplayChinese(72,0,13,16,1,3,0,WORD);  //在LCD上显示“℃”
DisplayChinese(0,2,13,16,3,4,0,WORD);  //在LCD上显示"声速:”
while(1)    //测量系统主循环
{
  bOK=0;
  num=0;
  Sum=0;
  ReadTemperature();      //检测当前环境温度
  
     for(i=1; i<=3; ++i)  //循环测量,求平均值
  {
   StartInit();  //测量初始化
   StartMeasure();  //开始测量第1次,确定大概范围
   if(Success==1)
   {
    bOK=1;     //有1次成功,则测距成功
    Sum=(nCount>Sum)?nCount:Sum;  //取测量最大值
   }
   Delay_ms(80);   //延时10ms后继续测量
  }
  nCount=Sum;
  Success=bOK;
  DisplayResult();
}  
}
/***************所用到的相关函数功能实现*****************/
void INT_0() interrupt 0  using 0  //运行到此处说明测距成功
{
TR0=0;  //关计数
ET0=0;  //关定时器中断
EX0=0;  //关INT0中断
while(!P3_2); //等待CX20106输出电平变高
//将计数器数据放进nCount,用来进行数据处理
nCount=TH0;
nCount=nCount<<8;
nCount|=TL0;
Success=1;
Done=1;
return;  
}
void INT_T0()  interrupt 1 using 1
{
//运行到此处说明测距失败
TR0=0;
EX0=0;
Success=0;
Done=1;  
return ;
}
void StartInit()
{
  TH0=0;
  TL0=0;  //计数器置0
  EA=1;   //开总中断
  ET0=0;  //关T0中断
  EX0=0;  //关INT0中断
  Success=0; //测量成功标志位
  Done=0; //测量一次标志位
}
void StartMeasure()
{
//产生脉冲波
uchar LOOP;
ET0=1;

for (LOOP = 0;LOOP < 4; )
{
        P3 = P3 ^ 0x80;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  _nop_();_nop_();_nop_();_nop_();//_nop_();_nop_();
         LOOP++;
}
VOUT = 1;
TR0 = 1; //启动计数器
if(Mode==0)  //近距离测量模式
{
  Delay_us(41); //50us延时测量,防止回波干扰
}
else       //远距离测量模式
{
  Delay_us(300); //50us延时测量,防止回波干扰
}

EX0=1;     //开INT0中断
while(Done==0);  //等待测量结束
}
void DisplayResult()
{
float temp=0;
char String[10];
//算出当前温度
temp=TempInt+TempDot/10000.0;   
//显示当前温度
sprintf(String,"%0.2f",temp);
DisplayEnglish(33,0,String);
//算出当前声速
temp=332+0.607*temp;     
//显示当前声速
sprintf(String,"%0.1fm",temp);
DisplayEnglish(33,2,String);
if(Success==1)     //测距成功,显示“成功”,并显示距离
{
  temp=nCount*temp/2000+0.5;  // 算出距离
  //显示远、近距离测量的结果
  if(Mode==0)
  {
   nResult=(0.9723*temp-14.803)+0.5;       //此式由拟合得到
   DisplayEnglish(0,4,"N");
  }
  else
  {
   nResult=0.9648*temp-5.7716+0.5;  //此式由拟合得到         
   DisplayEnglish(0,4,"F");
  }
      
  sprintf(String,"%5u cm",nResult);   //将整数转换为字符串
  //拼凑显示最终结果“xxx.xcm”
  DisplayEnglish(8,4,String);     
  DisplayEnglish(40,4,".");   
  String[5]='\0';
  DisplayEnglish(48,4,&String[4]);
  Delay_ms(50);
}
else      //测距失败,显示“失败”提示
{
        DisplayEnglish(0,4," --Fail-- ");
}
if(nResult>500)
{
  Mode=1;
}
else
{
  Mode=0;
}
}
void Delay_ms(uint x)    //12M环境下延时1ms
{
  uchar j;
  while(x--)
  {
     for(j=0;j<125;j++);
  }
}
void Delay_us(uint i)   //微秒级延时:T=7+2*(X-1) us
{
    while(--i);
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:74784 发表于 2015-4-12 11:28 | 只看该作者
代码有汇编的吗?
回复

使用道具 举报

板凳
ID:217936 发表于 2017-7-7 16:30 | 只看该作者
感觉很厉害,真的可以到2mm吗? 我自己做的效果很差 希望可以学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表