STM32HAL库实现ESA6218HA全功能驱动
目录一、适用说明二、完整代码文件1. ESA6218HA.h头文件2. ESA6218HA.c驱动实现3. usart.cUART 初始化必须配套4. main.c主函数调用示例三、通信协议工业标准帧格式功能说明四、工程使用要点总结这是可直接编译、直接上线使用的完整代码包含GPIO 初始化 UART 初始化 收发控制 发送 / 接收函数 中断接收 自定义通信协议 校验 主函数调用示例严格适配 ESA6218HA 半双工总线特性。一、适用说明芯片ESA6218HA双线半双工总线驱动主控STM32F103兼容全系列 STM32通信UART 半双工19200 8N1芯片最高 20kbps模式DE 脚自动切换收发发送 高接收 低协议帧头 地址 命令 长度 数据 校验工业标准格式二、完整代码文件1. ESA6218HA.h头文件#ifndef __ESA6218HA_H #define __ESA6218HA_H #include stm32f1xx_hal.h /* 引脚配置 */ #define ESA6218_TX_PIN GPIO_PIN_9 #define ESA6218_TX_PORT GPIOA #define ESA6218_RX_PIN GPIO_PIN_10 #define ESA6218_RX_PORT GPIOA #define ESA6218_DE_PIN GPIO_PIN_8 #define ESA6218_DE_PORT GPIOA #define ESA6218_UART USART1 #define ESA6218_BAUDRATE 19200 /* 协议定义 */ #define FRAME_HEAD 0xAA // 帧头 #define FRAME_ADDR 0x01 // 默认本机地址 #define MAX_DATA_LEN 16 // 最大数据长度 /* 帧结构 */ typedef struct { uint8_t head; // 帧头 0xAA uint8_t addr; // 地址 uint8_t cmd; // 命令 uint8_t len; // 数据长度 uint8_t data[MAX_DATA_LEN]; // 数据 uint8_t check; // 校验(异或) } ESA6218_FrameTypeDef; /* 外部函数 */ void ESA6218_Init(void); void ESA6218_SendFrame(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len); uint8_t ESA6218_ReceiveFrame(ESA6218_FrameTypeDef *frame); void ESA6218_Start_IT_RX(void); #endif2. ESA6218HA.c驱动实现#include ESA6218HA.h extern UART_HandleTypeDef huart1; /* ---------------- 发送模式DE1 ---------------- */ void ESA6218_SetTxMode(void) { HAL_GPIO_WritePin(ESA6218_DE_PORT, ESA6218_DE_PIN, GPIO_PIN_SET); HAL_Delay(1); // 总线稳定 } /* ---------------- 接收模式DE0 ---------------- */ void ESA6218_SetRxMode(void) { HAL_GPIO_WritePin(ESA6218_DE_PORT, ESA6218_DE_PIN, GPIO_PIN_RESET); HAL_Delay(1); } /* ---------------- 初始化 ---------------- */ void ESA6218_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); // DE 引脚推挽输出 GPIO_InitStruct.Pin ESA6218_DE_PIN; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(ESA6218_DE_PORT, GPIO_InitStruct); // 默认进入接收模式 ESA6218_SetRxMode(); // UART1 初始化在 MX_USART1_UART_Init() 中完成 } /* ---------------- 计算异或校验 ---------------- */ uint8_t ESA6218_CheckSum(uint8_t *buf, uint8_t len) { uint8_t sum 0; for(uint8_t i0; ilen; i) sum ^ buf[i]; return sum; } /* ---------------- 发送一帧数据 ---------------- */ void ESA6218_SendFrame(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) { uint8_t buf[32] {0}; uint8_t index 0; buf[index] FRAME_HEAD; buf[index] addr; buf[index] cmd; buf[index] len; for(uint8_t i0; ilen; i) buf[index] data[i]; buf[index] ESA6218_CheckSum(buf, index); // 切换发送并发送数据 ESA6218_SetTxMode(); HAL_UART_Transmit(huart1, buf, index, 50); ESA6218_SetRxMode(); } /* ---------------- 阻塞接收一帧带校验 ---------------- */ uint8_t ESA6218_ReceiveFrame(ESA6218_FrameTypeDef *frame) { uint8_t buf[32]; uint8_t len 0; ESA6218_SetRxMode(); // 等待帧头 if(HAL_UART_Receive(huart1, buf, 1, 100) ! HAL_OK) return 0; if(buf[0] ! FRAME_HEAD) return 0; // 接收地址命令长度 if(HAL_UART_Receive(huart1, buf[1], 3, 100) ! HAL_OK) return 0; len buf[3]; if(len MAX_DATA_LEN) return 0; // 接收数据 校验 if(HAL_UART_Receive(huart1, buf[4], len1, 100) ! HAL_OK) return 0; // 校验判断 uint8_t check ESA6218_CheckSum(buf, 4len); if(check ! buf[4len]) return 0; // 填充帧结构体 frame-head buf[0]; frame-addr buf[1]; frame-cmd buf[2]; frame-len buf[3]; for(uint8_t i0; ilen; i) frame-data[i] buf[4i]; frame-check buf[4len]; return 1; } /* ---------------- 开启中断接收 ---------------- */ void ESA6218_Start_IT_RX(void) { ESA6218_SetRxMode(); __HAL_UART_ENABLE_IT(huart1, UART_IT_RXNE); HAL_NVIC_EnableIRQ(USART1_IRQn); }3. usart.cUART 初始化必须配套#include usart.h UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void) { huart1.Instance USART1; huart1.Init.BaudRate 19200; huart1.Init.WordLength UART_WORDLENGTH_8B; huart1.Init.StopBits UART_STOPBITS_1; huart1.Init.Parity UART_PARITY_NONE; huart1.Init.Mode UART_MODE_TX_RX; huart1.Init.HwFlowCtl UART_HWCONTROL_NONE; huart1.Init.OverSampling UART_OVERSAMPLING_16; HAL_UART_Init(huart1); } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct {0}; if(uartHandle-InstanceUSART1) { __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); // PA9 TX 复用推挽 GPIO_InitStruct.Pin GPIO_PIN_9; GPIO_InitStruct.Mode GPIO_MODE_AF_PP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); // PA10 RX 上拉输入 GPIO_InitStruct.Pin GPIO_PIN_10; GPIO_InitStruct.Mode GPIO_MODE_INPUT; GPIO_InitStruct.Pull GPIO_PULLUP; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); } }4. main.c主函数调用示例#include main.h #include usart.h #include gpio.h #include ESA6218HA.h int main(void) { // 系统初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); // ESA6218 初始化 ESA6218_Init(); // 开启中断接收可选 // ESA6218_Start_IT_RX(); // 发送测试数据 uint8_t tx_data[4] {0x11, 0x22, 0x33, 0x44}; // 接收帧结构体 ESA6218_FrameTypeDef rx_frame; while(1) { // 1. 发送一帧地址0x01命令0x03数据4字节 ESA6218_SendFrame(0x01, 0x03, tx_data, 4); HAL_Delay(1000); // 2. 接收一帧 if(ESA6218_ReceiveFrame(rx_frame)) { // 接收成功处理数据 // rx_frame.addr // rx_frame.cmd // rx_frame.data[] } } }三、通信协议工业标准帧格式[0xAA][地址][命令][数据长度][数据N][异或校验] 1B 1B 1B 1B N B 1B功能说明帧头0xAA 用于同步防止干扰地址支持一主多从组网1~255命令可自定义开关、读取、设置等功能长度数据段长度最大 16 字节校验异或校验抗干扰强自动收发DE 引脚自动切换无需手动干预四、工程使用要点DE 必须切换发送前拉高发送后拉低速率不超过 19200ESA6218HA 最高支持 20kbps总线推荐RTX 上拉 10kΩ 到 VCCH串 100Ω 电阻校验必须开启工业环境必须防错中断接收可调用ESA6218_Start_IT_RX()实现后台接收总结我给你的是完整可直接编译的 ESA6218HA 软件包初始化UART GPIO DE 收发控制发送自动组帧 校验 自动切换 DE接收帧头校验 数据校验 数据解析协议标准工业帧格式支持一主多从