⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srf25.c

📁 超声波测距软件:单片机采用STC2052,误差小于1CM
💻 C
字号:
#include <intrins.h>
#include <reg51.h>

#define uint  unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define nop()  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

sbit Fout=P1^6;//40kHZ
sbit Damp=P3^3;//阻尼
sbit Block=P3^4;//封锁
sbit Led_seg=P1^1;
sbit Led_rclk =P1^0;
sbit Led_srclk=P3^7;
sbit DQ =P1^7;   //定义通信端口

const char tab[]=	//定义LED数码管显示数字.常量(不带点)
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
				  0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//0-9,-,全灭 0-9带小数点  共阳数码管

float Distance;//距离
uint Time;
uchar wd;//存储计时器高位,低位
uchar ReceiveOk=0,flag=0;
void Init();//初始化
void Delay(uchar t);
void Send();//发射声波
void Receive();//接收外部中断程序
void Display(uint x);//显示程序
void Disp(void);
float ReadTemperature(void);
void WriteOneChar(uchar dat);	
uchar ReadOneChar(void);
void Init_DS18B20(void);
void delays(uint i);

//-----------------------主程序-------------------------------
void main(void)
{   
    uchar j, k;
	TMOD=0x01;	 	//计数器1模式1
    IE=0x00;
//	PX0=1; 		 	//INT0高优先级
    TF0=0;
	IT0=0; 		 	//INT0下降沿触发0
	wd=ReadTemperature();//读温度
	while (1)
	{  
		   Send();
		   for(j=0;j<5;j++) Delay(250);
           IT0=1; 		 	//INT0下降沿触发0
		   while(1)
               { 
			   if(ReceiveOk==1)
				    {
					 ReceiveOk=0;
					// Distance=(331.5+0.6*wd)*Time/20000;//89C2051
                     Distance=(331.5+0.6*wd)*Time/29000;//STC2051
                     Display((int)(Distance));
	      			 break;	
        	     	}
        	   if(flag==1)
        	     	{
					flag=0; 
					TF0=0;
					Distance=0;
        	     	Display(0);
        	     	break;
        	     	} 
			   Delay(250);
        	   }
        	for(k=0;k<100;k++) Delay(250);

	}		
}

//------------------------延时函数----------------------------
void Delay(uchar t)
{
uchar i,j=0xff;
for(i=0;i<t;i++)
    {
    for(j=0x19;j>0;j--);
    }
}
//------------------------40KHZ超声波发射----------------------------
void Send()
{
	uchar counter;
	IE=0x00;
	IT0=0; 		 	//INT0下降沿触发0
	Damp=0;     //关阻尼
	Block=0;    //开始封锁 低电平9012导通
    Fout=0;
	TH0=0;
	TL0=0;      //计数器清零
	TR0=1;      //启动计数器1;
for (counter=0;counter<20;)
		{
     	  nop() nop() nop() nop() nop() nop() 
     	  nop() nop() nop() nop() nop() nop()
     	  nop() nop() nop() nop() nop() nop()
     	  nop()
     	  counter++;
		  Fout=!Fout;
		}
	Damp=1; 	//开阻尼    9014高电平导通
	Block=1;	//解除封锁  9012高电平关断
	EX0=1;      //外部中断0允许
	ET0=1;      //定时器0溢出允许
	EA=1;
}

void Out595(void)
 {
 	Led_rclk=0;
	nop() 
	Led_rclk=1;
}
 
 void Sendbyte(uchar byte)
{
     uchar data count;
     uchar num;
     num=tab[byte]; 
	for(count=0;count<=7;count++)
   		{
    		 Led_srclk=0;
    		 if((num&0x80)==0x80)         //*最高位为1,则向SDATA_595发送1*/
       		 		Led_seg=1;            //*发出数据的最高位*/
     			else  
        			Led_seg=0;    
    				num<<=1;              //*右移位*/
    				Led_srclk=1;          //*产生上生沿*/    
    	}    
 }

void Display(uint x)
{
 	uchar a,b,c;
		a=x%10;
 		b=x/10%10;
 		c=x/100%10;
			Sendbyte(a);
			Sendbyte(b);
			Sendbyte(c+0x0b);
			   Out595();
}
//--------------------外部中断接收程序-------------------------
void Receive() interrupt 0 //外部中断INT0
{
	TR0=0;
	IE=0x00;	//关中断
	Time=TH0*256+TL0;
	ReceiveOk=1;	
}
void Overtime() interrupt 1 //定时器0溢出
{
 TR0=0;
 IE=0x00;	//关中断
 flag=1;
}
//读取温度
float ReadTemperature(void)
{
   uchar a=0;
   uchar b=0;
   uint t=0;
   float tt=0;
   Init_DS18B20();
   WriteOneChar(0xCC); // 跳过读序号列号的操作
   WriteOneChar(0x44); // 启动温度转换
   Init_DS18B20();
   WriteOneChar(0xCC); //跳过读序号列号的操作
   WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
   a=ReadOneChar();
   b=ReadOneChar();
   t=b;
   t<<=8;
   t=t|a;
   tt=t*0.0625;
   return(tt);
}

//写一个字节
void WriteOneChar(uchar dat)
{
  uchar i=0;
  for (i=8; i>0; i--)
   {
     DQ = 0;
     DQ = dat&0x01;
     delays(5);
     DQ = 1;
     dat>>=1;
   }
  delays(4);
}

//读一个字节
uchar ReadOneChar(void)
{
  uchar i=0;
  uchar dat = 0;
  for (i=8;i>0;i--)
   {
     DQ = 0; // 给脉冲信号
     dat>>=1;
     DQ = 1; // 给脉冲信号
     if(DQ)
      dat|=0x80;
     delays(4);
   }
  return(dat);
}

//初始化函数
void Init_DS18B20(void)
{
  uchar x=0;
  DQ = 1;      //DQ复位
  delays(8);  //稍做延时
  DQ = 0;     //单片机将DQ拉低
  delays(80); //精确延时 大于 480us
  DQ = 1;     //拉高总线
  delays(14);
  x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  delays(20);
}
//延时函数
void delays(uint i)
{
 while(i--);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -