尚视界科技有限公司

当前位置: 首页 > 新闻资讯 > 产品新闻 > 串口屏SF035(ESP32-S3)开发

产品新闻

日期:2026-03-05 10:05:17      浏览次数:

主包在此记录的第一个小项目,这个项目的功能相对简单,主控连接上WiFi后,首先进行实践同步,同步成功后显示在屏幕上。也就是一个简单的桌面小型时钟吧。同时我还连接了一个DHT11 温湿度模块来检测环境的温湿度。当然,这几个功能就略显得简单了,后续主包还会在上面添加比如闹钟、天气显示等功能来添加可玩性。


主要硬件介绍

      

  本次带来的项目选用了尚视界科技的串口彩屏模块SF-035,3.5寸大小。与传统的LCD+触摸屏方案相比,这一块串口屏可以通过自带的sHMI设计 工具,通过拖拽的方式来设计页面元素,不需要编写复杂的图形库。同时屏幕与ESP32-S3开发板的链接仅依靠2条通讯线:RX、TX,这样减少了引脚的占用。同时与LVGL相比,这种方案的资源占用较低,主控只需要通过UART发送指令即可控制显示内容,这样大大节约了MCU的资源。






硬件连接

这里使用ESP32-S3的UART1里的GPIO17和GPIO18与屏幕的TX、RX相连接。DHT11温湿度模块的DAT线连在了GPIO4。这里串口使用到的波特率为115200。这里想起来遇到的一道笔试题:波特率115200代表了什么意思,主包当时没想起来,结果就被刷掉了。


项目信息

硬件:ESP32-S3、SF035-HVGA-ST-01-V02

开发环境:ESP-IDF v5.5.0


页面设计

以下是主包设计的UI界面:

设计这个主界面这样子主要是写的时候已近马年春节,祝看到这里的朋友春节快乐。

这个软件的sHMI设计软件的使用还是比较方便的,基本包含了常见的控件。这里我使用了标签来显示文本内容,曲线用来显示当前的温湿度变化,码表我设计成钟表的样式来显示时间。


软件架构设计

作为一个完整的项目,我没有把所有代码都堆在main.c里,而是将代码按功能模块进行了划分:

这样分层有几个好处:1. 职责清晰:每个模块只做一件事,比如uart_comm只负责收发数据;2. 易于测试:可以单独测试每个模块;3. 方便扩展:要加新功能只需要添加新模块,不用改动原有代码;4. 便于维护:出问题时能快速定位到具体模块


核心功能实现

1. WiFi连接与NTP时间同步

WiFi连接流程

这部分我使用了ESP-IDF提供的WiFi API,主要步骤如下:

1. 初始化WiFi

2. 连接WiFi

3. 等待连接成功

这里使用了FreeRTOS事件组来等待WiFi连接:


NTP时间同步

WiFi连接成功后,就可以进行时间同步了:


遇到的问题

问题1:时间同步一直失败

原因:防火墙拦截了UDP 123端口

解决:换了个NTP服务器(ntp.aliyun.com)就好了

问题2:时区不对,显示的是UTC时间

解决:设置时区为中国标准时间



2. 串口屏通信协议

串口屏通信协议

这是整个项目的十分重要的部分,也是我花时间最多的地方。

协议格式

SF035串口屏使用固定的帧格式,所有指令均为大端序:

其中帧尾固定为:FF FC FF FF

常用指令实现

文本显示指令

这是最常用的,主包在这个项目中用它用来更新时间、日期等文本:

要注意单次发送的文本不宜过长,建议控制在100字节以内,不然会爆。

曲线控件指令

主包用曲线控件来显示温湿度变化曲线:

注意:


 1.曲线控件支持多条曲线,通过曲线ID区分(这里主包用0表示温度,1表示湿度)

 2.数据会自动滚动推移,无需手动管理历史数据

 3.建议采样间隔不要太短,5秒左右比较合适

码表控件指令


这个是我觉得很帅的功能,可以做出模拟时钟效果,这里需要说明的是:


 1.控件ID: 钟表控件的ID

 2.角度: 0-359度

 3.指针ID: 0=时针, 1=分针, 2=秒针

其中还包含了角度的计算问题

这里开发的时候要注意:

  1. 1.角度计算需要考虑控件的初始朝向,主包当时选择的控件12点方向对应180度
  2. 2.时针角度 = (小时%12) * 30 + 分钟/2 + 偏移量
  3. 3.分针角度 = 分钟 * 6 + 偏移量
  4. 4.刷新频率1秒即可,过快会增加串口负担

