带温度补偿的超声波测距完整程序 分享下

2020-01-14 18:58发布

嘿嘿,调了好几天终于弄好了      程序如下






#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
uchar dis[]="0123456789";
sbit rs=P1^0;
sbit lcden=P1^2;
sbit rw=P1^1;
sbit tx=P1^4;
sbit DQ=P1^3;
sbit in=P3^2;
uchar k,d;
uint date,ju,jl,O;
uchar time;
uchar TH,TL,TZ;
uchar dis1[]={"0123456789-"};
uchar temp[]={"WENDU:"};
uchar cent[]={"Cent"};
void delay(uint z)
{
   uint x,y;
     for(x=z;x>0;x--)
          for(y=110;y>0;y--);
}
void delaynus(uint n)
{
   while(n--);
}
void write_date(uchar date)
{
        rs=1;
        lcden=0;
        P0=date;
        delay(1);
        lcden=1;
        delay(1);
        lcden=0;       
}
void write_com(uchar com)
{
        rs=0;
        lcden=0;
        P0=com;
        delay(1);
        lcden=1;
        delay(1);
        lcden=0;       
}
void write(uchar *p)
{
    while(*p)
   {
    write_date(*p);
    p++;       
        }
}
bit initb(void)       
{
bit flag;         //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在
DQ = 1;           //先将数据线拉高
for(time=0;time<2;time++) //略微延时约6微秒
     ;
DQ = 0;           //再将数据线从高拉低,要求保持480~960us
for(time=0;time<200;time++)  //略微延时约600微秒
     ;         //以向DS18B20发出一持续480~960us的低电平复位脉冲
DQ = 1;           //释放数据线(将数据线拉高)
  for(time=0;time<10;time++)
     ;  //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag=DQ;          //让单片机检测是否输出了存在脉冲(DQ=0表示存在)      
for(time=0;time<200;time++)  //延时足够长时间,等待存在脉冲输出完毕
      ;
return (flag);    //返回检测成功标志
}
void init1()
{
    rw=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
//        write_com(0x02);
        write_com(0x80+0x40);
        write("Distance");         
}
void xianshi()
{
           uchar t;
        write_com(0x80);
        for(t=0;t<5;t++)
        {
          write_date(temp[t]);
        }
        write_com(0x8a);
        for(t=0;t<4;t++)
        {
          write_date(cent[t]);
        }
}
uchar readonechar(void)
{
                uchar i=0;       
                uchar dat;  //储存读出的一个字节数据
                for (i=0;i<8;i++)
                 {
                  
                   DQ =1;       // 先将数据线拉高
                   _nop_();            //等待一个机器周期         
                   DQ = 0;      //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
                   _nop_();     //等待一个机器周期                  
                   DQ = 1;     //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
                  for(time=0;time<2;time++);    //延时约6us,使主机在15us内采样
                                 dat>>=1;
                   if(DQ==1)
                      dat|=0x80;  //如果读到的数据是1,则将1存入dat
                        else
                                dat|=0x00;//如果读到的数据是0,则将0存入dat
                     //将单片机检测到的电平信号DQ存入r       
                   for(time=0;time<8;time++);              //延时3us,两个读时序之间必须有大于1us的恢复期       
            }                            
         return(dat);    //返回读出的十六进制数据
}
void writeonechar(uchar shu0)
{
   uchar j;
   for(j=0;j<8;j++)
   {
     DQ=1;
         _nop_();
         DQ=0;
         DQ=shu0&0x01;                  //并将其送到数据线上等待DS18B20采样
         delaynus(20); //延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
         DQ=1;
         delaynus(3);    //延时5us,两个写时序间至少需要1us的恢复期
         shu0>>=1;       
   }
     delaynus(12);           // 稍作延时,给硬件一点反应时间
}
void readyread()                  //做好读温度的准备
{
  initb();
  writeonechar(0xcc);           // 跳过读序号列号的操作
  writeonechar(0x44);           // 启动温度转换         
  delay(200);              //转换一次需要延时一段时间
  initb();
  writeonechar(0xcc);                    
  writeonechar(0xBE);
}
void xianshiwen(uchar shu2)
{
   write_com(0x86);
   write_date(dis[shu2/100]);
   write_date(dis[(shu2%100)/10]);
   write_date(dis[shu2%10]);
   delay(50);
}
void xianshic()
{
        write_com(0x80+0x49);
        write_date(dis[jl/1000]);
        write_date(dis[jl/100%10]);
        write_date(dis[jl%100/10]);
        write_date(dis[jl%10]);
        write_date('m');
        write_date('m');
}
void init()
{
  IT0=0;                            //外部中断低电平触发
  TMOD=0X21;
  TH0=0x00;
  TL0=0x00;
  TH1=TL1=0xfc;          
  EA=1;
  ET0=1;
  ET1=1;
// TR1=1;                      
}
void init2()
{
   //T2CON=0x0c;
   RCAP2H=(65536-5)/256;
   RCAP2L=(65536-5)%256;
   TH2=(65536-5)/256;
   TL2=(65536-5)%256;
   EA=1;
   ET2=1;
   TR2=1;
  // PT2=1;                                                //T2设为高优先级
}
void main()
{       
   init1();                                          //液晶初始化
   xianshi();                                                        //温度字母
   init2();                                   //T2初始化
   tx=0;                      
   IT0=0;                            //外部中断低电平触发
   init();                                                //定时器初始化
   while(1);                                                          
}                 
void timer1() interrupt 3
{
   tx=~tx;
   k++;
   if(k==3)
   {
     k=0;
         TR0=0;
         TR0=1;
         delaynus(6);          //除共振
         EX0=1;
         //for(d=0;d<3;d++);
        // in=0;
   }
}
void int0() interrupt 0
{
   IE0=0;                //中断触发位
   EX0=0;                //关中断
   TR1=0;
   ET1=0;
   TR0=0;
   ET0=0;
   date=TH0*256+TL0;
   date+=500;
   if(TZ>=0&&TZ<=10)
   {
   jl=(date*0.161);
   }
   if(TZ>10&&TZ<=20)
   {
     jl=(date*0.169);
   }
    if(TZ>20&&TZ<=30)
   {
     jl=(date*0.172);
   }
    if(TZ>30&&TZ<=40)
   {
     jl=(date*0.174);
   }
    if(TZ>40&&TZ<=500)
   {
     jl=(date*0.175);
   }
   xianshic();
   for(d=800;d>0;d--);
   TH0=0x00;
   TL0=0x00;
   ET1=1;
   TR1=1;   
   O++;
   if(O==100)
   {
     O=0;
         TR1=0;
         ET1=0;
     TR2=1;
         ET2=1;
   }                                                                                
}
void timer0() interrupt 1                                 //计时
{       
    TR1=0;
    TR0=0;
    TH0=0X00;
        TL0=0X00;
    TR1=1;
}
void timer2() interrupt 5
{
     TF2=0;
         EXF2=0;
         TR2=0;
         ET2=0;
        // xianshi();                                                        //温度字母
         readyread();
     TL=readonechar();
         TH=readonechar();
         TZ=TH*16+TL/16;
         xianshiwen(TZ);
         delay(10);       
         TR1=1;       
         ET1=1;                                                                                                                 
   }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。