找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1102|回复: 2
收起左侧

单片机超声波测距为啥显示不了小数点后面的数,我用的是HC-SR04,下面是全部模块的代码

[复制链接]
ID:913310 发表于 2021-12-7 10:44 | 显示全部楼层 |阅读模式
主函数

#define uchar unsigned char
#define uint unsigned int
#define ULint unsigned long int
//温度零上与零下的标志位
char flag=0;
//超声波
char flags=0;
//超声波距离
char flag1s=0;
//计算定时间
uint time=0;
//计算距离
//ULint L_=0;
uchar L=0;
//温度
uint t_=0;
//显示模式  0正常  1最大值调整  2最小值调整
uchar mode=0;
uint Max=150;
uint Min=5;
//按键标志
uchar k=0;
//数值有误
uchar FW=0;
//头函数
#include <reg52.h>
#include <intrins.h>
#include "BJ_Key.h"                    //报警按键
#include "display.h"                         //显示头函数
#include "ultrasonic_wave.h"//超声波头函数
#include "DS18B20.h"                    //温度传感器头函数
//函数声明
void delayms(uint ms);
//主函数
void main()
{
        Init_ultrasonic_wave();
        //屏幕初始化
        Init1602();
        //温度初始化
        tmpchange();
        t_=tmp();
        tmpchange();
        t_=tmp();
        tmpchange();
        t_=tmp();

        //循环显示
        while(1)
        {
                Key();
                //正常显示
                if(mode==0)
                {
                        StartModule();//启动超声波
                        while(!RX);          //当RX为零时等待
                        TR0=1;                  //开启计数
                        while(RX);          //当RX为1计数并等待
                        TR0=0;                  //关闭计数
        
                        delayms(20);  //20MS
                        tmpchange();  //温度转换
                        t_=tmp();     //度温度
                        Conut(t_/10); //计算距离
                        if(L>Max||L<Min)
                        {
                                Feng_Start();
                        }
                        else
                        {
                                if(FW!=1)
                                Feng_Stop();
                        }
                        Display_1602(t_/10,L);
                }
                //调整显示
                else if(mode!=0)
                {
                        //最大最小值
                        Init_MaxMin();
                        while(mode!=0)
                        {                        
                                Key();
                                if(k==1&&mode==1)
                                {
                                        Init_MaxMin();        
                                   write_com(0x8d);//设置位置                                       
                                }
                                else if(k==1&&mode==2)
                                {
                                        Init_MaxMin();        
                                   write_com(0x8d+0x40);//设置位置        
                                }
                                k=0;
                        }
                        //界面初始化
                        Init1602();
                }}}
void delayms(uint ms)
{
        uchar i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }}}
//T0中断用来计数器溢出,超过测距范围
void CJ_T0() interrupt 1
{
    flags=1;                                                         //中断溢出标志
}


超声波函.h

sbit RX=P2^1;
sbit TX=P2^0;

//超声波初始化
void Init_ultrasonic_wave()
{
         TX=0;                           //关闭发射
         TMOD=0x01;                   //设T0为方式1,GATE=1;
         TH0=0;
         TL0=0;         
         ET0=1;           //允许T0中断
         EA=1;                           //开启总中断        
}

//启动超声波
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 JS_(uchar WD)
{
        //大于-30
        if(WD>=30&&flag==1)
        {
                L=(time*3.13)/200;     //算出来是CM;               
        }
        //大于-20<-30
        else if(WD>=20&&WD<30&&flag==1)
        {
                L=(time*3.19)/200;     //算出来是CM;               
        }
        //大于-10<-20
        else if(WD>=10&&WD<20&&flag==1)
        {
                L=(time*3.25)/200;     //算出来是CM;               
        }
        //大于0<-10
        else if(WD>=0&&WD<10&&flag==1)
        {
                L=(time*3.23)/200;     //算出来是CM;               
        }
        //大于0<10
        else if(WD<=10&&WD>0&&flag==0)
        {
                L=(time*3.38)/200;     //算出来是CM;               
        }
        //大于10<20
        else if(WD<=20&&WD>10&&flag==0)
        {
                L=(time*3.34)/200;     //算出来是CM;               
        }
        //大于20<30
        else if(WD<=30&&WD>20&&flag==0)
        {
                L=(time*3.49)/200;     //算出来是CM;               
        }
        //大于30
        else if(WD>30&&flag==0)
        {
                L=(time*3.86)/200;     //算出来是CM;               
        }
}
//距离计算 SD为当时的超声速度
void Conut(uchar WD)
{
         time=TH0*256+TL0;
         TH0=0;
         TL0=0;
         JS_(WD);

         //距离大于200或者超时
         if(L>450||flags==1)
         {
                flags=0;
                //无效显示
                flag1s=0;
                L=0;
                FW=1;        
                Feng_Start();        
         }        
         //距离小于100
         else if(L<=150)
         {
                flag1s=1;
                FW=1;        
                Feng_Stop();
         }}


