您的位置:首页 > 其它

基于89C51单片机的超声波测距系统设计与制作

2014-04-29 11:34 621 查看
 




程序如下

main.c

/*********************************************************************/

/*              超声波测距数码管显示                                 */

/*********************************************************************/

/*  温度补偿                                                         */

/*  用定时器0计数测量超声波发送接收时间                              */

/*  用定时器1给ds18b20定时发收温度信号                               */

/*  用外部中断0接收超声波返回的第一个脉冲                            */

/*********************************************************************/

#include<reg52.H> 

#include<intrins.h>

#include<wen.h>

#include<chao.h>

/*********************************************************************/

extern uint dis;

/*********************************************************************/

/***********************************/

/*        主函数     */

/***********************************/ 

void main(void) 


init(); 

// display(1234);

// delayms(100); 
while(1)           //循环测量并显示 

tran();        //发送超声波信号测距 
display(dis);  //显示距离
delayms(100); 

// wen();
  //显示温度 


}

chao.c文件

#include<reg52.H> 

#include<intrins.h>

#include<wen.h>

#include<chao.h> 

/*********************************************************************/

uint dis;

uint H=100;

uint L=20; 

uchar flag=0;    //中断标志

uchar high_time;   //时间高位

uchar low_time;    //时间低位

uchar i,s1num;

/*************************** 

数码管为共阴数码管 

***************************/ 

#define seg P0   //数码管的数据口为P0口 

sbit s3=P2^0;  

sbit s0=P2^1;     

sbit s1=P2^2;   

sbit s2=P2^3; 

sbit dp=P0^7;    //小数点 

uchar shuzu[]={  

0x3F, //"0" 

0x06, //"1" 

0x5B, //"2" 

0x4F, //"3" 

0x66, //"4" 

0x6D, //"5" 

0x7D, //"6" 

0x07, //"7" 

0x7F, //"8" 

0x6F, //"9" 

/*0x77, //"A" 

0x7C, //"B" 

0x39, //"C" 

0x5E, //"D" 

0x79, //"E" 

0x71, //"F" 

0x76, //"H" 

0x38, //"L" 

0x37, //"n" 

0x3E, //"u" 

0x73, //"P" 

0x5C, //"o" 

0x40, //"-" */

0x00, //熄灭 

0x00  //自定义   

}; 

/*********************************************************************/

/***********************************/

/*       初始化函数     */

/***********************************/  

void init(void) 


TMOD=0x11;  //定时器0方式1用于计时 
TH0=0; 
TL0=0;
TH1=(65536-60000)/256;    //温度计时初值     
TL1=(65536-60000)%256;
ET1=1;                           //开定时器1中断
TR1=1;                            //启动定时器1   
EA=1; 
IT0=1;  //下降沿有效



/***********************************/

/*       显示函数         */

/***********************************/ 

void display(uint dat) 


uchar i,j,k,l;  //分别为百十个位的缓存
dat=dat-70;
i=dat/1000;     //百位 
j=dat/100%10;   //十位 
k=dat/10%10;    //个位
l=dat%10;       //十分位

// write_12864com(0x8b);

// write_12864dat(table[i]);

// delay_50us(1);

// write_12864dat(table[j]);

// delay_50us(1);

// write_12864dat(table[k]);

// delay_50us(1);

// write_12864dat(table[10]);

// delay_50us(1);

// write_12864dat(table[l]);

// delay_50us(1);
s3=1;
s2=0;
s1=1;
s0=1; 
seg=~shuzu[i]; 

// dp=0; 
delayms(2); 

// dp=1; 
s2=1; 
s3=1;
s2=1;
s1=0;
s0=1; 
seg=~shuzu[j]; 
delayms(2); 
s1=1; 
s3=1;
s2=1;
s1=1;
s0=0; 
seg=~shuzu[k];
dp=0; 
delayms(2); 
dp=1;
s0=1; 

    s3=0;
s2=1;
s1=1;
s0=1; 
seg=~shuzu[l];

// dp=0;  
delayms(2);

// dp=1;  
s3=1; 



/***********************************/

/*       超声波测量函数        */

/***********************************/

void tran(void) 


uchar i; 
float temp; 
TH0=0; 
TL0=0;    //清定时0 
TR0=1;    //开定时0
flag=0;
for(i=8;i>0;i--) 

csb=!csb;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop; 
nop; 
nop; 
nop;
nop; 
nop;
nop; 
nop;
nop;
nop;
nop;
nop;
nop;

}    
csb=1; 
delayms(50);
EX0=1;        //开中断

// if(flag!=1)

// {

// dis=55;

// } 
if(flag==1)   //中断标志位置1,说明有回波 
{             //以下为路程计算 
temp=high_time*256+low_time; 
temp=(temp/100.0)/2.0;  
temp*=331.45+0.607*30; //温度补偿V=331.45+0.607*T(温度)
// temp*=350+0.607*(gett()/100.0); 
temp=temp/10.0;
dis=temp;
 
flag=0; 


}

/***********************************/

/*       中断函数             */

/***********************************/  

void TT() interrupt 0 


float tmp; 
TR0=0;     //关定时器0 
ET0=0;     //关外部中断 
flag=1;    //置位标志位 
tmp=TH0*256+TL0;         //读取定时器的值 

// if((tmp>0)&&(tmp<30000)) //判断是否超出范围,此设置的范围为0到5米
if((tmp>0)&&(tmp<=60000))

