stm32f103 HAL库 HC-SR04测距

目录

一、实现测距

配置时钟

配置定时器

GPIO口

配置串口

c 复制代码
#include "SR04.h"
 
uint32_t measure_Buf[3] = {0};   //存放定时器计数值的数组
uint8_t  measure_Cnt = 0;    //状态标志位
uint32_t high_time;   //超声波模块返回的高电平时间
float distant;      //测量距离
 
//===============================================读取距离
void SR04_GetData(void)
{
switch (measure_Cnt){
	case 0:
         TRIG_H;
         delay_us(30);
         TRIG_L;
    
		measure_Cnt++;
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
		HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);	//启动输入捕获       或者: __HAL_TIM_ENABLE(&htim5);                                                                                    		
        break;
	case 3:
		high_time = measure_Buf[1]- measure_Buf[0];    //高电平时间
         printf("\r\n----高电平时间-%d-us----\r\n",high_time);							
		distant=(high_time*0.034)/2;  //单位cm
        printf("\r\n-检测距离为-%.2f-cm-\r\n",distant);          
		measure_Cnt = 0;  //清空标志位
        TIM2->CNT=0;     //清空计时器计数
		break;
				
	}
}
 
 
//===============================================us延时函数
    void delay_us(uint32_t us)//主频72M
{
    uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
    while (delay--)
	{
		;
	}
}
 
//===============================================中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//
{
	
	if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
	{
		switch(measure_Cnt){
			case 1:
				measure_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
				measure_Cnt++;                                            
				break;              
			case 2:
				measure_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
				HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
				measure_Cnt++;  
                         
		}
	
	}
	
}
 

二、添加TIM3控制LED根据距离以不同频率闪烁

这里我只设置了两个速度,小于10cm时0.2间隔闪烁,大于10cm时0.5s间隔闪烁

主要代码实现

头文件

c 复制代码
#ifndef __SR04_H
#define __SR04_H
#include "main.h"
#include "tim.h"
#include "stdio.h"
 
#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)

extern float distant;      //测量距离

void delay_us(uint32_t us);
void SR04_GetData(void);
 
