您的位置:首页 > 游戏 > 游戏 > 红外超声波雷达

红外超声波雷达

2025/5/16 6:01:16 来源:https://blog.csdn.net/qq_65913626/article/details/139239465  浏览:    关键词:红外超声波雷达

一. 采用stm32F103和HC-SR04超声波模块, 使用标准库或HAL库+ 定时器中断,完成1或2路的超声波障碍物测距功能。

CubeMX配置:

1、RCC配置外部高速晶振——HSE
在这里插入图片描述
2、SYS配置:Debug设置成Serial Wire
在这里插入图片描述
ADC1配置:配置ADC-IN1模数转换
在这里插入图片描述
TIM2配置:设置定时器TIM2每1us向上计数一次,通道1为上升沿捕获并连接到超声波模块的ECHO引脚
在这里插入图片描述
GPIO配置:PA5接到了HC-SR04的TRIG触发引脚,默认输出低电平
在这里插入图片描述
TIM1配置:由上面可知HC-SR04的使用需要us级的延迟函数,HAL库自带只有ms的,所以需要自己设计一个定时器
在这里插入图片描述

超声波模块代码:

HC-SR04.h:

#ifndef HCSR04_H_
#define HCSR04_H_#include "main.h"
#include "delay.h"typedef struct
{uint8_t  edge_state;uint16_t tim_overflow_counter;uint32_t prescaler;uint32_t period;uint32_t t1;	//	上升沿时间uint32_t t2;	//	下降沿时间uint32_t high_level_us;	//	高电平持续时间float    distance;TIM_TypeDef* instance;uint32_t ic_tim_ch;HAL_TIM_ActiveChannel active_channel;
}Hcsr04InfoTypeDef;extern Hcsr04InfoTypeDef Hcsr04Info;/*** @description: 超声波模块的输入捕获定时器通道初始化* @param {TIM_HandleTypeDef} *htim* @param {uint32_t} Channel* @return {*}*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel);/*** @description: HC-SR04触发* @param {*}* @return {*}*/
void Hcsr04Start();/*** @description: 定时器计数溢出中断处理函数* @param {*}    main.c中重定义void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)* @return {*}*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim);/*** @description: 输入捕获计算高电平时间->距离* @param {*}    main.c中重定义void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)* @return {*}*/
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim);/*** @description: 读取距离 * @param {*}* @return {*}*/
float Hcsr04Read();#endif /* HCSR04_H_ */

HC-SR04.c:

#include "hc-sr04.h"Hcsr04InfoTypeDef Hcsr04Info;/*** @description: 超声波模块的输入捕获定时器通道初始化* @param {TIM_HandleTypeDef} *htim* @param {uint32_t} Channel* @return {*}*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel)
{/*--------[ Configure The HCSR04 IC Timer Channel ] */// MX_TIM2_Init();  // cubemx中配置Hcsr04Info.prescaler = htim->Init.Prescaler; //  72-1Hcsr04Info.period = htim->Init.Period;       //  65535Hcsr04Info.instance = htim->Instance;        //  TIM2Hcsr04Info.ic_tim_ch = Channel;if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_1){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_1;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_2){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_2;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_3){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_3;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4;             //  TIM_CHANNEL_4}/*--------[ Start The ICU Channel ]-------*/HAL_TIM_Base_Start_IT(htim);HAL_TIM_IC_Start_IT(htim, Channel);
}/*** @description: HC-SR04触发* @param {*}* @return {*}*/
void Hcsr04Start()
{HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);DelayUs(10);  //  10us以上HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);
}/*** @description: 定时器计数溢出中断处理函数* @param {*}    main.c中重定义void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)* @return {*}*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim)
{if(htim->Instance == Hcsr04Info.instance) //  TIM2{Hcsr04Info.tim_overflow_counter++;}
}/*** @description: 输入捕获计算高电平时间->距离* @param {*}    main.c中重定义void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)* @return {*}*/
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim)
{if((htim->Instance == Hcsr04Info.instance) && (htim->Channel == Hcsr04Info.active_channel)){if(Hcsr04Info.edge_state == 0)      //  捕获上升沿{// 得到上升沿开始时间T1,并更改输入捕获为下降沿Hcsr04Info.t1 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_FALLING);Hcsr04Info.tim_overflow_counter = 0;  //  定时器溢出计数器清零Hcsr04Info.edge_state = 1;        //  上升沿、下降沿捕获标志位}else if(Hcsr04Info.edge_state == 1) //  捕获下降沿{// 捕获下降沿时间T2,并计算高电平时间Hcsr04Info.t2 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);Hcsr04Info.t2 += Hcsr04Info.tim_overflow_counter * Hcsr04Info.period; //  需要考虑定时器溢出中断Hcsr04Info.high_level_us = Hcsr04Info.t2 - Hcsr04Info.t1; //  高电平持续时间 = 下降沿时间点 - 上升沿时间点// 计算距离Hcsr04Info.distance = (Hcsr04Info.high_level_us / 1000000.0) * 340.0 / 2.0 * 100.0;// 重新开启上升沿捕获Hcsr04Info.edge_state = 0;  //  一次采集完毕,清零__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_RISING);}}
}/*** @description: 读取距离 * @param {*}* @return {*}*/
float Hcsr04Read()
{// 测距结果限幅if(Hcsr04Info.distance >= 500){Hcsr04Info.distance = 500;        //元器件资料说是600cm最高距离,这里保守一点}return Hcsr04Info.distance;
}
/* USER CODE BEGIN 4 */
/*** @description: 定时器输出捕获中断* @param {TIM_HandleTypeDef} *htim* @return {*}*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)    //捕获回调函数
{Hcsr04TimIcIsr(htim);
}/*** @description: 定时器溢出中断* @param {*}* @return {*}*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)    //在中断回调函数中添加用户代码
{Hcsr04TimOverflowIsr(htim);
}
/* USER CODE END 4 */

ranging.h:

#ifndef __SHARP2Y0A21_H
#define __SHARP2Y0A21_H	#include "main.h"#define Adc1IN1Distance_READ_TIMES	10		//定义红外传感器读取次数,以便取平均值void DistanceSensor_Init(void); 				//初始化红外传感器
float DistanceSensor_Get_Val(void);				//读取红外传感器的值#endif 

ranging.c:

#include "sharp.h"
#include "adc.h"
#include "main.h"
#include "stdio.h"//初始化ADC,不用修改
//这里我们仅以规则通道为例														   //初始化传感器,需要修改端口和引脚号,这里是c出口,c1引脚,ADC1的IN1
void DistanceSensor_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;__HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟//先初始化ADC1通道11 IO口GPIO_InitStructure.Pin = GPIO_PIN_1;//PA1GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;//模拟输入GPIO_InitStructure.Pull = GPIO_NOPULL ;//不带上下拉HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  MX_ADC1_Init();//初始化ADC1
}
//PA1=IN1
float DistanceSensor_Get_Val(void)
{uint32_t temp_val=0;float distemp=0.0;uint8_t t;for(t=0;t<Adc1IN1Distance_READ_TIMES;t++){temp_val+=HAL_ADC_GetValue(&hadc1);	//读取ADC值,通道1HAL_Delay(5);}temp_val/=Adc1IN1Distance_READ_TIMES;//得到平均值,这个是平均的ADC,distemp=temp_val*3.3/4095;//电压对应距离distemp=(-13.2*distemp*distemp*distemp)+72.84*distemp*distemp-140*distemp+107.12;return distemp;}

main 函数:

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_I2C2_Init();MX_ADC1_Init();MX_TIM2_Init();MX_TIM1_Init();/* USER CODE BEGIN 2 */OLED_Init();OLED_CLS();Hcsr04Init(&htim2, TIM_CHANNEL_1);  // 通道选择Hcsr04Start();  //  启动超声波/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///显示实验对比OLED_ShowCN_STR(30,0,0,4);//红外测距显示HAL_ADC_Start(&hadc1);adcx=HAL_ADC_GetValue(&hadc1);distance=DistanceSensor_Get_Val();OLED_ShowCN_STR(0,2,4,5);OLED_Showdecimal(80,2,distance,3,2,16);//超声波测距显示Hcsr04Start();OLED_ShowCN_STR(0,4,9,5);OLED_Showdecimal(80,4,Hcsr04Read(),3,2,16);//显示单位OLED_ShowCN_STR(30,6,14,5);}/* USER CODE END 3 */
}

二. 当前智能汽车上一般配置有12路超声波雷达,这些专用超声波雷达内置了MCU,直接输出数字化的测距结果,一般硬件接口采用串口RS485,通信协议采用modbus。请思考:

1)RS485与RS232(UART)有什么不同?