DS1820.h

#define uchar unsigned char
#define uint unsigned int
//define interface  定义 DS18B20 接口
sbit DS=P1^4;
//variable of temperature                     
uint temp=0;                        
//延时子函数  
//sign of the result positive or                                 
void delay(uint count)
{   
        uint i;
        while(count)
    {
        i=200;
        while(i>0)
        i--;
        count--;
    } }
//发送初始化及复位信号
void dsreset(void)
{
        //DS18B20 初始化
    uint i;                                 
    DS=0;
    i=103;
    while(i>0)i--;
    DS=1;
    i=4;
    while(i>0)i--;
}
//read a bit  读一位
bit tmpreadbit(void)               
{
      uint i;
      bit dat;
          //i++ for delay    小延时一下  
      DS=0;i++;                    
      DS=1;i++;i++;
      dat=DS;
      i=8;while(i>0)i--;
return (dat);
}
//read a byte date  读一个字节
uchar tmpread(void)      
{
    uchar i,j,dat;
    dat=0;
    for(i=1;i<=8;i++)
    {
        j=tmpreadbit();
                //读出的数据最低位在最前面,这样刚好
                //一个字节在 dat 里
        dat=(j<<7)|(dat>>1);      
    }
        //将一个字节数据返回
    return(dat);                          
}
//write a byte to ds18b20
//写一个字节到 DS18B20 里   
void tmpwritebyte(uchar dat)      
{                                                            
    uint i;
    uchar j;
    bit testb;
    for(j=1;j<=8;j++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)             //write 1       写 1 部分
        {
            DS=0;
            i++;i++;
            DS=1;
            i=8;while(i>0)i--;
        }
        else
        {
            DS=0;              //write 0      写 0 部分
            i=8;while(i>0)i--;
            DS=1;
            i++;i++;
        }
  }
}
//DS18B20 begin change  发送温度转换命令
void tmpchange(void)     
{
    dsreset();             //初始化 DS18B20
    delay(1);              //延时
    tmpwritebyte(0xcc);    //跳过序列号命令
    tmpwritebyte(0x44);    //发送温度转换命令
}
//get the temperature  获得温度
uint tmp()                              
{
    float tt=0;
    uchar a=0,b=0;
    dsreset();
    delay(1);
         //发送读取数据命令
    tmpwritebyte(0xcc);
    tmpwritebyte(0xbe);
         //连续读两个字节数据         
    a=tmpread();               
    b=tmpread();
         //two byte    compose a int variable
         //两字节合成一个整型变量。
    temp=b;
    temp<<=8;   //temp=temp<<=8  左移8位                       
    temp=temp|a;                 
         if(b==0xff)
         {
           flag=1;
           temp=~temp+1;  //负温度表示 取补码
         }
         //得到真实十进制温度值,因为 DS18B20        
    tt=temp*0.0625;               
    //可以精确到 0.0625 度,所以读回数据的最低位代表的是
    //0.0625 度。
         //放大十倍,这样做的目的将小数点后第一位
    temp=tt*10+0.5;      
    //也转换为可显示数字,同时进行一个四舍五入操作。
         //返回温度值
    return temp;           
}  


display.h

sbit LCDRS = P2^7;
sbit LCDEN= P2^6;
//初始画时显示的内容
uchar code Init1[]="Temperature:   C";
uchar code Init2[]="Distance:0000 CM";
//初始画时显示的内容
uchar code Init3[]="  Max------   CM";
uchar code Init4[]="  Min------   CM";
//LCD延时
void LCDdelay(uint z)
{
  uint x,y;
  for(x=z;x>0;x--)
    for(y=10;y>0;y--);
}
//写命令
void write_com(uchar com)
{
  LCDRS=0;
  P0=com;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}
//写数据
void write_data(uchar date)
{
  LCDRS=1;
  P0=date;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}
//1602初始化
void Init1602()
{
  uchar i=0;
  write_com(0x38);//屏幕初始化
  write_com(0x0C);//打开显示 无光标 无光标闪烁
  write_com(0x06);//当读或写一个字符是指针后一一位
  write_com(0x01);//清屏
  write_com(0x80);//设置位置

  for(i=0;i<14;i++)
  {
                write_data(Init1[i]);
  }
        write_data(0xdf);
        write_data(Init1[14]);        
  write_com(0x80+0x40);//设置位置
  for(i=0;i<16;i++)
  {
                write_data(Init2[i]);
  }}