#endif
c 复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM3)
	{
        // 切换LED状态
         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
 
}

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_TIM2_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);
	HAL_TIM_Base_Start_IT(&htim3);	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  //printf("\r\n----高电平时间--us----\r\n");							
		  SR04_GetData();
		if (distant < 10.0f) {
			// distant小于5,设置定时器周期为0.2秒
			__HAL_TIM_SET_AUTORELOAD(&htim3, 25000 - 1);//(uint32_t)(SystemCoreClock / 2) / 1000); // 假设系统时钟为SystemCoreClock
		} else {
			// distant大于等于5,设置定时器周期为0.5秒
			__HAL_TIM_SET_AUTORELOAD(&htim3, 50000-1);
		}

		// 重新启动定时器
		HAL_TIM_Base_Start_IT(&htim3);
		HAL_Delay(1500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

三、观察时序


延时30us左右和代码中匹配

Modebus协议

Modbus协议是一种串行通信协议,最初由Modicon公司(现在的施耐德电气Schneider Electric)在1979年发表,用于可编程逻辑控制器(PLC)之间的通信。它已经成为工业领域通信协议的业界标准,并且是工业电子设备之间常用的连接方式。Modbus协议的主要特点包括公开发表、无版权要求、易于部署和维护,以及对供应商来说,修改移动本地的比特或字节没有很多限制。

Modbus协议允许多个设备(大约240个)连接在同一个网络上进行通信,例如,一个测量温度和湿度的设备,并将结果发送给计算机。在数据采集与监视控制系统(SCADA)中,Modbus通常用来连接监控计算机和远程终端控制系统(RTU)。Modbus协议存在用于串口、以太网以及其他支持互联网协议的网络的版本。大多数Modbus设备通信通过串口EIA-485物理层进行。

Modbus协议有两种主要的串行通信变体:Modbus RTU和Modbus ASCII。Modbus RTU采用二进制表示数据,而Modbus ASCII则是人类可读的、冗长的表示方式。RTU格式的命令/数据带有循环冗余校验(CRC)的校验和,而ASCII格式采用纵向冗余校验的校验和。Modbus Plus是Modbus的一个扩展版本,但是它是Modicon专有的,和Modbus不同。

Modbus协议采用master/slave架构,其中一个节点是master节点,其他节点是slave节点,每个slave设备都有一个唯一的地址。在串行和Modbus Plus网络中,只有被指定为主节点的节点可以启动命令,在以太网上,任何一个设备都能发送Modbus命令,但通常也只有一个主节点设备启动指令。

Modbus命令包含了执行操作的设备的Modbus地址,所有设备都会收到命令,但只有指定地址的设备会执行及回应指令。Modbus命令还包括检查码,以确保命令在传输过程中没有被破坏。基本的ModBus命令可以指令一个RTU改变寄存器的值、控制或读取I/O端口,以及指挥设备回送其寄存器中的数据。

Modbus协议是应用层报文传输协议,定义了一个与物理层无关的协议数据单元(PDU),PDU由功能码和数据域组成,功能码为1字节,数据域长度不固定。Modbus RTU协议允许PLC和计算机之间通过串行线路交换信息,并在建筑管理系统(BMS)和工业自动化系统中得到广泛应用。Modbus TCP是设计用于通过TCP/IP堆栈传输Modbus帧的协议,通常通过以太网物理层传输。Modbus最初作为串行层传输数据的应用级协议,现在也可以通过TCP/IP和UDP实现。

12路超声波雷达设计方案

设计一款12路车载超声波雷达系统,使用STM32F103微控制器和HC-SR04超声波传感器模块,同时提供RS485和Modbus协议的接口,需要考虑以下几个关键方面:

1. 系统架构设计

  • 主控制器:选择STM32F103系列微控制器作为主控单元,因为它具有足够的GPIO、定时器和通信接口。
  • 传感器模块:每个HC-SR04模块负责一个方向的测距,共需要12个。

2. 硬件设计

  • GPIO配置:为每个HC-SR04配置一对GPIO用于TRIG和ECHO信号。
  • 定时器:使用STM32的定时器来精确测量HC-SR04的回波时间。
  • RS485通信:使用STM32的USART接口配置为RS485,以实现数据的串行通信。
  • Modbus协议栈:集成Modbus协议栈来处理Modbus RTU或TCP通信。
  • 电源管理:确保系统有稳定的电源供应,并考虑电源防反接和过压保护。
  • 物理布局:合理布局12个传感器,确保覆盖车辆周围所有必要的监测区域。

3. 软件设计

  • 驱动程序:编写HC-SR04超声波传感器的驱动程序,实现距离测量。
  • Modbus协议实现:实现Modbus RTU协议,处理功能码,响应数据读取和写入请求。
  • RS485通信:实现RS485通信接口,确保数据传输的可靠性。
  • 任务调度:设计任务调度程序,合理分配CPU时间给各个传感器的测量任务。
  • 数据融合:设计算法对12路传感器数据进行融合处理,提供更准确的车辆周围环境信息。

4. 通信协议设计

  • Modbus功能码:定义Modbus功能码,实现对每个传感器的独立控制和数据读取。
  • 数据帧格式:设计Modbus数据帧格式,包括设备地址、功能码、数据寄存器地址、数据长度和校验等。

5. 用户接口

  • 配置界面:提供一种方式(如串口命令行、图形界面等)来配置设备参数,例如传感器校准、Modbus地址等。

6. 安全和冗余

  • 故障检测:实现故障检测机制,当某个传感器失效时能够及时报警。
  • 数据校验:确保所有通信数据都有校验机制,如CRC校验。

7. 测试和验证

  • 单元测试:对每个模块进行单元测试,确保其功能正确。
  • 集成测试:进行系统集成测试,确保所有模块协同工作正常。
  • 环境测试:在实际车辆上进行测试,验证系统在不同环境下的性能。

8. 电源和物理封装

  • 电源设计:设计合适的电源方案,包括电源转换和稳压。
  • 封装设计:设计适合车载环境的封装,确保系统的稳定性和耐用性。

9. 文档和支持

  • 用户手册:提供详细的用户手册,包括安装、配置和故障排除指南。
  • 开发文档:为二次开发提供API文档和开发指南。

这个设计方案提供了一个基本的框架,具体实现时还需要根据实际需求和环境进行调整和优化。

相关推荐
LateBloomer7771 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
wenchm2 小时前
细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
stm32·单片机·嵌入式硬件
编码追梦人3 小时前
如何实现单片机的安全启动和安全固件更新
单片机
电子工程师UP学堂3 小时前
电子应用设计方案-16:智能闹钟系统方案设计
单片机·嵌入式硬件
飞凌嵌入式3 小时前
飞凌嵌入式T113-i开发板RISC-V核的实时应用方案
人工智能·嵌入式硬件·嵌入式·risc-v·飞凌嵌入式
blessing。。5 小时前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
嵌新程6 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012306 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)6 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII6 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件