前言

在人机交互系统开发中,串口屏(HMI)与单片机(MCU)的通讯,本质上是主机(MCU)和从设备(屏)之间的数据交换。

以三易串口屏开发架构来看,通讯主要分为两种模式:

系统指令通讯模式(ASCII指令方式)

自定义协议通讯模式(二进制协议方式)

两种模式均适配市面主流单片机开发平台,包括:

  • Keil MDK(STM32、51、GD32等)
  • STM32CubeIDE
  • Arduino IDE
  • ESP-IDF(ESP32官方开发环境)
  • (扩展)IAR Embedded Workbench

其底层本质一致:

单片机程序 → UART发送数据 → 串口屏接收解析 → 更新控件

一、串口屏通讯基本原理

1.1 硬件连接

通常使用UART:

MCU TX ----> LCD RX

MCU RX <---- LCD TX

GND ------ GND

典型参数:

  • 115200
  • 8 Data Bits
  • 1 Stop Bit
  • No Parity

二、方式一:系统指令通讯

2.1 协议格式

ASCII格式:

命令 + 参数 + \r\n

结束符:

0D 0A

例如:

页面切换

page 0\r\n

设置控件值

wset numVf.valf 3.45\r\n

wset numA.val 120\r\n

wset text.txt "电量充足"\r\n

查询属性

wget numA.val\r\n

模拟按键触发

click button0\r\n

2.2 返回数据解析

条件

只有当系统变量bkcmd为非0的时候才会返回指令执行成功或者失败数据。

格式

返回指令格式为 命令码(1字节)+参数(长度随命令码而不同)+结束符(2字节,\r\n)

数据

所有指令名以及参数全部16进制数据,非ASCII数据,便于软件解析。

命令码

含义

格式

参数说明

0x00

指令执行结果

执行结果代码

+返回数据

+结束符(\r\n)

执行结果代码:1字节

0x00  指令执行成功

0x01  命令码无效(指令第一个字符串无效)

0x02  指令参数1无效(指令第二个字符串无效)

0x03  指令参数2无效(指令第三个字符串无效)

0x04  指令参数3无效(指令第四个字符串无效)

0x05  指令参数4无效(指令第五个字符串无效)

0x06  指令参数5无效(指令第六个字符串无效)

0x07  指令参数个数错误

0x08  串口接收超时

说明:

命令执行结果返回值,主要用于客户取得串口屏控件的属性值,响应客户发送的命令,如果客户发送的指令有错,例如命令码拼写错误,属性名称拼写错误,属性名称拼写错误等,造成串口屏不能解析,将返回不同的错误码,方便客户查错。

只有当系统变量bkcmd为非0的时候才会返回指令执行成功或者失败数据。

这个命令提供了一种客户的调试命令的方式,大部分情况下,在调试完毕后,都会把系统变量bkcmd置0,不会收到此命令。

举例:如果客户发送指令的命令码拼写错误,返回:“00010d0a”。解释:从左到右,00 表示返回的命令码,01表示命令码无效,0d表示 \r,0a表示 \n。

0x01

整数返回

0x01+4字节整数+结束符

4字节整数:4字节小端模式存储,低字节在前

0x02

小数返回

0x02+4字节小数+结束符

4字节小数:4字节小端模式存储,低字节在前

0x03

字符串返回

0x03+字符串+结束符

字符串:GBK编码

返回结果包括客户发起的命令执行情况和需要返回的数据。执行情况即执行结果,需要返回的数据主要是取串口屏控件属性的值。值的类型为整数,小数,字符串。

举例:获取按钮1的x坐标。发送指令“wget button1 x\r\n”,返回为:“01880000000d0a”

解释:01 表示返回值为整数;88000000表示位buttton1的 x坐标,低字节在前的格式;0D0A是命令结束符。

如果系统变量bkcmd没有设置为0,这个指令会接收到两个返回指令,“00000d0a”,和“01880000000d0a”,第一个指令表示命令执行成功,第二个指令是用户需要的结果。如果系统变量bkcmd设置为0,则只返回第二个指令(默认不返回执行成功或失败)。

三、Keil MDK 与串口屏通讯