页面ID查询机制

这是主包在开发中遇到的一个重要问题的解决方案。


问题:切换到其他页面后,原页面的控件仍在刷新,导致串口拥塞和画面干扰。就比如我在页面2的控件里看到了本应该在页面1更新的数据。这是因为

控件修改指令时没有页面ID导致不同页面的ID串通的现象。因此主包使用了页面ID查询机制,因为屏幕支持页面ID的查询,在查询当前页面后得到页面

ID后,根据页面ID启停不同的数据发送任务。这个机制大大提升了系统的稳定性和响应速度。这里需要在设计界面打开“触摸控件输出坐标点”

按钮事件处理

1.按钮事件帧格式

串口屏的按钮被按下时,会通过UART回传事件帧:

2.事件解析实现

我使用了一个专门的按钮处理模块:

应用场景:

  1. 页面切换:通过按钮在不同页面间跳转
  2. LED控制:按钮控制WS2812 RGB灯的开关
  3. 计算器输入:数字和运算符按钮

遇到的问题

问题1:中文乱码


原因:编码格式不对,我以为是GBK,所以出现了乱码,在查询了说明书后发现其实是UTF-8


解决:确保源文件保存为UTF-8编码


问题2:指令发送后没反应


排查过程:


  1. 用串口打印日志发现帧尾少了一个字节


  2. 检查代码,发现数组越界了


解决:增加缓冲区大小,添加边界检查


问题3:频繁发送导致屏幕卡顿


问题:每秒发送太多数据,屏幕响应变慢


解决:


  1. 只在数据变化时才发送


  2. 不同页面只发送当前页面需要的数据


  3. 降低刷新频率(温湿度从1秒改为5秒)

3.多任务设计

FreeRTOS多任务设计

ESP32-S3基于FreeRTOS,我充分利用了多任务的优势。

任务划分

我创建了以下几个任务:

优先级设置

高优先级(5):串口接收任务,需要及时响应按钮事件

中优先级(3):时间更新和钟表刷新,保证显示流畅

低优先级(2):传感器采集,不需要太实时

任务同步

使用互斥锁保护共享资源


为什么要用多任务?

如果不用多任务,代码会变成这样:

这样就会出现,所有功能都在一个循环里,耦合严重;同时延时会影响所有功能的响应速度;最后就是难以控制每个功能的更新频率。而使用了多任务后,每个功能独立运行,互不影响;还可以为每个任务设置不同的更新频率;而且高优先级任务可以抢占低优先级任务。

4.调试与优化

调试过程与优化

1. ESP-IDF监视器

可以实时查看日志,非常方便。

2. 指令调试

sHMI设计软件还提供了专门的指令调试功能,可以用来分析发出的指令是否正确

实际应用

功能页面

我的项目实现了3个功能页面:

Page 0 - 主页面

  1. 1.WiFi连接状态显示
  2. 2.实时时间显示(年月日时分)
  3. 3.模拟时钟显示
  4. 4.时针、分针实时走动
  5. 5.星期显示(中文)
  6. 6.温湿度曲线实时显示

Page 1 - 控制页面

  1. 1.LED灯控制按钮
  2. 2.页面跳转按钮

数据更新策略

针对不同类型的数据,我采用了不同的更新策略:

这样的策略既保证了显示的实时性,又避免了串口带宽浪费。


性能优化


优化1:减少串口发送频率

优化前:每秒发送所有数据、串口利用率80%以上、屏幕有时会卡顿

优化后:只在数据变化时发送、根据页面ID控制发送内容、串口利用率降到30%以下

优化2:内存优化

问题:频繁malloc/free导致内存碎片

解决:

优化3:任务栈大小调整

问题:某些任务栈溢出导致重启

解决:


写在最后

这是我第一次完整地做一个嵌入式项目,虽然功能还比较简单,但整个过程让我收获很多。


从一开始的迷茫,到慢慢理清思路,再到最后看到屏幕上显示出时间的那一刻,那种成就感是无法用言语形容的。


当然,这个项目还有很多需要改进和拓展的地方。希望这篇文章能帮到正在学习的你。如果有任何问题,欢迎交流讨论!


最后,祝大家春节快乐,马年大吉!




————————————————

版权声明:本文为CSDN博主「尔多隆了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/m0_74220243/article/details/157469977