HC-SR04 是最常见的用于单片机的超声波测距模块。
我拿到手后,研究了一番,改进了厂方提供的代码,重新整理成一个函数库。
如果最近你也在研究的话,可以参考一下。测距速度很快。调用也很方便,使用T0计数器。
并且采用串口方式将测距结果传回下位机。
代码部分,首先是接口管脚配置UltrasonicDistanceConfig.h
- #ifndef __ULTRASONIC_DISTANCE_CONFIG_H__
- #define __ULTRASONIC_DISTANCE_CONFIG_H__
- #include <reg52.h>
- //***************************************************//
- // HC-SR04 超声波测距模块配置文件 //
- //---------------------------------------------------//
- // 晶振:11.0592 //
- // Create Date:2011-09-27 User:JerryLi //
- // email:lijian@dzs.mobi //
- // 工作时将会占用 T0 计数器 //
- // HC-SR04 的探测精度范围为 2cm-400cm //
- // 在当前晶振工作频率下,一次有效测距需要23.42ms //
- //---------------------------------------------------//
- #define DOUBLE_CRYSTAL_FREQ 11.0592 //晶振频率(单位M)(11.94477)
- /**
- *管脚硬件连接配置
- * Echo回波引脚为 RX
- * Trig触发信号控制端 TX
- */
- sbit RX =P1^1; //Echo回波引脚
- sbit TX =P1^2; //Trig触发信号控制端
- #endif
其次为函数库头文件UltrasonicDistanceDriver.h
- #ifndef __ULTRASONIC_DISTANCE_DRIVER_H__
- #define __ULTRASONIC_DISTANCE_DRIVER_H__
- #include <reg52.h>
- //***************************************************//
- // HC-SR04 超声波测距模块操作库 //
- //---------------------------------------------------//
- // 晶振:11.0592 //
- // Create Date:2011-09-27 User:JerryLi //
- // email:lijian@dzs.mobi //
- // 工作时将会占用 T0 计数器 //
- // HC-SR04 的探测精度范围为 2cm-400cm //
- // 在当前晶振工作频率下,一次有效测距需要23.42ms //
- //---------------------------------------------------//
-
- /*-------------------------------------------------------
- *超声波测距模块初始化函数
- *@return void
- *-------------------------------------------------------*/
- extern void InitUltrasonicDistance(void);
-
- /*-------------------------------------------------------
- *获取最近一次测得的距离
- * 注意:每次成功测距,需要耗时100ms-150ms左右时间
- *-------------------------------------------------------*/
- extern unsigned int getDistance(void);
-
- /*-------------------------------------------------------
- *获取最近一次的测距状态
- *@return unsigned int 0:正常 / 1:(err)距离太近 /2:(err)超量程
- *-------------------------------------------------------*/
- extern unsigned int getDistanceState(void);
-
- /*-------------------------------------------------------
- *检查距离操作(将测得的距离保存在公共变量中)
- * 备注:本函数调用完成后,需要通过getDistance()或getDistanceState()获得结果
- * 注意:每次成功测距,需要耗时100ms-150ms左右时间
- * @return 0:完成测距操作 / 1:正在延迟等待下次测距的开始
- *-------------------------------------------------------*/
- extern unsigned char refreshDistance(void);
- #endif
-
- /*使用方式:
- #include "SerialComm.h" //串口通讯操作类
- void main(void)
- {
- uchar pcOutBuf[30];
- uint iOld=0;
-
- InitUltrasonicDistance();
- InitSerialComm();
- while(1)
- {
- //当调用测距函数后,返回为0,表示测距成功,否则测距函数正在延迟中
- if (0 == refreshDistance())
- {
- //当取值有效时,如果与前次值没变化,则不作更新
- if (0 == getDistanceState() && (iOld != getDistance()))
- {
- iOld = getDistance();
- sprintf(pcOutBuf, "S=%d\r\n", iOld);
- SerialSendStr(pcOutBuf); //送到串口
- }
- }
- }
- }
- */
最后是函数库文件UltrasonicDistanceDriver.c
串口通信配置文件SerialComm.h
- #ifndef __Serial_Comm_H__
- #define __Serial_Comm_H__
- #include <reg52.h>
- //***************************************************//
- // 串口通讯操作库 //
- //---------------------------------------------------//
- // 波特率:9600, 11.0592, 无奇偶校验, 8数据位,1停止位//
- // Create Date:2011-09-22 User:JerryLi //
- // email:lijian@dzs.mobi //
- // 工作时将会占用 interrupt 4 using 1 这个中断 //
- // 即: 占用 T1 计数器 //
- //---------------------------------------------------//
-
- /*-------------------------------------------------------
- *串口初始化,波特率9600 方式1 8 UART
- *@return void
- *-------------------------------------------------------*/
- extern void InitSerialComm(void);
-
- /*-------------------------------------------------------
- *读取串口接收状态
- *@return 0:无数据 / 1:有数据
- *-------------------------------------------------------*/
- extern bit getReceiveFlg(void);
-
- /*-------------------------------------------------------
- *读取串口中的一个字节
- * 读取条件,必须当getReceiveFlg() == 1的时候才能读取
- *@return void
- *-------------------------------------------------------*/
- extern char ReadChar(void);
-
- /*-------------------------------------------------------
- *读取一个字符串
- * 备注:当读取到第一个字符时,直到出现'\0'或'\r'结束,
- * 或者当缓冲区填满的时候结束,输出字符串以'\0'结束
- * 注意:务必注意结束符,如果发送端没有传入结束符将会一直
- * 死循环等着,直到等到出现有结束符为止。
- *@param char *pOutBuf 在缓存中存放接收到字符并以 '\0'结束
- *@param short sLen 缓冲区的长度
- *@return short 返回成功接收到的字符数量,<0表示未读到数据
- *-------------------------------------------------------*/
- extern short ReadStr(char *pOutBuf, short sLen);
-
- /*-------------------------------------------------------
- *向串口发送单字节
- *@param char cData 要发送的数据
- *@return void
- *-----------------------------------------------------*/
- extern void SerialSendByte(char cData);
-
- /*-------------------------------------------------------
- *向串口发送一个字符串 以'\0'结束
- *@param char *str 需要发送的字符串指针
- *@return void
- *-----------------------------------------------------*/
- extern void SerialSendStr(char *str);
- #endif
-
- /*使用方式:
- #include "SerialComm.h" //串口通讯操作类
- void main (void)
- {
- char pReBuf[20];
- // char cBuf;
-
- InitSerialComm();
- while(1)
- {
- if (getReceiveFlg())
- {
- //测试时,字符接收与字符串接收不要一起用
- // SerialSendByte(ReadChar()); //发送一个字符
- ReadStr(pReBuf, 20); //接收一个字符串
- SerialSendStr(pReBuf); //发送一个字符串
- }
- }
- }
- */
串口通信程序文件SerialComm.c
这个是函数库的调用文件,主程序main.c
我是用自己的串口通信函数送回收到的数据的,你可以使用系统的print函数来输出数据到串口,结构很简单看了就懂。
- /***********************************************************************************************************/
- //HC-SR04 超声波测距模块 DEMO 程序
- //晶振:11.0592
- //接线:模块TRIG接 P1.2 ECH0 接P1.1
- //串口波特率:9600
- /***********************************************************************************************************/
- #include <reg52.h> //包函8051内部资源的定义
- #include <STDIO.H>
- #include "SerialComm.h"
- #include "UltrasonicDistanceDriver.h"
- /********************************************************/
- void main(void)
- {
- char pcOutBuf[30];
- unsigned int iOld=0;
-
- InitUltrasonicDistance();
- InitSerialComm();
- while(1)
- {
- //当调用测距函数后,返回为0,表示测距成功,否则测距函数正在延迟中
- if (0 == refreshDistance())
- {
- //当取值有效时,如果与前次值没变化,则不作更新
- if (0 == getDistanceState() && (iOld != getDistance()))
- {
- iOld = getDistance();
- sprintf(pcOutBuf, "S=%d\r\n", iOld);
- SerialSendStr(pcOutBuf); //送到串口
- P2=~(unsigned int)(iOld); //点灯
- }
- }
- }
- }
|