HC-SR04简介
超声波是由机械振动产生的, 可在不同介质中以不同的速度传播, 具有定向性好、能量集中、传输过程中衰减较小、反射能力较强等优点。超声波传感器可广泛应用于非接触式检测方法,它不受光线、被测物颜色等影响, 对恶劣的工作环境具有一定的适应能力, 因此在水文液位测量、车辆自动导航、物体识别等领域有着广泛的应用。
超声波测距原理
超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波, 从而测出发射和接收回波的时间差Δt , 然后求出距离S 。在速度v 已知的情况下,距离S 的计算,公式如下:S = vΔt/ 2在空气中,常温下超声波的传播速度是334 米/秒,但其传播速度V 易受空气中温度、湿度、压强等因素的影响,其中受温度的影响较大,如温度每升高1 ℃, 声速增加约0. 6 米/ 秒。因此在测距精度要求很高的情况下, 应通过温度补偿的方法对传播速度加以校正。已知现场环境温度T 时, 超声波传播速度V 的计算公式如下:
V = 331. 5+0.607T
这样, 只要测得超声波发射和接收回波的时间差Δt 以及现场环境温度T,就可以精确计算出发射点到障碍物之间的距离。
HC-SR04超声波测距模块简介
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。
HC-SR04超声波测距模块特点
1、典型工作用电压:5V
2、超小静态工作电流:小于5mA
3、感应角度(R3 电阻越大,增益越高,探测角度越大):
R3 电阻为392,不大于15 度
R3 电阻为472, 不大于30 度
4、探测距离(R3 电阻可调节增益,即调节探测距离):
R3 电阻为392 2cm-450cm
R3 电阻为472 2cm-700cm
5、高精度:可达0.3cm
6、盲区(2cm)超近
HC-SR04超声波测距模块管脚
VCC(5V)、 Trig(控制端)、 Echo(接收端)、地(GND)
使用方法:控制口发一个10US 以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,就可以达到你移动测量的值了。
HC-SR04超声波测距模块工作原理
1、采用IO 触发测距,给至少10us 的高电平信号;
2、模块自动发送8 个40khz 的方波,自动检测是否有信号返回;
3、有信号返回,通过IO 输出高电平,高电平持续时间就是超声波从发射到返回时间.测试距离=(高电平时间*声速(340M/S))/2。
实物
STM32CubeMX配置
芯片使用的是STM32F103ZET6。
本次使用定时器去驱动HC-SR04,没有使用屏幕(主要没有找到),使用了串口进行数据显示。
时钟配置如下:
定时器配置
使用了定时器二,配置如下:
开启定时器的中断
GPIO引脚配置
使用了PA6和PA7两个引脚进行配置,分别做TRIG和ECHO。
串口配置
核心代码
HC-SRO4代码
/*
* 作者:PrairieOne
* csdn:PrairieOne
* 邮箱:prairieone1024@163.com
* 嵌入式技术交流群:826251093
*/
#define Trig_H HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_SET);
#define Trig_L HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_RESET);
htim2.Instance->CNT=0;
/* USER CODE END WHILE */
Trig_L;
Trig_H;
HAL_Delay(1);
Trig_L;
while(HAL_GPIO_ReadPin(Echo_GPIO_Port ,Echo_Pin)==GPIO_PIN_RESET)
s1=htim2.Instance->CNT;
while(HAL_GPIO_ReadPin(Echo_GPIO_Port ,Echo_Pin)==GPIO_PIN_SET)
s2=htim2.Instance->CNT;
distance=(s2-s1)*0.034/2;
printf("Distance is : %0.1fcm\r\n",distance);
HAL_Delay(500);
串口代码,加入之后可以直接使用printf
/*
* 作者:PrairieOne
* csdn:PrairieOne
* 邮箱:prairieone1024@163.com
* 嵌入式技术交流群:826251093
*/
extern UART_HandleTypeDef huart1;
#define RXBUFFERSIZE 256 //最大接收字节数
char RxBuffer[RXBUFFERSIZE]; //接收数据
uint8_t aRxBuffer; //接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(Uart1_Rx_Cnt >= 255) //溢出判断
{
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", Uart1_Rx_Cnt,0xFFFF);
}
else
{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; //接收数据转存
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
{
HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)//检测UART发送结束
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中断
}
/**
* 函数功能: 重定向c库函数printf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
/**
* 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;}
/* USER CODE END 4 */
主函数代码
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
HAL_TIM_Base_Start_IT(&htim2);//开启中断二
// Hcsr04Init(&htim1, TIM_CHANNEL_1); // 超声波模块初始化
// Hcsr04Start(); // 开启超声波模块测距
printf("hc-sr04 start!\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
htim2.Instance->CNT=0;
/* USER CODE END WHILE */
Trig_L;
Trig_H;
HAL_Delay(1);
Trig_L;
while(HAL_GPIO_ReadPin(Echo_GPIO_Port ,Echo_Pin)==GPIO_PIN_RESET)
s1=htim2.Instance->CNT;
while(HAL_GPIO_ReadPin(Echo_GPIO_Port ,Echo_Pin)==GPIO_PIN_SET)
s2=htim2.Instance->CNT;
distance=(s2-s1)*0.034/2;
printf("Distance is : %0.1fcm\r\n",distance);
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
效果展示
遇事不决,可问春风!