原理:
超声波方面:
超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波可用于距离的测量。
超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),
即:S=Vt/2 。
51单片机方面:
震荡周期,时钟周期:晶振提供
机器周期:CPU完成一个独立操作,为十二个震动周期
即:外接12MHz晶振51单片机每进行一次操作需要1us
HC-SR04方面:
(1)采用IO口TRIG触发测距,给至少10us的高电平信号; (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
时序图:
代码实现部分:
#include #include typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit Trig = P2^1; sbit Echo = P2^0; sbit LED=P2^2; u8 str[20]={0}; u8 zhi=10; u8 code strerror[]={"error"}; u8 i; u16 time; u16 S=0; bit flag=0; /******************************************************************************* 函数功能 :串口通信配置 *******************************************************************************/ void USARTinit() { SCON=0X50; //设置为工作方式1 TMOD=0X20|TMOD; //设置计数器工作方式2 PCON=0X80; //波特率加倍 TH1=0XF3; //计数器初始值设置,波特率是4800 TL1=0XF3; ES=1; //打开串口中断 EA=1; //打开总中断 TR1=1; //打开计数器 } /******************************************************************************* 函数功能 : 串口通信发送中断函数 输入 : 要发送的一字节数据 *******************************************************************************/ void send(u8 Data) { SBUF=Data; //数据放入到发送寄存器 while(!TI); //等待发送数据完成 TI=0; //清除发送完成标志位 } /******************************************************************************* 函数功能 : 定时器0初始化,用于计算时间 *******************************************************************************/ void T0inti() { TMOD=0x01|TMOD; //设T0为方式1 TH0=0; TL0=0; ET0=1; //允许T0中断 EA=1; //开启总中断 } /******************************************************************************* 函数功能 : 外部中断初始化 *******************************************************************************/ void EXinit() { EX0=1; //打开外部中断0 IT0=1; //边沿触发方式 EX1=1; //打开外部中断1 IT1=1; //边沿触发 EA=1; //打开总中断 } /******************************************************************************* 函数功能 : 阈值初始化 *******************************************************************************/ void zhiinit() interrupt 0 { zhi=10; } /******************************************************************************* 函数功能 : 阈值加10 *******************************************************************************/ void zhichuli() interrupt 2 { zhi=zhi+10; } /******************************************************************************* 函数功能: 提示计数器溢出,超过测距范围 *******************************************************************************/ void error() interrupt 1 { flag=1; //中断溢出标志 S=0; } /******************************************************************************* 函数功能 : 定时器0初始化,用于计算距离 *******************************************************************************/ void Conut() { if(flag==0) { time=TH0*256+TL0; TH0=0; TL0=0; (u16)S=(time*1.7)/100; //算出来是CM } } /******************************************************************************* 函数功能 : 对计算数据做处理,并发送,同时做量程判断 *******************************************************************************/ void chuli() { ES=1; //打开串口中断 TI=0; if(S<=zhi) //距离小于阈值cm或者距离大于测量值LED点亮,LED低电平点亮 (初始为10) { LED=0; } else { LED=1; } if(S==0) { for(i=0;i<=5;i++) { send(strerror[i]); } flag=0; TH0=0; TL0=0; } if(S>0) { for(i=1;S>=1;i++) { str[i]=(unsigned char)(S%10)+'0'; (u16)S=S/10; } for(i=i-1;i>0;i--) { send(str[i]); } send('r'); send('n'); ES=0; //关闭串口中断 } } /******************************************************************************* 函数功能 : 启动HC-SR04 *******************************************************************************/ void Start() //启动HC-SR04需要10us高电平,一个_nop_()是1us,保险起见设置20个 { Trig=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig=0; } void main() { T0inti(); EXinit(); USARTinit() ; while(1) { Start() ; while(!Echo); //当Echo为零时等待 TR0=1; //开启计数 while(Echo); //当Echo为1计数并等待 TR0=0; //关闭计数 Conut() ; chuli(); } } 收获: 对于单片机串口通信有了更深理解。 模块化编程有了一些尝试。
上一篇:LCD液晶显示的51单片机简单计算器
下一篇:基于51单片机的呼吸灯
推荐阅读最新更新时间:2024-11-12 09:47