基本知识
JUMP6是一个超声波和红外切换的跳帽,1-3 2-4是超声波,3-5 4-6是红外。红外不考,拿到板子之后,跳帽也不需要动。
74LS04是一个非门,为的是增加单片机的驱动能力。
超声波测距步骤:
跳线帽放在Sonic处(1-3 2-4)
P10发送40KHZ的方波(CX20106A只接收40KHZ方波),并开始计时
P11读取低电平,结束计时,得到时间T
距离等于声速*超声波发出到接收的时间除以2(发出去和回来,是两端距离)
根据胜诉V=340m/s,算出距离D=V*T/2=T*170(D单位是m,T单位是s)
ps:定时器2用来产生中断,定时器0用来NE555计数,剩下定时器1 用来超声波计时
程序控制
15系列单片机为了兼容8051单片机,定时器0、定时器1、定时器2分为后是传统得8052得速度,即12分频,所以12MHZ进行12分频之后为1MHZ,所以每经过1微秒,计数器+1,所以定时器1不需要进行配置,只需要对TL1,TH1进行赋初值和清零操作和开关定时器1就可以了。
编程思路:
编程实现P10输出40KHZ的方波(推荐发送8个方波,保证CX20106A一定能接收到方波)
清零TL1和TH1,并启动定时器1
等待P11接收到低电平
关闭定时器1,并根据TL1和TH1的值,计算出距离
#include "Sonic.h"
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void vSend_Wave()
{
u8 i;
for(i=0;i<8;i++) //发送8个40kHz方波
{
P10 = 1;
Delay12us();
P10 = 0;
Delay12us();
}
}
u16 uiDistance_Get()
{
u16 dist;
vSend_Wave(); //发送8个40kHz方波
TH1 = 0; TL1 = 0; //清零定时器1
TR1 = 1; //开启定时器1
while(P11 == 1); //等待P11变成低电平
TR1 = 0; //关闭定时器1
dist = (TH1<<8|TL1)*0.017; //计算距离,单位是cm
return dist;
}
//超声波测距,并数目管显示距离
#include "system.h"
HexToBin led_ctrl,uln_ctrl;
void vSystem_Init(void)
{
vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
vDevice_Ctrl(0x80,0xff); /* 关闭LED*/
}
//超声波操作函数
u16 cnt_sonic;
u16 dist_sonic;
void vSonic_Process()
{
if(cnt_sonic>=100)
{
cnt_sonic=0;
dist_sonic = uiDistance_Get();
}
}
//数码管操作函数
void vSMG_Process()
{
smg_buf[0]=smg_code[dist_sonic/10000];
smg_buf[1]=smg_code[dist_sonic/1000%10];
smg_buf[2]=smg_code[dist_sonic/100%10];
smg_buf[3]=smg_code[dist_sonic/10%10];
smg_buf[4]=smg_code[dist_sonic%10];
smg_buf[5]=0x00;
smg_buf[6]=0x00;
smg_buf[7]=0x00;
}
void main(void)
{
vSystem_Init();
vTimer2_Init();
vCounter0_Init();
while(1)
{
vSMG_Process();
vSonic_Process();
}
}
//中断服务程序
void vTimer2_ISR() interrupt 12 //中断入口,仅操作实时性要求高的函数
{
cnt_sonic++;
vSMG_Display();
}