目录
- 一、实现测距
- 二、添加TIM3控制LED根据距离以不同频率闪烁
- 三、观察时序
- Modebus协议
- 12路超声波雷达设计方案
-
-
- [1. 系统架构设计](#1. 系统架构设计)
- [2. 硬件设计](#2. 硬件设计)
- [3. 软件设计](#3. 软件设计)
- [4. 通信协议设计](#4. 通信协议设计)
- [5. 用户接口](#5. 用户接口)
- [6. 安全和冗余](#6. 安全和冗余)
- [7. 测试和验证](#7. 测试和验证)
- [8. 电源和物理封装](#8. 电源和物理封装)
- [9. 文档和支持](#9. 文档和支持)
-
一、实现测距
配置时钟
配置定时器
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文档和开发指南。
这个设计方案提供了一个基本的框架,具体实现时还需要根据实际需求和环境进行调整和优化。