在CT107D开发板内,协同超声波一同使用的芯片是CX20106A,其中关于超声波模块的布线,如果要启动此模块的话,需要将跳线帽切换至1-3脚相连,2-4脚相连。这样在物理连接上,超声波模块可以正常使用。
完成物理上的连接更换后,我们接下来的是要明白超声波的使用原理,和如何程序设计,使其实现。
1.超声波使用原理概括
CT107D开发板上分别有发射声波模块和接收声波模块。发射模块,通过P10(A),发射8至15个频率大致40KHZ的方波(用周期来算,也就是25us左右的方波),程序中我将采取为20us的方波放送。
方波发送之后,会遇到前方的障碍,然后返回,被接收模块对应 管脚P11(B)接受。在方波发送后,接受模块还未接收到方波之前,P11管脚始终处于高电平状态,直到接收到方波后,才变为低电平。
2.所需模块讲解
在分析代码之前,我们来捋一捋所需要的其他模块。
(1)定时器:用超声波测距,我们需要知道来回所需的时间,这样好求出距离。也就是需要用到定时器一个,同样因为需要模拟发送声波,所以,我们还需借用一个定时器来发送方波。
(2)数码管:数码管是用来显示距离的最直观的模块,该模块不用,如何知道测量距离和真实距离的误差,如何验证代码正确?
除了超声波模块,所用的基础模块也就这两个,下面我将手把手的讲解:
3.代码分析
首先需要包含对应的头文件,其次定义好超声波发送口和接收口管脚名,便于后面操作。还有就是超声波多久发送一次的标志wave_flag,还有存储距离的变量distance。
初始化定时0和定时1,选用16位自动重装工作模式。其中定时器1用来计时。
#include <STC15F2K60S2.H>
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit TX=P1^0; //超声波发送口
sbit RX=P1^1; //超声波接收口
uchar wave_flag; //定义扫描标志
uchar code smg_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar disp[4];
uint distance;
/*定时器初始化*/
void time0_init()//定时器0初始化
{
TMOD|=0x00;//16位
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TH1=0;
TL1=0;
TF1=0 ;
ET0=1;
EA=1;
TR0=1;
}
模拟方波,需要先设置相对的延时。
/*10us的延时程序*/
void delay10us() //@12.000MHz
{
uchar i;
_nop_();
_nop_();
i = 33;
while (--i);
}
设置超声波发送函数模块,注释里面有详细解释。
void send_wave()//发送超声波函数
{
uchar i=8; //发送8个周期为20us的方波
do
{ TX=1;
delay10us(); //高电平10us
TX=0;
delay10us(); //低电平10us
}
while(i--);
}
后面部分内容,包含数据处理,数码管显示
void data_process(uint k)//数据处理
{
disp[0]=k%10;//个位
disp[1]=k%1000%100/10;
disp[2]=k%1000/100;
disp[3]=k/1000;//千位
}
void smg_disp()
{
static uchar temp=0;
P2=(P2&0x1f)|0xc0;
P0=0x08>>temp;
P2&=0x1f;
P2=(P2&0x1f)|0xe0;
P0=smg_duan[disp[temp]];
P2&=0x1f;
if(++temp==4) temp=0;
}
主函数部分,每次等到wave_flag为1时,发送声波,声波发送完后,再开启T1定时器计数。一直等待声波被接收模块接收,确认声波是否接受的标志有两个,一个是RX由高电平变为低电平,另一个是T1的中断溢出标志为1,(超过计数范围)退出循环判定条件。
而当接收当声波后,需要将T1定时器关闭,停止计数。将TH0和THL内的数进行处理,放在一个较长字节的数内。根据时间*速度的公式进行处理,切记路程是来回两个距离,需要除2。
本程序中,因为使用cm为单位,所以是乘0.017。
void main()
{
time0_init();
while(1)
{ if(wave_flag)
{
wave_flag=0;
send_wave();
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1==1) {
TF1=0;distance=9999;
}//超出范围
else{
distance=TH1;
distance<<=8;
distance|=TL1;
distance = (uint) (distance*0.017);
}
data_process(distance);
TH1=0;
TL1=0;
}
}
}
void time0() interrupt 1//T0中断入口
{
static uint i;
smg_disp();
if(++i==1000)
{wave_flag=1;
i=0;
}
}
谢谢查看,如有错误,欢迎指正。