//温度 距离显示
void Display_1602(uchar W,uchar L)
{
        //温度值显示
        write_com(0x80+12);
        write_data('0'+W/10);
        write_data('0'+W%10);

        if(L>=100)
        {
                  write_com(0x80+0x40+0x09);
                  write_data(((L*10)/1000)+0x30);    //百
                  write_data(((L*10)%1000/100)+0x30);  //十
                  write_data(((L*10)%100/10)+0x30);     //个
                  write_data(0x2e);           //点
                  write_data(((L*10)%10)+0x30);  //小数位1
                }
                else if(L>=10 && L<100)
                {
                  write_com(0x80+0x40+0x09);
                  write_data((L*10/100)+0x30);  //十
                  write_data((L*10%100/10)+0x30);     //个
                        write_data(0x2e);           //点
                        write_data((L*10%10)+0x30); //小数位1
                }
                else if(L>=0 && L<10)
                {
                  write_com(0x80+0x40+0x09);
                        write_data((L*10/10)+0x30);  //个
                        write_data(46);           //点
                  write_data((L*10%10)+0x30);     //小数位1
                }
        else if(flag1s==0)
        {
                write_com(0x80+0x40+0x0a);
                write_data('-');
                write_data('-');
                write_data('-');
                write_data('-');
        }}
//1602初始化最大化最小化调整界面
void Init_MaxMin()
{
  uchar i=0;
  write_com(0x38);//屏幕初始化
  write_com(0x0f);//打开显示 无光标 无光标闪烁
  write_com(0x06);//当读或写一个字符是指针后一一位
  write_com(0x01);//清屏
  write_com(0x80);//设置位置
  for(i=0;i<16;i++)
  {
                write_data(Init3[i]);
  }
  write_com(0x80+0x40);//设置位置
  for(i=0;i<16;i++)
  {
                write_data(Init4[i]);
  }
  write_com(0x8b);//设置位置
        write_data('0'+Max/100);
        write_data('0'+Max/10%10);
        write_data('0'+Max%10);
  write_com(0x80+0x40+0x0b);//设置位置
        write_data('0'+Min/100);
        write_data('0'+Min/10%10);
        write_data('0'+Min%10);
  write_com(0x8d);//设置位置        
}


key.h

sbit Feng=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
sbit K3=P1^3;
//蜂鸣打开
void Feng_Start()
{
        Feng=0;
}
//蜂鸣关闭
void Feng_Stop()
{
        Feng=1;
}
//等待
void delay_key()
{
        uchar i,j;
        for(i=0;i<200;i++)
        for(j=0;j<200;j++);
}
//按键检测
void Key()
{
        //功能键按下
        if(K1==0)
        {
                Feng_Start();//蜂鸣器开
                delay_key(); //消抖
                while(K1==0);//等待松手
                Feng_Stop(); //蜂鸣器关闭
                mode++;      //模式++
                if(mode==3)         //达到最大限度归为
                        mode=0;        
                k=1;                         //按键标志位
        }
        //+键
        else if(K2==0)
        {
                Feng_Start();//蜂鸣器开
                delay_key(); //消抖
                while(K2==0);//等待松手
                Feng_Stop(); //蜂鸣器关闭
                //最大值调整
                if(mode==1)  //在最大值调整下
                {
                        Max++;         //调整最大值
                        if(Max==201)//到达201归为200
                        {
                                Max=200;
                        }        
                }
                //最小值
                else if(mode==2)//最小模式下调整
                {
                        Min++;                //调整最小值
                        if(Min>Max) //最小值不能大于最大值
                        {
                                Min=Max;
                        }                                
                }
                k=1;
        }
        //-键
        else if(K3==0)
        {
                Feng_Start();
                delay_key();
                while(K3==0);
                Feng_Stop();
                //最大值调整
                if(mode==1)
                {
                        Max--;
                        if(Max<Min)
                        {
                                Max=Min;
                        }        
                }
                //最小值
                else if(mode==2)
                {
                        Min--;
                        if(Min==0xff)
                        {
                                Min=0;
                        }                                
                }
                k=1;
        }
}
回复

使用道具 举报

ID:913310 发表于 2021-12-7 13:35 | 显示全部楼层
我怀疑是数据类型不对,然后我也试着改了,可能我改的不对,还是不行,呜呜
回复

使用道具 举报

ID:913310 发表于 2021-12-7 21:06 | 显示全部楼层
没人帮帮忙嘛
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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