#include "STC15W4K56S4.H"
#include "JLX12864G-086S-ZK.H"
sbit TX=P1^2;
unsigned char temp[16]; //显示变量
unsigned long ju_li; //距离变量
unsigned int shi_cha,haomi; //时差,以毫米为单位的长度
unsigned char xun_huan_ci_shu; //记录主循环循环的次数
sbit RX=P1^0; //接收电路的回波信号
unsigned char X=1;
/***************************************************************
STC单片机IO口初始化函数
注意:主函数最前面一定要记得加该函数,否则许多IO口功能不正常
****************************************************************/
void port_mode()
{
P0M1=0x00;P0M0=0x00;P1M1=0x00;P1M0=0x00;P2M1=0x00;P2M0=0x00;P3M1=0x00;P3M0=0x00;
P4M1=0x00;P4M0=0x00;P5M1=0x00;P5M0=0x00;P6M1=0x00;P6M0=0x00;P7M1=0x00;P7M0=0x00;
}
void CSB_SC(unsigned char geshu) //超声波输出子程序,传递参数:超声波个数
{
do //do-while 循环
{ // 循环开始
TX=0; //P1.0=0
_nop_();_nop_();_nop_(); //3μS 延时
_nop_();_nop_();_nop_(); //3μS 延时
_nop_();_nop_();_nop_(); //3μS 延时
_nop_();_nop_(); //2μS 延时,连同取反2μS共13μS
TX=1; //P1.0=1
_nop_();_nop_();_nop_(); //3μS 延时
_nop_();_nop_();_nop_(); //3μS 延时
_nop_();_nop_(); //2μS 延时
}
while(--geshu); //循环结束,跳转回开始需要 2μS, 共 12μS
TX=0; //结束输出
}
void delay_nus(unsigned int i)
{
while(--i);
}
void T0_INT(void) //初始化子程序
{
TMOD|=0x01; //定时器0工作于16位模式(0-65535)
EA=1; //允许总中断
ET0=1; //允许定时器0中断
}
void ce_ju(void) //测距主程序
{
TH0=0X00; //定时器计数清零(高八位)
TL0=0X00; //定时器计数清零(低八位)
TF0=0; //清溢出标志
TR0=1; //启动定时器开始计时
CSB_SC(20); //立即输出20个周期的超声波
delay_nus(40); //延时一段时间,防止发射波干扰
while(RX&&(TF0==0)); //等待回波信号及溢出信号
//即如果没有收到回波就一直等待下去
//但也不能死等,等待超过65535μS后仍然没有回波就放弃
TR0=0; //收到回波或超时,停止定时器,冻结定时器的值
if(TF0) //判断是否超时(定时器是否溢出)
{ //如果条件成立(确实超过65535μS未收到回波)
X=0;
// display_GB2312_string(3,1,"未接收到");
}
else //未超时并收到回波
{ //未超时,确实在发出超声波65535μS内收到回波
X=1;
shi_cha=TH0*256+TL0; //从定时器中取出计时值,即往返时差
ju_li=170L*shi_cha; //距离=声速×往返时间÷2,即距离=170×往返时差
//得到的距离单位是μM因为定时器计得的时间为微秒
haomi=ju_li/1000; //把得到的距离除以1000,得到以毫米为单位的长度数据
}
}
void main(void)
{
port_mode(); //IO口初始化函数
T0_INT(); //初始化,设置定时器工作模式
initial_lcd(); //LCD模块初始化
clear_screen(); //全屏清屏
while(1)
{
if(X==1)
{
sprintf(temp,"距离:%d",haomi);
display_GB2312_string(3,1,temp);
}
if(X==0)
{
display_GB2312_string(3,1,"未接收到");
}
delay_nus(500);
xun_huan_ci_shu++; //主循环每循环一次,变量加一
if(xun_huan_ci_shu>=5) //每循环5次,就进行一次测距,控制测距间隔时间
{
ce_ju(); //调用测距子程序进行测距
xun_huan_ci_shu=0; //循环计数变量清零
clear_screen();
}
}
}