上学期做过的开始实验就是关于超声波的……虽然自己拿单片机没搞出来,但好在队友给力,换了主板搞了出来,不过主要还是当时的水平确实太菜了,现在大概知道当时的AD转换混乱的原因了,应该是没有加延时。这次蓝桥杯的题目中有从EEPROM中读数据,如果连续读不同地址,一定要加延时,不然会混乱,我估计当时也应该是这个原因,等空了试试看……
回归正题,首先看发射模块
加了一堆反相器,据说是为了增大功率?反正换能器只要给他8个脉冲就可以发射超声波了……

当 CX20106A 接收到40KHz的信号时,会在第7脚产生一个低电平下降脉冲,这个信号可以接到单片机的外部中断引脚作为中断信号输入。
故发射超声波后打开定时器,检测到低电平关闭定时器即可得到时间

JUMP6为相关接口,实现超声波测距应接13,24
下面是具体的代码实现

//发射超声波
void Send_wave()
{
	uchar i;
	for(i=0;i<8;i++)
	{
		Tx=1;
		Delay10us();		//延时函数,可从ISP中得到
		Tx=0;
		Delay10us();
	}
}

//定时器0初始化,主要控制1s的产生
void Timer0_Init()
{
	TH0=(65535-50000)/256;
	TL0=(65535-50000)%256;
	EA=1;
	ET0=1;
	TR0=1;
}

//定时器0的中断服务函数
void Timer0_Service() interrupt 1
{
	Timer0_count++;
	if(Timer0_count==20)	//每一秒测一次距离
	{
		Timer0_count=0;
		Distance_measure();
	}
}

//定时器1的初始化
void Timer1_Init()
{
	AUXR=0x00;
	TMOD=0x00;
	TH1=0;
	TL1=0;
	ET1=0;					//关闭定时器1的中断使能	
	EA=1;
	TR1=0;
}

//距离的检测
void Distance_measure()
{
	uint t;
	Send_wave();
	TR1=1;
	while((Rx==1)&&(TF1==0));			//溢出了或者检测到低电平关闭定时器1
	TR1=0;
	if(TF1==1)
	{
		TF1=0;
		distance=999;
	}
	else
	{
		t=TH1;					//distance为uint型
		t=t<<8;
		t=t|TL1;			//距离的计算,记得除2
		distance=(uint)(t*0.017);
	}
	TH1=0;
	TL1=0;
}

不知道是不是换能器或者芯片的原因,最多只能检测到7cm……
代码应该没错吧……

已更正

1、发射超声波时,采用10us的延时
2、计算距离时,定义一个uint型的中间变量,并做防溢出处理

经测试,可以测量到127cm左右