3.1 串口发送函数

3.2 发系统指令

3.3 注意事项

每条指令间建议加微延时:

delay_ms(1);

避免命令粘连。

四、STM32CubeIDE 与串口屏通讯

五、Arduino IDE 与串口屏通讯

示例

void setup()

{

Serial.begin(115200);

}

void loop()

{

Serial.println("wset temp.val 25");

delay(500);

println自动补:

\r\n

非常适合快速验证。

六、ESP-IDF(ESP32)通讯

UART配置

uart_config_t cfg={

.baud_rate=115200,.data_bits=UART_DATA_8_BITS,.parity=UART_PARITY_DISABLE,.stop_bits=UART_STOP_BITS_1

};

发送指令

char *cmd="wset led.val 1\r\n";

uart_write_bytes(UART_NUM_1,cmd,strlen(cmd));

七、IAR开发平台

与Keil本质一致。

printf("page 1\r\n");

重定向printf即可驱动屏。

八、自定义协议通讯(推荐)

系统指令适合简单界面。

复杂项目推荐自定义协议。

8.1 协议格式

示例协议:

帧头 命令 数据 CRC

A5 43 01 xxxx xxxx

命令定义:

  • 01 电压
  • 02 电流
  • 03 SOC

数据小端:

低字节在前

高字节在后

CRC16多项式:

8005

8.2 MCU组帧发送

Keil代码:

str[0]=0xA5;

str[1]=0x43;

str[2]=0x01;

str[3]=V&0xff;

str[4]=V>>8;

crc=Get_CRC16(5,str);

str[5]=crc&0xff;

str[6]=crc>>8;

USART_OUT(str,7);

发送:

A5 43 01 7C 01 91 86

代表:

3.80V

九、屏端协议解析

十、主机与屏双向通讯

MCU→屏

  • 显示参数
  • 切页
  • 改图片
  • 触发事件

屏→MCU

屏脚本:

uartSend("START");

发送字节:

byte a[5]={01,02,03,04,05};

uartSendBytes(a,0,5);

MCU解析:

if(strcmp(rx,"START")==0)

{

motor_run();

}

形成双向交互。

十一、开发平台对比

十二、两种通讯模式对比

系统指令模式

优点:

  • 简单
  • 不设计协议
  • 调试方便

缺点:

  • 数据量大效率低
  • 多控件更新麻烦

示例:

wset numVf.valf 3.45

wset numA.val 120

wset psoc.val 95

三条指令。

自定义协议模式

优点:

  • 一帧可更新多个控件
  • 效率高
  • 更适合量产项目

推荐优先使用。

十三、通讯常见问题

1 白屏但程序正常

排查:

  • TX/RX接反
  • 波特率错误
  • MCU IO被击穿
  • 命令没带\r\n
  • 多条指令粘连  

2 中文乱码

编码一致:

VP工程 GBK

Keil GB2312/GBK

否则中文异常。

3 自定义协议无响应

检查:

  • 帧头
  • 长度
  • CRC
  • 小端格式

十四、完整实例架构(推荐)

MCU层

├─串口驱动

├─协议组帧

├─CRC校验

屏端

├─协议解析器

├─控件刷新

├─触摸事件回传

这是当前串口屏最典型架构。

总结

主流单片机开发平台,无论是:

  • Keil
  • STM32CubeIDE
  • Arduino IDE
  • ESP-IDF
  • IAR

与串口屏通讯本质一致,都是UART数据收发。

区别只是:

  • 发送函数写法不同
  • 底层驱动不同

而通讯模型只有两种:

  • 系统指令
  • 自定义协议

如果界面简单,用系统指令;

如果项目量产,建议自定义协议+协议解析器方案。

系统指令通讯模式(ASCII指令方式)

自定义协议通讯模式(二进制协议方式)

两种模式均适配市面主流单片机开发平台,包括:

  • Keil MDK(STM32、51、GD32等)
  • STM32CubeIDE
  • Arduino IDE
  • ESP-IDF(ESP32官方开发环境)
  • (扩展)IAR Embedded Workbench

其底层本质一致:

单片机程序 → UART发送数据 → 串口屏接收解析 → 更新控件

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