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

来源:互联网 发布:usb2.0高速端口 编辑:程序博客网 时间:2024/05/02 00:17

 


程序如下

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;                       
}


这是我们大三时候的课程设计,现在拿出来和大家分享,希望对各位朋友有帮助!











0 0
原创粉丝点击