1. 通信方式

  • RS485
    • 差分信号传输:使用一对平衡信号线(A和B)进行差分传输,可以有效抵抗电磁干扰,提高通信可靠性。
    • 多点通信:支持多点总线结构,最多可以连接32个驱动器和32个接收器(有扩展可支持更多设备)。
    • 半双工/全双工:通常采用半双工通信(两线制),但也可以实现全双工通信(四线制)。
  • RS232
    • 单端信号传输:使用单端信号传输,相对于地传输信号,抗干扰能力较差。
    • 点对点通信:只能实现点对点通信,通常只连接两个设备(一个发送,一个接收)。
    • 全双工:可以同时发送和接收数据。

2. 信号电平

  • RS485
    • 差分信号电平:典型情况下,差分电压在+5V和-5V之间。
  • RS232
    • 单端信号电平:逻辑高电平(通常为-3V到-15V),逻辑低电平(通常为+3V到+15V)。

3. 传输速率

  • RS485
    • 支持较高的传输速率,通常可以达到10 Mbps(距离越短速率越高)。
  • RS232
    • 传输速率较低,通常为115200 bps,最高可达1 Mbps(距离越短速率越高)。

2)Modbus协议是什么?

Modbus协议是一种用于电子控制器之间通信的开放式协议,最早由Modicon(现为施耐德电气的一部分)在1979年开发。它已成为工业自动化和控制系统中广泛使用的通信标准。Modbus协议主要用于连接监控计算机与远程终端单元(RTU),以及不同种类的传感器和仪表之间的数据交换。

Modbus协议的主要特点

  1. 开放性:Modbus是一个开放协议,这意味着任何制造商都可以免费使用它来开发自己的Modbus设备。

  2. 简单性:Modbus协议相对简单,易于实现,特别适合资源有限的嵌入式系统。

  3. 灵活性:Modbus可以在多种通信介质上传输,包括串行通信(RS232、RS485)、以太网(Modbus TCP/IP)、以及通过各种无线技术。

Modbus的通信方式

  1. Modbus RTU(Remote Terminal Unit)

    • 传输方式:使用RS232或RS485串行通信。
    • 数据帧格式:数据以二进制形式传输,包含地址、功能码、数据、校验码(CRC)等字段。
    • 适用场景:多用于工业现场,支持远距离和多点通信。
  2. Modbus ASCII

    • 传输方式:使用RS232或RS485串行通信。
    • 数据帧格式:数据以ASCII码形式传输,每个字节用两个ASCII字符表示,具有起始符(冒号)、地址、功能码、数据、校验码(LRC)、结束符(回车换行)。
    • 适用场景:较少使用于工业现场,通常在一些需要与人进行交互或需要易读性的场景中使用。
  3. Modbus TCP/IP

    • 传输方式:使用以太网通信。
    • 数据帧格式:封装在TCP/IP报文中,适用于以太网环境。
    • 适用场景:工业自动化系统中需要快速、可靠的通信,常用于PLC、HMI、SCADA系统之间的数据交换。

