LD2410B(雷达模块)HAL库
LD2410B.h#ifndef __LD2410B_H__ #define __LD2410B_H__ #include stm32f1xx_hal.h // STM32 HAL 库头文件 #include usart.h // 串口句柄声明 #define LD2410B_UART huart1 // LD2410B 使用的串口 #define length 256 // 接收缓冲区长度 #define LD2410B_ENERGY_BYTES 128 // 工程模式距离门能量值最大保存字节数 typedef struct { uint16_t data_size; // 帧内数据长度 uint8_t moving_status; // 目标状态0无目标1运动2静止3运动静止 uint16_t moving_distance; // 运动目标距离单位cm uint8_t moving_energy; // 运动目标能量 uint16_t static_distance; // 静止目标距离单位cm uint8_t static_energy; // 静止目标能量 uint16_t detect_distance; // 探测距离单位cm uint8_t data_type; // 数据类型0x01工程模式0x02基本信息 uint8_t energy[LD2410B_ENERGY_BYTES]; // 工程模式额外能量值 uint16_t energy_size; // 实际保存的能量值长度 } LD2410B_Data_t; void LD2410B_Init(void); // 初始化串口接收 uint8_t LD2410B_Read(LD2410B_Data_t *dev); // 读取最新解析结果成功返回1 #endifLD2410B.c#include LD2410B.h #define LD2410B_FRAME_MAX 128U // 单帧最大长度 #define LD2410B_FRAME_HEAD_LEN 4U // 帧头长度F4 F3 F2 F1 #define LD2410B_LEN_FIELD_LEN 2U // 长度字段长度 #define LD2410B_FRAME_TAIL_LEN 4U // 帧尾长度F8 F7 F6 F5 #define LD2410B_INNER_HEAD 0xAAU // 帧内头部固定值 #define LD2410B_INNER_TAIL 0x55U // 帧内尾部固定值 #define LD2410B_CHECK_VALUE 0x00U // 帧内校验固定值 #define LD2410B_BASIC_DATA_LEN 13U // 基本信息帧内数据长度 #define LD2410B_TARGET_INFO_LEN 9U // 目标基本信息长度 #define LD2410B_MIN_FRAME_LEN 23U // 普通上报完整帧最小长度 static uint8_t rx_byte; // 串口单字节接收缓存 static uint8_t rx_frame[LD2410B_FRAME_MAX]; // 正在拼接的当前帧 static uint8_t latest_frame[LD2410B_FRAME_MAX]; // 最近一帧完整有效数据 static uint16_t rx_index; // 当前帧接收下标 static uint16_t expected_len; // 根据长度字段计算出的整帧长度 static volatile uint16_t latest_len; // 最近有效帧长度 static volatile uint8_t frame_ready; // 完整帧就绪标志 static uint16_t LD2410B_U16LE(uint8_t low, uint8_t high) { return (uint16_t)low | ((uint16_t)high 8); // 小端转uint16_t } static void LD2410B_ResetRxFrame(void) { rx_index 0; // 从帧头重新匹配 expected_len 0; // 清空期望长度 } static uint8_t LD2410B_TailOk(const uint8_t *frame, uint16_t frame_len) { uint16_t tail frame_len - LD2410B_FRAME_TAIL_LEN; // 帧尾起始位置 return (frame[tail] 0xF8 // 校验帧尾第1字节 frame[tail 1U] 0xF7 // 校验帧尾第2字节 frame[tail 2U] 0xF6 // 校验帧尾第3字节 frame[tail 3U] 0xF5); // 校验帧尾第4字节 } void LD2410B_Init(void) { LD2410B_ResetRxFrame(); // 清空接收状态 latest_len 0; // 清空有效帧长度 frame_ready 0; // 清空就绪标志 HAL_UART_Receive_IT(LD2410B_UART, rx_byte, 1); // 开启单字节中断接收 } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance ! LD2410B_UART.Instance) // 判断是否为LD2410B串口 { return; // 不是则退出 } if (rx_index LD2410B_FRAME_HEAD_LEN) // 还在匹配帧头阶段 { static const uint8_t head[LD2410B_FRAME_HEAD_LEN] {0xF4, 0xF3, 0xF2, 0xF1}; // 上报帧头 if (rx_byte ! head[rx_index]) // 当前字节不符合帧头顺序 { rx_index (rx_byte head[0]) ? 1U : 0U; // 若像新帧头开头则保留进度 rx_frame[0] rx_byte; // 保存可能的新帧头首字节 HAL_UART_Receive_IT(LD2410B_UART, rx_byte, 1); // 继续接收 return; // 本次处理结束 } } rx_frame[rx_index] rx_byte; // 保存当前字节 if (rx_index (LD2410B_FRAME_HEAD_LEN LD2410B_LEN_FIELD_LEN)) // 已收到长度字段 { uint16_t data_len LD2410B_U16LE(rx_frame[4], rx_frame[5]); // 帧内数据长度 expected_len LD2410B_FRAME_HEAD_LEN LD2410B_LEN_FIELD_LEN data_len LD2410B_FRAME_TAIL_LEN; // 整帧长度 if (expected_len LD2410B_FRAME_MAX || expected_len LD2410B_MIN_FRAME_LEN) // 长度异常 { LD2410B_ResetRxFrame(); // 丢弃当前帧 } } if (expected_len ! 0U rx_index expected_len) // 收到完整帧 { if (LD2410B_TailOk(rx_frame, expected_len) ! 0U) // 帧尾正确 { for (uint16_t i 0; i expected_len; i) // 复制有效帧 { latest_frame[i] rx_frame[i]; // 保存到最新帧缓存 } latest_len expected_len; // 记录有效帧长度 frame_ready 1; // 标记可读取 } LD2410B_ResetRxFrame(); // 准备下一帧 } if (rx_index LD2410B_FRAME_MAX) // 防止越界 { LD2410B_ResetRxFrame(); // 越界前重置 } HAL_UART_Receive_IT(LD2410B_UART, rx_byte, 1); // 继续接收下一个字节 } uint8_t LD2410B_Read(LD2410B_Data_t *dev) { uint16_t data_index; // 帧内数据起始位置 uint16_t target_index; // 目标数据起始位置 uint16_t energy_size; // 工程模式额外能量长度 if (dev 0 || frame_ready 0U || latest_len LD2410B_MIN_FRAME_LEN) // 参数或状态检查 { return 0; // 无有效数据 } frame_ready 0; // 消费当前帧 dev-data_size LD2410B_U16LE(latest_frame[4], latest_frame[5]); // 帧内数据长度 data_index LD2410B_FRAME_HEAD_LEN LD2410B_LEN_FIELD_LEN; // 帧内数据起始位置 if (latest_frame[data_index 1U] ! LD2410B_INNER_HEAD) // 校验0xAA { return 0; // 帧内头部错误 } if (latest_frame[data_index dev-data_size - 2U] ! LD2410B_INNER_TAIL || latest_frame[data_index dev-data_size - 1U] ! LD2410B_CHECK_VALUE) // 校验0x55和0x00 { return 0; // 帧内尾部错误 } dev-data_type latest_frame[data_index]; // 数据类型 target_index data_index 2U; // 跳过数据类型和0xAA dev-moving_status latest_frame[target_index]; // 目标状态 dev-moving_distance LD2410B_U16LE(latest_frame[target_index 1U], latest_frame[target_index 2U]); // 运动距离 dev-moving_energy latest_frame[target_index 3U]; // 运动能量 dev-static_distance LD2410B_U16LE(latest_frame[target_index 4U], latest_frame[target_index 5U]); // 静止距离 dev-static_energy latest_frame[target_index 6U]; // 静止能量 dev-detect_distance LD2410B_U16LE(latest_frame[target_index 7U], latest_frame[target_index 8U]); // 探测距离 energy_size dev-data_size - LD2410B_BASIC_DATA_LEN; // 工程模式额外数据长度 if (energy_size LD2410B_ENERGY_BYTES) // 防止数组越界 { energy_size LD2410B_ENERGY_BYTES; // 限制最大长度 } dev-energy_size energy_size; // 保存能量值长度 for (uint16_t i 0; i energy_size; i) // 复制工程模式额外能量值 { dev-energy[i] latest_frame[target_index LD2410B_TARGET_INFO_LEN i]; // 目标数据之后的数据 } return 1; // 解析成功 }