超声波程序

至此51程序暂时就不发了,后续发32的了。其实超声波程序不想发的,因为网上都有很多成熟的了。HCSR04个人看来是个很垃圾的超声波,很差。

题外话我们电赛前准备了KS103超声波(虽然没有用到,我们用了另一种,可实现误差2mm以内,有些溶液会有些大误差,需要代码自行补偿)

//Trig  = P1^0
//Echo  = P3^2
/***********************************************************************************************************/	    
#include 
#include 

#define LCD_data  P0             //数据口
#define uint unsigned int
#define uchar unsigned char

//***********************************************
    sbit     RX    =  P1 ^ 6;
    sbit     TX    =  P1 ^ 7;
unsigned int  time=0;
         long S=0;
         bit  flag =0;
unsigned char disbuff[4]	   ={ 0,0,0,0,};

bit succeed_flag;  //测量成功标志		 
sbit E  =  P3^4;      //使能端  
sbit RS  =  P3^5;     //命令/数据选择       
sbit RW  =  P3^6;     //读写口      
sbit PSB =  P3^7;     //串并选择   

uchar code num[]={"0123456789 e:.-"};
			 

void delay(uint z)
{
	uint x,y;
for(x=z; x>0; x--)
  for(y=920; y>0; y--);                         
}

//////////////12864///////////////////////
bit busy()  //查忙
{
	bit result;
	P0=0X00; 
	RS=0;			//命令/数据选择,为0时选择命令    
	RW=1;			//读/写选择,为1时选择读
	E=1;			//使能
	delay(1);
	result = (bit)(P0&0x80); //查忙标志位,等待标志位为0,即表示写入完毕
	E=0;			//关闭读写 
	return (result);
}
void wcode(uchar cmd)   //向lcd写一命令
{
	while(busy());  					 //查忙
	RS=0;							 //命令/数据选择,为0时选择命令 
	RW=0;							 //读/写选择,为0时选择写
	E=0;
	_nop_();
  _nop_(); 
	P0=cmd;				 //送入命令
	delay(1);				//等待
	E=1;							
	delay(1);
	E=0;
}

void wdata(uchar dat) 	//向LCD写一数据
{
	while(busy());
	RS=1;            //H为数据
	RW=0;
	E=0;
	P0=dat;
	delay(1);
	E=1;
	delay(1);
	E=0;
}

void initlcd()    //LCD初始化
{
	PSB=1;     //设置为8BIT并口工作模式  H并行 L串行
	delay(10);
	wcode(0x34);
	delay(5);
	wcode(0x30);  //选择基本指令集
	delay(5);
	wcode(0x0c);  //开显示,无游标
	delay(5);
	wcode(0x01);	//清除显示,并且设定地址指针为00H
	delay(5);
	wcode(0x06);	//指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
}
void Delay20us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 52;
	while (--i);
}

void dis(uchar x,uchar y,uchar code *s)  //任意位置显示字符串
{                         //x为横坐标,y位纵坐标,*s表示指针,为数据的首地址
	switch(y)    						//选择纵坐标
	{
		case 0:wcode(0x80+x);break;  //第一行
		case 1:wcode(0x90+x);break;	 //第二行
		case 2:wcode(0x88+x);break;  //第三行
		case 3:wcode(0x98+x);break;  //第四行
		default:break;
	}
	while(*s>0)										 //写入数据,直到数据为空
	{
		wdata(*s);									 //写数据
		delay(10);									//下一字符
		s++;
	}
}  

void wrnum(uchar s)
{
	wdata(num[s]);
	delay(1);
}

 
  void Conut()
	{
	   time=TH0*256+TL0;
	   TH0=0;
	   TL0=0;
	   S=time*1.87/100;       //算出来是CM	  11。0592M晶振
//	   if(flag==1)		      //超出测量
//	  {	 
//	   flag=0;
//			dis(0,0,"距离超出范围");
//	  
//	   }
//	 else
//	  {
			dis(0,0,"距离:");
	   disbuff[1]=S%1000/100;
	   disbuff[2]=S%1000%100/10;
	   disbuff[3]=S%1000%10 %10;
	 
	   wrnum(disbuff[1]);
	   wrnum(13);
	   wrnum(disbuff[2]);
	   wrnum(disbuff[3]);
		 wdata('m');
//	  }
	}
	
	  void zd0() interrupt 1 		 //T0中断用来计数器溢出,超过测距范围
  {
    flag=1;							 //中断溢出标志
  }
/********************************************************/
   void  StartModule() 		         //T1中断用来扫描数码管和计800MS启动模块
  {
	  TX=1;			                 //800MS  启动一次模块
		Delay20us();
	  TX=0;
  }
/********************************************************/
void main(void)
{  
    TMOD=0x01;		   //设T0为方式1,GATE=1
	TH0=0;
	TL0=0; 
	TR0=1; 

	initlcd();       //设置液晶显示器

	while(1)
	{
	 StartModule();	 
	 		        	//计算
	 while(!RX);		//当RX为零时等待
	 TR0=1;			    //开启计数
	 while(RX);			//当RX为1计数并等待
	 TR0=0;				//关闭计数
	 Conut();
	 delay(80);		//80MS

	}
}             

 

你可能感兴趣的:(单片机程序)