专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

一款液晶显示的超声波测距板

作者:huqin   来源:本站原创   点击数:  更新时间:2013年11月14日   【字体:

   这是一款液晶显示超声波测距板,资料是从网上收集整理的。该测距板显示屏为3310手机液晶屏,测量范围是4cm--450cm。单片机用的是51系列单片机,超声波接收用的是CX20106A。为了使精度尽可能的提高,硬件方面使用了18B20监测温度,由温度算出声速的变化;软件方面使用了“近距离<--->远距离”自动调节“盲区时间”进行测量。因为盲区时间设小一点,可以测到较小的距离,但是测远距离时就极不稳定了;而盲区时间大了则相反;.软件较正使用的是数据拟合的方式,即测出几十组数据(仪器测出的矩离和实际矩离),输入EXCEL里面,画出XY散点图。然后再拟合出距离关系曲线。这种方法可以使测量点尽量靠近每一个实际距离点。

 




 

源程序:

#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);

}

关闭窗口

相关文章