OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 820|回复: 3

HMI串口屏与STM32F1串口通信例子

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2025-1-23
在线时间
3 小时
发表于 2026-4-24 22:53:35 | 显示全部楼层 |阅读模式
1金钱
跪求HMI串口屏与STM32F1串口通信例子

最佳答案

查看完整内容[请看2#楼]

以下是 STM32F1 与 HMI串口屏(如迪文屏、淘晶驰屏等)的串口通信完整示例代码及说明。包含 STM32发送数据 和 接收HMI指令并响应 的核心逻辑。 一、硬件接线(UART 直连) STM32F1 (PA9/PB6) HMI串口屏 TX (输出) → RX RX (输入) → TX GND → GND VCC (可选) → VCC 确保共地!否则通信异常。 二、STM32F1 工程配置(基于标准库) 1. USART 初始化(波特率 115200,8N1) ...
回复

使用道具 举报

0

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2026-1-29
在线时间
21 小时
发表于 2026-4-24 22:53:36 | 显示全部楼层
本帖最后由 664929323 于 2026-4-27 15:05 编辑

以下是 STM32F1 与 HMI串口屏(如迪文屏、淘晶驰屏等)的串口通信完整示例代码及说明。包含 STM32发送数据 和 接收HMI指令并响应 的核心逻辑。

一、硬件接线(UART 直连)
STM32F1 (PA9/PB6)        HMI串口屏
TX (输出) → RX        
RX (输入) → TX        
GND → GND        
VCC (可选) → VCC        确保共地!否则通信异常。

二、STM32F1 工程配置(基于标准库)
1. USART 初始化(波特率 115200,8N1)

#include "stm32f10x.h"

void UART_Init(void) {
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
   
    // 配置 PA9 -> TX, PA10 -> RX
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 推挽复用输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    // 配置 USART1
    USART_InitTypeDef USART_InitStruct;
    USART_InitStruct.USART_BaudRate = 115200;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStruct);
   
    // 使能中断(用于接收)
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    NVIC_EnableIRQ(USART1_IRQn);
   
    USART_Cmd(USART1, ENABLE); // 使能串口
}

      
三、发送数据函数(带回车换行)
      
void UART_SendString(char *str) {
    while (*str != '\0') {
        USART_SendData(USART1, *str++);
        // 等待发送完成
        while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    }
}

// 发送整数(转字符串)
void UART_SendInt(uint16_t num) {
    char buf[10];
    sprintf(buf, "%d", num);
    UART_SendString(buf);
}

      
四、接收中断 + 指令解析(核心!)
      
#define RX_BUFFER_SIZE 64
char rxBuffer[RX_BUFFER_SIZE];
uint8_t rxIndex = 0;
uint8_t commandReady = 0;

void USART1_IRQHandler(void) {
    uint8_t data = USART_ReceiveData(USART1);
   
    if (data == '\n') { // 假设HMI每条指令以换行结束
        rxBuffer[rxIndex] = '\0'; // 字符串结尾
        commandReady = 1;           // 标记指令就绪
        rxIndex = 0;                // 重置索引
    } else if (data == '\r') {
        // 忽略回车符(可选)
    } else {
        if (rxIndex < RX_BUFFER_SIZE - 1) {
            rxBuffer[rxIndex++] = data;
        } else {
            rxIndex = 0; // 缓冲区溢出,清空重来
        }
    }
}

// 在主循环处理指令
void Process_Command(void) {
    if (commandReady) {
        // 例:收到 "LED ON" 打开LED
        if (strncmp(rxBuffer, "LED ON", 6) == 0) {
            GPIO_SetBits(GPIOB, GPIO_Pin_5); // LED亮
            UART_SendString("OK\r\n");        // 回复HMI
        }
        // 例:收到 "LED OFF" 关闭LED
        else if (strncmp(rxBuffer, "LED OFF", 7) == 0) {
            GPIO_ResetBits(GPIOB, GPIO_Pin_5); // LED灭
            UART_SendString("OK\r\n");
        }
        // 例:收到 "GET TEMP" 返回温度值
        else if (strncmp(rxBuffer, "GET TEMP", 8) == 0) {
            uint16_t temp = Read_Temperature(); // 你的传感器读取函数
            UART_SendString("TEMP=");
            UART_SendInt(temp);
            UART_SendString("\r\n");
        }
        
        commandReady = 0; // 清除标志
    }
}

      
五、主函数模板
      
int main(void) {
    SystemInit();          // 系统时钟初始化(确保已配置)
    UART_Init();           // 串口初始化
   
    // 初始化LED(PB5)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitTypeDef gpio;
    gpio.GPIO_Pin = GPIO_Pin_5;
    gpio.GPIO_Mode = GPIO_Mode_Out_PP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &gpio);
   
    while (1) {
        // 主动上报数据(例如每秒发送一次温度)
        UART_SendString("STATUS=OK\r\n");
        Delay(1000); // 自定义延时函数
        
        // 处理HMI发来的指令
        Process_Command();
    }
}

      
六、HMI串口屏端配置建议(迪文/淘晶驰通用)
波特率:115200(与STM32一致)
数据格式:8位数据位,无校验,1位停止位(8N1)
发送指令示例:
点亮LED → 发送 LED ON\r\n
获取温度 → 发送 GET TEMP\r\n
接收显示:设置HMI接收缓冲区,解析 STATUS=OK 或 TEMP=25 等数据更新界面。
七、调试技巧
用USB转串口工具监听:将STM32的TX接到电脑串口助手,验证发送内容。
HMI日志功能:启用HMI的串口调试模式,查看收发原始数据。
添加心跳包:定期发送 HEARTBEAT\r\n,确认链路通畅。
八、常见问题解决
现象        原因        解决方案
HMI无反应        接线错误/未共地        检查TX/RX/GND
乱码        波特率不匹配        双方统一为115200
指令无效        缺少结束符        确保发送 \r\n
程序卡死        接收缓冲区溢出        增加 RX_BUFFER_SIZE
提示:不同HMI厂商可能有私有协议(如迪文DGUS),若需图形界面交互,请参考对应HMI的《串口指令集》文档扩展本例程。

按此框架修改即可快速实现STM32与HMI串口屏的双向通信!
回复

使用道具 举报

1

主题

29

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2980
金钱
2980
注册时间
2014-7-29
在线时间
182 小时
发表于 2026-4-27 09:11:55 | 显示全部楼层
自己去找个HMI串口屏的厂家 资料内基本都有STM32的例程
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2025-1-23
在线时间
3 小时
 楼主| 发表于 2026-4-30 10:16:22 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-5-16 14:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表