基于51单片机的超声波测距仪

#include <reg51.h>
#include  <intrins.h>  
#define LCD1602_DATAPINS P0
 # define uchar unsigned char
# define uint unsigned int
uint distance=0;
 sbit  K1=P3^3;
uchar xuehao[]={"id:  131114105"};
uchar dis[]={"dis= "};


sfr P4=0xc0;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sbit LCD1602_E=P4^4;
sbit LCD1602_RW=P4^2;
sbit LCD1602_RS=P4^1;
sbit RX=P1^7; //Rx为输出回响信号    echo
sbit TX=P1^6;    //tx为输入触发信号 trig
long time;//time为双高精度浮点数
uint  temp=0,t=0,n=0,th,tl;
 bit flag_csb_juli;          //超声波超出量程
uint  m=0,flag_time0;
uchar th0,tl0;
uchar code num[] = "0123456789";
unsigned char disbuff[4]       ={ 0,0,0,0,};

uint j;
void delayms(unsigned int ms)
{
    unsigned char i=100,j;
    for(;ms;ms--)
    {
        while(--i)
        {
            j=10;
            while(--j);
        }
    }
}
void Delay10ms(unsigned int c)   //误差 0us
{
    unsigned char a, b;
    //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
    {
        for (b=38;b>0;b--)
        {
            for (a=130;a>0;a--);
        }          
    }       
}
void LcdWriteCom(uchar com)      //写入命令
{
    LCD1602_E = 0;     //使能
    LCD1602_RS = 0;       //选择发送命令
    LCD1602_RW = 0;       //选择写入
    LCD1602_DATAPINS = com;     //放入命令
    Delay10ms(1);        //等待数据稳定
    LCD1602_E = 1;              //写入时序
    Delay10ms(5);      //保持时间
    LCD1602_E = 0;
}
void LcdWriteData(uchar dat)            //写入数据
{
    LCD1602_E = 0;    //使能清零
    LCD1602_RS = 1;    //选择输入数据
    LCD1602_RW = 0;    //选择写入
    LCD1602_DATAPINS = dat; //写入数据
    Delay10ms(1);
    LCD1602_E = 1;   //写入时序
    Delay10ms(5);   //保持时间
    LCD1602_E = 0;
}
void Delay_ms(uint c)   //误差 0us
{
    uint x,y ;
    for(x=c;x>0;x--)
        for(y=110;y>0;y--);
}
void LcdInit()                          //LCD初始化子程序
{
     LcdWriteCom(0x38);  //开显示
    LcdWriteCom(0x0c);  //开显示不显示光标
    LcdWriteCom(0x06);  //写一个指针加1
    LcdWriteCom(0x01);  //清屏
    LcdWriteCom(0x80);  //设置数据指针起.点
}
//数字显示函数
void LCD_Write_number(uint i)
{    
    LcdWriteData(num[i]);
    Delay_ms(1);
}
/***********************lcd1602上显示超声波距离************************/
void Display()
{
/*    LcdWriteCom(0x80+0x40);          
    LCD_Write_number(distance/100%10);
    LcdWriteData('.');
    LCD_Write_number(distance/10%10);
    LCD_Write_number(distance%10);     */
    
    LcdWriteCom(0x80+0x40);
    disbuff[1]=distance%1000/100;
       disbuff[2]=distance%1000%100/10;
       disbuff[3]=distance%1000%10 %10;
            for(j=0;j<5;j++)
     {
                  LcdWriteData(dis[j]);
                Delay_ms(1);
     }
       LCD_Write_number(disbuff[1]);
         LcdWriteData('.');
      
       LCD_Write_number(disbuff[2]);
       LCD_Write_number(disbuff[3]);
           LcdWriteData(' ');
        LcdWriteData(' ');
       LcdWriteData('m');

}
//T0中断用来计数器溢出,超过测距范围
  void T0_time() interrupt 1         
{
 
}
  //定时器初始设置
  void time_init()      
{
    EA  = 1;           //开总中断
    TMOD = 0X01;      //定时器0工作方式1
    ET0 = 1;          //开定时器0中断
    TR0 = 1;          //允许定时器0定时
}
//小时间延迟函数
void delay()
{
    _nop_();                    //执行一条_nop_()指令就是1us
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();  
    _nop_();
    _nop_();
    _nop_();
    _nop_();                   
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();  
    _nop_();
    _nop_();
    _nop_();
    _nop_();                   
    _nop_();
    _nop_();                    //执行一条_nop_()指令就是1us
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();  
    _nop_();
    _nop_();
    _nop_();
    _nop_();                   
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();  
    _nop_();
    _nop_();
    _nop_();
    _nop_();                   
    _nop_();
}
void send_wave1()
{    
//    delay();
    TX=1;
    delay();
    TX=0;    
//    delay();
}
/*********************超声波测距程序*****************************/
void send_wave()
{
//    time_init();
//    distance=0;//test,distance clear
    send_wave1();
    
//    TR0 = 1;
    while(!RX);
    TR0=1;          //当c_recive为零时等待
    while(RX);    
    TR0=0;          //当RX为1计数并等待
    
    flag_time0 = TH0 * 256 +TL0;
    TH0 = 0;                  //给定时器0清零
    TL0 = 0;
    if((flag_time0 > 40000))      //当超声波超过测量范围时,显示3个888
    {
        flag_csb_juli = 2;
        distance = 888;    
    }
    else
    {
        flag_csb_juli = 1;    
    }
    if(flag_csb_juli == 1)                   
    {                                //测试,为什么要关掉定时器
        distance =flag_time0;             //读出定时器0的时间
         distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
        if((distance > 500))                 //距离 = 速度 * 时间
        {    
            distance = 888;                 //如果大于3.8m就超出超声波的量程
        }    
    }
}
void main(void)
{        
    uint t=0;
        
    
//    time_init();//定时器初始化
TMOD = 0X01;
    TH0=0;
    TL0=0;
    TR0=1;
    LcdInit();    //lcd  
    //第一行写学初始化
    LcdWriteCom(0x80);

    for(t =0; t<14; t++)
    {
        LcdWriteData(xuehao[t]);    
    }    
       while(1)
      {
        send_wave();     //超声波模块发射超声波
        Display();
        delayms(80); //测试
        //delay10ms(100);//测试,延时
        }
    }
    

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值