Modbus协议的工作模式

  1. 主/从(Master/Slave)模式

    • 主设备(Master)发起通信,发送请求,等待从设备(Slave)的响应。
    • 从设备(Slave)被动响应主设备的请求,不能主动发送数据。
    • 适用于Modbus RTU和Modbus ASCII通信模式。
  2. 客户端/服务器(Client/Server)模式

    • 客户端(Client)发起通信,发送请求,服务器(Server)被动响应。
    • 适用于Modbus TCP/IP通信模式。

Modbus帧结构

Modbus通信中的数据帧结构大致如下:

  • 地址域:标识目标设备的地址。
  • 功能码:表示执行的操作,例如读写寄存器。
  • 数据域:包含具体的操作数据。
  • 错误校验码:用于检测通信错误(如CRC或LRC)。

Modbus协议的应用

  • 工业自动化:广泛用于PLC、DCS、SCADA系统的集成和数据交换。
  • 能源管理:电力监控系统、智能电表等。
  • 过程控制:工厂自动化、过程监控、传感器数据采集。

3)如果让你设计一款 12路车载超声波雷达,采用 stm32F103+HC-SR04超声波模块,对外提供RS485和Modbus协议,你的设计方案是什么?

设计一款12路车载超声波雷达系统,采用STM32F103微控制器和HC-SR04超声波模块,并对外提供RS485和Modbus协议通信,涉及多个硬件和软件层面的细节。以下是一个详细的设计方案:

a、硬件设计

1. 主要组件
  • 微控制器:STM32F103
  • 超声波模块:12个HC-SR04
  • RS485收发器:如MAX485
  • 电源管理:稳压电源模块,为系统提供稳定的5V和3.3V电压
  • 其他:电容、电阻、连接线等
2. 硬件连接
  • HC-SR04超声波模块连接

    • 每个HC-SR04模块需要连接4个引脚:VCC、GND、Trig和Echo。
    • VCC和GND连接到电源和地。
    • Trig和Echo引脚分别连接到STM32F103的GPIO引脚。
  • RS485通信模块连接

    • 使用MAX485或类似的RS485收发器模块。
    • 收发器的DE和RE引脚可以连接在一起,由STM32F103的GPIO控制(使能和禁用)。
    • DI引脚连接到STM32F103的UART TX引脚,RO引脚连接到STM32F103的UART RX引脚。
  • 电源管理

    • 使用DC-DC稳压模块将车载电源(如12V)降压到5V,用于供电HC-SR04模块和STM32F103。
    • 可能需要进一步降压到3.3V供电STM32F103(如果它需要3.3V)。

b、软件设计

1. STM32F103固件开发
  • 开发环境:使用Keil uVision或STM32CubeIDE。

  • 外设初始化

    • 初始化GPIO,用于HC-SR04模块的Trig和Echo引脚。
    • 初始化USART,用于RS485通信。
    • 初始化定时器,用于测量HC-SR04的回声脉冲宽度。
  • 超声波测距功能

    • 为每个HC-SR04模块配置一个Trig引脚和一个Echo引脚。
    • 通过Trig引脚发送10µs的高电平脉冲,触发超声波发送。
    • 使用定时器捕获Echo引脚的高电平持续时间,并计算距离。
  • 多路超声波测距

    • 采用轮询或定时触发方式,逐个触发12个HC-SR04模块,并读取测量结果。
2. Modbus协议实现
  • Modbus RTU协议栈

    • 实现Modbus RTU主/从模式(通常作为从设备)。
    • 实现基本的Modbus功能码,例如读取保持寄存器(0x03)、写单个寄存器(0x06)、写多个寄存器(0x10)等。
  • 数据处理和存储

    • 将超声波测得的距离数据存储在特定的寄存器中,以便通过Modbus协议读取。
    • 每个HC-SR04模块对应一个或多个寄存器。
  • RS485通信

    • 实现RS485收发控制,在发送数据前使能发送,在接收数据后禁用发送。
    • 处理Modbus请求和响应,通过RS485接口进行数据交换。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com