high_time=TH0;       //把计时值放入缓冲 
low_time=TL0; 

else         //超出范围则重新测量 

high_time=0; 
low_time=0;  
}  



wen.c文件

#include <reg52.h>

#include <wen.h>

#include"chao.h"

/***********************************************************************************/

uchar8 dis1[6] = { 0, 0, 0, 0, 0, 0 }; //数据暂存

uchar8 code wendu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};  //0到9的代码

uchar8 flag1,sig,temp1;    //flag用于判定是否有中断,sig判定温度符号

/***********************************************************************************/

/********************************/

/*         延时函数             */

/********************************/

void delay(int us)  //DELAY-11.0592MHZ 调用程序大约为24us,每次循环为16us

{
int s;
for(s=0;s<us;s++);

}

/********************************/

/*         毫秒延时             */

/********************************/

void delayms(int z)

{
int x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);

}

/********************************/

/*         复位程序             */

/********************************/

unsigned char reset(void)

{
uchar8 presence;
DQ=0;  //拉低总线。当总线停留在低电平480us-960us ,总线上所以器件都将被复位
delay(30);
 //保持低电平504us
DQ=1;  //释放总线,让其恢复高电平
delay(3);
 //等待芯片应答信号
presence=DQ;
 //获取应答信号
delay(25);
 //延时以完成整个时序
return(presence);//返回应答信号。有芯片应答返回0,否则返回1。

}

/********************************/

/*        写一位数据            */

/********************************/

void write_bit(char bitval)

{
DQ=0;   //拉低DQ总线,开始时序
if(bitval==1)  //如果写入的为1,则返回高电平
DQ=1;
delay(5);  //延时104us,以完成整个时序
DQ=1;  

}

/********************************/

/*       写一字节数据           */

/********************************/

void write_byte(char val)

{
uchar8 i,commend;
for (i=0;i<8;i++)    //写入一个字节的数据,一个时序中写一次
{
commend=val>>i;     //右移i位
commend&=0x01; //复制那位数据到temp
write_bit(commend);  //调用write_bit()
}
delay(5);
 //延时104us以完成此次时序,之后再写下一数据

}

/********************************/

/*       读一位数据             */

/********************************/

unsigned char read_bit(void)

{
uchar8 i;
DQ=0;   //拉低DQ,开始读时序
DQ=1;   //释放DQ总线  
for(i=0;i<3;i++);//从时序开始延时15us

    return(DQ);  //返回DQ值

}

/********************************/

/*     读一字节数据             */

/********************************/

unsigned char read_byte(void)

{
uchar8 i,value=0;
for(i=0;i<8;i++)
{
if(read_bit())  //读一字节数据,一个时序中读一次,并作移位处理
value|=0x01<<i;
delay(6);
//延时以完成此次读时序,之后再读下一数据
}
return(value);

}

/********************************/

/*     温度转化                 */

/********************************/

void tmconvert(void)

{
reset();
 //复位
delay(1);
write_byte(0xcc); //仅一个DS18b20 ,跳过ROM
write_byte(0x44);  //温度变换

}

/********************************/

/*     读取温度                 */

/********************************/

unsigned int gett()

{
uchar8 LSB=0,MSB=0; //用于存储读取的温度
long temp;
 
reset();
  //复位
write_byte(0xcc);  //写指令,跳过ROM,仅一个DS18b20
write_byte(0xbe);  //写指令,读暂存存储器
LSB = read_byte();  //读LSB
MSB = read_byte();    //读MSB
sig=(MSB>>4==0X0F);
if(sig)                   //判断符号位是否为负值,是负值了,转去处理

    {   

      LSB=~LSB;                 //温度处理
    MSB=~MSB;
    LSB=LSB+1;
}
temp=MSB*256+LSB;   //十六进制转换为10进制
temp=temp*100/16;   //12位精度,最小分辨率为0.0625°C
return temp; 
       //获得0.01°C 的精度并返回

}

/********************************/

/*     温度处理                 */

/********************************/

void display1(unsigned int m)    

{

    uchar8 i;           //分离各数位
dis1[1] = m/10000;  //百位
  
dis1[2] = (m%10000)/1000;  //十位
dis1[3] = (m%1000)/100;  //个位
dis1[4] = (m%100)/10;  //小数第一位

dis1[5] = m%10;  //小数第二位

delayms(30);

      

// write_12864com(0x9b); //0x80+地址码,设置数据地址指针(显示 第一行:0-0fH,第二行:40-4fH;)

// if(sig) write_12864dat(table[11]);//如果sig=1,显示负号;否则显示正号

// else write_12864dat(table[12]); 

// for(i=1; i<6; i++)

// {

//// write_12864dat(table[dis1[i]]);//显示温度

//// if(i==3) write_12864dat(table[10]); //显示小数点  
     

//     }

}

/********************************/

/*     温度显示函数             */

/********************************/

void wen(void)

{

    char i;
if(flag1==1)    //是否有中断产生
{
flag1=0;     
  //中断标志位清零
tmconvert();
  //开始温度转化
gett();
  //读取温度
for(i=0;i<30;i++)
display(gett());  //显示温度  

    }

}

void timer0() interrupt 3   //定时器0 中断

{   
TH1 =(65536-60000)/256;         
TL1 =(65536-60000)%256;
flag1=1;                       

}

这是我们大三时候的课程设计,现在拿出来和大家分享,希望对各位朋友有帮助!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  超声波