laizi123 发表于 2011-5-14 21:06:07

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

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






#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uintunsigned 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);
        }
        write_com(0x8a);
        for(t=0;t<4;t++)
        {
          write_date(cent);
        }
}
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);
   write_date(dis[(shu2%100)/10]);
   write_date(dis);
   delay(50);
}
void xianshic()
{
        write_com(0x80+0x49);
        write_date(dis);
        write_date(dis);
        write_date(dis);
        write_date(dis);
        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;                                                                                                               
   }

wangdabo 发表于 2011-11-23 16:22:54

回复【楼主位】laizi123
-----------------------------------------------------------------------
楼主   date+=500   是什么意思 啊
谢谢了

wangdabo 发表于 2011-11-23 17:07:18

没有人回答吗   都忙着呐   谢谢大家了

zhaozhenxingabc 发表于 2017-12-22 12:24:39

wangdabo 发表于 2011-11-23 16:22
回复【楼主位】laizi123
-----------------------------------------------------------------------
楼主 ...

那里补偿了

页: [1]
查看完整版本: 带温度补偿的超声波测距完整程序 分享下