☰
STM32+迪文屏DGUS打造智能家居温湿度控制面板
2026/9/28 5:56:30 网站建设 项目流程

去年给家里做智能家居改造时,一直困扰我的不是传感器选型,也不是继电器驱动,而是“人机交互”这一块。手机App控制当然方便,但每次开关灯、看数据都要掏手机解锁打开App,时间一长就觉得很繁琐。后来接触到迪文屏和DGUS组态开发,发现这东西非常适合做墙面固定面板——串口一接、变量一配,就能做出带触摸的彩色控制界面,不用自己折腾复杂的GUI库。再加上一颗STM32做数据采集和逻辑联动,整套系统的完整度一下子就上来了。这篇就把我这次用迪文屏做温湿度控制面板的过程拆开揉碎讲清楚,硬件选型、DGUS工程配置、STM32端协议代码、常见坑位,一次性整理出来。

1. 整体设计与思路拆解

1.1 需求定位:面板到底要解决什么问题

这套智能家居控制面板的项目需求并不复杂,核心是三个:把环境温湿度数据以直观、美观的方式显示在墙面上;允许用户通过触摸直接设置温湿度上下限阈值;当温度或湿度越限时,STM32负责输出控制信号,去驱动风扇、加湿器这类外部负载。也就是说,面板并不是一个单纯显示的数码管温度计,而是“显示 + 输入 + 联动控制”的完整节点。

很多初学者有一个思维定式:想做界面就上正点原子的RGB屏,然后移植LVGL或emWin。这个路线可行,但代价是学习成本很高,而且每次改界面布局都要重新编译固件、重新烧录,效率很低。这个项目里我选择迪文屏,核心逻辑就是“数据和界面分离”——界面布局、图片切图、控件配置全部在PC端完成,生成配置文件下载到屏幕Flash;运行时STM32只负责往指定变量地址写数据,屏幕就会自动刷新显示内容。触摸事件的回传也一样,用户按了哪个按钮,屏幕会把对应的键值或数据通过串口发给STM32,由STM32来决定下一步逻辑。这一套流程对单片机的性能要求极低,对开发效率的提升却很可观。

1.2 系统架构与工作流程

整套系统的数据流可以拆成三个环节:

  • 采集环节:STM32通过GPIO或I2C读取温湿度传感器(DHT11/DHT22/SHT30),得到当前环境的温度和湿度值。
  • 交互环节:STM32将温湿度数值通过串口发送给迪文屏指定变量地址,屏幕实时更新显示;同时用户通过屏幕的触摸控件设置目标阈值,屏幕将用户输入的数据回传给STM32。
  • 执行环节:STM32将采集值与阈值做比较,通过PID或滞回逻辑控制继电器,继电器再驱动风扇、加热器、加湿器等负载。

这个架构最大的优点是耦合度低。如果你以后想换LCD屏,只需要保证串口协议不变,改显示层的物理实现即可;如果要加更多传感器,STM32端加采集代码就行,屏幕上预留好变量地址就能直接显示新数据。实际上这也是工业HMI常见的设计套路:MCU专注于控制逻辑,屏幕专注于显示交互。

1.3 硬件选型与成本权衡

硬件清单如下:

模块型号/规格作用参考成本
主控MCUSTM32F103C8T6数据采集、通信、逻辑控制约10元
温湿度传感器DHT11 / DHT22 / SHT30环境温湿度采集5-25元
迪文屏DMG80480C070_04WTC(7寸)人机交互显示与触摸150-250元
继电器模块5V单路/双路控制风扇、加湿器等负载5-15元
电源12V/5V双输出电源模块系统供电20元

选STM32F103C8T6不是因为性能多强,而是因为资料多、价格低、入门门槛低,就算新手也能很快上手标准库或HAL库开发。传感器这里我推荐SHT30,精度比DHT11高一个量级,而且是I2C接口,代码写起来比DHT11的单总线时序要简单很多。不过考虑到很多人手里只有DHT11,后面我会把两种都提一下。迪文屏选7寸电容屏,是因为作为墙面面板,显示面积大一些,数字和触摸区域不会显得局促;如果板材开孔尺寸有限,4.3寸的DMT48270C043也完全可以,下位机代码几乎不需要改动。

2. DGUS开发核心细节与实操要点

2.1 DGUS到底是什么,跟普通串口屏有什么区别

迪文屏之所以叫“智能屏”,核心在于它内部运行着一套DGUS系统,这套系统把传统的“屏幕外设”变成了“变量映射终端”。DGUS的全称是DGUS Graphic Utility Software,它定义了一套变量地址与显示/触控控件的映射关系。你在PC端的DGUS软件里,在背景图片上放置一个“数据变量显示”控件,指定它显示内存地址0x1000处的数据,再设置数据类型为无符号整型;下载到屏幕后,只要串口收到指令往0x1000地址写入新数值,屏幕上的对应位置就会自动刷新成新的数字。整个过程完全不涉及屏幕端的代码编程,界面交互逻辑全部通过配置文件描述。

这里有一个非常重要的思维转换:不要再去想“屏幕执行代码”这件事。DGUS屏的运行模式是——屏幕负责“画”,MCU负责“算”。屏幕把用户的触摸行为转换成数据帧发给MCU,MCU把要显示的数据按协议发给屏幕,屏幕只是忠实呈现。理解了这一点,整个开发思路就清晰多了,也不会在后期联调时搞混“数据到底存在谁那里”的问题。

2.2 变量地址规划方案

一份好的变量地址表是整个项目的地基。地址规划不好,后面写代码和配置控件容易混乱,甚至出现地址覆盖导致数据错乱。建议按功能模块划分地址区间:

地址长度数据类型含义
0x10001 Word带符号整数当前温度值(放大10倍)
0x10011 Word带符号整数当前湿度值(放大10倍)
0x11001 Word无符号整数温度上限设置值
0x11011 Word无符号整数温度下限设置值
0x12001 Word无符号整数湿度上限设置值
0x12011 Word无符号整数湿度下限设置值
0x13001 Word无符号整数联锁/手动模式切换标志
0x13011 Word无符号整数继电器开关状态反馈

地址规划的原则是:显示数据区、设置参数区、控制状态区完全分开。显示数据是只读的,MCU单方向往屏上写;设置参数是双向的,用户触摸写入后MCU要能读回来;控制状态则是状态反馈,用于屏幕显示当前继电器是开还是关。按区间划分后,无论是你写代码还是后续调试,出了故障都能快速定位是哪个区的问题。

2.3 DGUS工程配置流程

用DGUS做界面,最核心的步骤在PC端完成。以7寸屏为例,流程如下:

  1. 准备一张800×480的底图。不要用自带的美观图片模板,建议用制图软件做一张深色背景、带清晰数字区域的工业风底图,底图上温度显示区、湿度显示区、阈值设置区、按钮区域都要规划好坐标。
  2. 用DGUS软件新建工程,选择对应的屏型号。这里一定要选对型号,比如DMG80480C070对应的是T5L1芯片平台,如果用T5L2的配置,下载工程后会出现莫名其妙的花屏。
  3. 导入底图后,在图片上放置控件。首先放“数据变量显示”控件:设置变量地址0x1000,数据类型为有符号整数,整数位数3位,小数位数1位(因为我们在STM32端把温度放大10倍发送)。然后放“触摸设置”控件:地址设为0x1100,设置类型选择“上限值”,取值范围0到600。
  4. 配置返回到“设置页面”的按钮,按下后清空当前输入焦点或跳转页面,这个看具体需求。
  5. 编译工程,生成DWIN_SET文件夹,将这个文件夹整个拷贝到SD卡的根目录,把SD卡插入屏幕背面卡槽,上电后屏幕会自动升级配置文件,等待蓝屏或提示完成即可。

这里有个极其容易踩的坑是SD卡升级问题。迪文屏对SD卡的要求比较严格,最好使用FAT32格式、容量不超过16G的卡,且卡内不要套文件夹,DWIN_SET文件夹必须是根目录下唯一运行目录。升级过程中屏幕如果直接停在开机画面不动,基本就是配置文件和屏型号对不上,或者SD卡格式有问题。

2.4 显示控件数据类型的选择

DGUS里的数据变量显示控件支持多种格式:无符号整型、有符号整型、长整型、浮点型、字符串等。温湿度显示这里最常见的坑是负数温度的处理。冬天环境温度可能降到零下,如果用无符号整型,-5℃会被显示成65531,非常离谱。所以温度值在STM32端发送时,建议统一放大10倍,用有符号整型表示:-5℃对应-50。这样DGUS端只要设置小数位数为1位,显示出来就是-5.0,干净利落。湿度同理,放大10倍后显示。这是在工程配置阶段就要确定下来的约定,不然后面改起来也很麻烦。

3. STM32端逻辑实现与协议联调

3.1 底层硬件初始化

STM32端主要用到两个外设:I2C读取SHT30或单总线读取DHT11,以及USART1与迪文屏通信。时钟配置这里不多讲,直接说几个关键点:

开启I2C1和USART1的时钟,配置USART1为115200-8-N-1模式。迪文屏默认波特率115200,但T5L平台可以通过配置文件设置波特率。为了稳定性,建议115200,不高不低,线缆稍长也不容易出错。

GPIO方面,SHT30的SCL和SDA要配置为开漏输出,并外接4.7k上拉电阻;如果是DHT11,则数据引脚配置成推挽输出/开漏输出切换的模式,按单总线时序进行读写。

USART1的TX/RX直接接迪文屏的RXD/TXD,注意是屏的RXD接STM32的TX,交叉连接。有些屏的接口电平是3.3V TTL,STM32F103也是3.3V,可以直接互连;如果使用5V供电的MCU或屏,需要加电平转换模块,否则容易烧引脚。

3.2 温湿度采集与数据处理

传感器选SHT30为例,它通过I2C读取。SHT30有两种读取模式:周期采集模式和单次采集模式。控制面板场景下建议用周期采集,让传感器每秒自动出数据,MCU定时读取最新值即可,这样MCU不用去触发测量,逻辑更简洁。SHT30的周期模式配置命令是0x2236(每秒重复采集)。读取数据时,从0x24开头地址读取6字节,其中温度数据是两个字节(MSB和LSB),湿度同理。

原始AD值要转成物理值:温度 = -45 + 175 * (raw / 65535),湿度 = 100 * (raw / 65535)。计算出来是浮点型,为了DGUS显示方便,我们乘以10转成整数存储,发送时按整型发送即可。如果不放大,直接在DGUS里配置成浮点显示也行,但浮点格式的串口传输涉及IEEE754格式,STM32端要内存拷贝发送,会稍微繁琐一点。整数加固定小数位是更稳妥的通行做法。

3.3 迪文屏串口协议封装

迪文屏的串口指令格式遵循“帧头 + 长度 + 指令 + 数据”的结构。最常见的两条指令是:

  • 写变量地址指令:0x82,格式为 5A A5 长度 82 地址高字节 地址低字节 数据...。长度 = 3 + 2 * 数据字数(Word)。
  • 读变量地址指令:0x83,格式为 5A A5 长度 83 地址高字节 地址低字节 读取字数。屏幕返回同样的帧格式,数据区带上读到的值。

比如往0x1000地址写温度值250(表示25.0℃),指令就是:

5A A5 05 82 10 00 00 FA

这里05是长度,82是写指令,10 00是地址,00 FA是数据(250的十六进制)。如果是写两个地址连续的数据,长度相应增加即可。STM32端只需要用sprintf格式化一个缓冲区,然后通过串口发送即可。发送频率不用太高,每秒2次显示刷新足够。

读取用户设置阈值时,STM32周期性向屏幕发送读指令,比如读0x1100地址:

5A A5 04 83 11 00 01

返回帧中会带上当前0x1100的值。STM32解析返回帧时,要按帧头、长度、指令、地址、数据逐字节校验。特别注意长度字段和数据区的对应关系,很多人在解析时少算或多算一个字节,导致读出来的值全是乱的。

3.4 联动控制逻辑与继电器输出

联动控制不需要太复杂,但要做对逻辑,避免负载频繁抖动。我采用的是滞回控制方式。

温度控制:当温度大于上限时,继电器1吸合,输出高电平驱动风扇或空调启动;当温度回落到上限减1℃以下时,才断开继电器。湿热控制:湿度同理,低于下限时启动加湿器,高于下限加2%时才关闭。滞回区间的作用是防止继电器在临界点来回吸合,延长继电器寿命。如果你用的是继电器模块来控制交流负载,建议把频繁切换的时间间隔至少设置为10秒以上,不然触点寿命会急速下降。

控制状态通过变量地址0x1301实时写回屏幕显示,这样用户能直观看到当前继电器是ON还是OFF状态,而不是盲猜。

3.5 关键代码框架

这里给出一份简化版的代码骨架,方便你理解整个数据流和协议层的写法。

// 发送温湿度到屏幕 void Dwin_Report_TempHum(int16_t temp, int16_t hum) { uint8_t buf[16]; buf[0] = 0x5A; buf[1] = 0xA5; buf[2] = 0x05; // 长度 = 3 + 2*1 buf[3] = 0x82; buf[4] = 0x10; // 地址高字节 buf[5] = 0x00; // 地址低字节 buf[6] = (uint8_t)(temp >> 8); buf[7] = (uint8_t)(temp & 0xFF); HAL_UART_Transmit(&huart1, buf, 8, 100); buf[4] = 0x10; buf[5] = 0x01; buf[6] = (uint8_t)(hum >> 8); buf[7] = (uint8_t)(hum & 0xFF); HAL_UART_Transmit(&huart1, buf, 8, 100); } // 读取屏幕阈值变量,返回0x83读取帧 void Dwin_Read_Threshold(void) { uint8_t buf[8]; buf[0] = 0x5A; buf[1] = 0xA5; buf[2] = 0x04; buf[3] = 0x83; buf[4] = 0x11; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x01; HAL_UART_Transmit(&huart1, buf, 8, 100); }

接收中断里解析返回帧,判断帧头和长度后,取出数据区第3、4字节拼接为16位阈值保存。

控制逻辑这一块,用简单的状态机就够了:

void Temp_Control_Loop(void) { if (current_temp > threshold_temp_high) { relay1_on(); } else if (current_temp < (threshold_temp_high - 10)) { relay1_off(); } }

这里的减法10代表滞回区间10个计数单位,即1℃。具体滞回范围根据你的设备特性调整。

4. 常见问题与排查技巧实录

4.1 屏幕下载配置后花屏或白屏

多半是工程型号和屏幕型号不匹配。T5L平台分为T5L0、T5L1、T5L2,DGUS软件里工程创建时选的型号必须和屏背面的标签一致,尤其是UI内核版本,不一致的情况下升级配置很容易白屏。还有一种可能是SD卡容量过大,部分屏幕对32GB甚至64GB的卡支持不好,换一张8G的旧卡,格式化成FAT32,分配单元大小32KB,基本就能解决。

4.2 串口发送数据变量没有变化

检查三个地方:地址是否写错,特别是十六进制换算错误;数据显示控件的数据类型是否和发送的数据格式匹配(有无符号、小数位是否一致);发送的帧长度是否计算正确。0x82指令的字节长度计算方式是:长度 = 3 + 2*N,N是连续写入的字数。如果这条搞错了,屏幕端会丢弃整帧,自然不会有任何反应。还有一个容易忽略的点:DGUS控件属性里有一个“显示方式”,默认是覆盖显示,但如果你误设成了其他模式,数据刷新时会出现旧数字残影。

4.3 触摸设置无效或者数值跳动

触摸设置控件在DGUS里有个“输入范围”设置,如果范围设置得太窄,超过限制的数据会被自动丢弃。比如温度上限设置范围是0到600,你输入650,屏幕可能显示成功但实际写入的值是错误的。另外,电容屏的触摸有时会因为供电电源纹波过大而出现数值跳动,电源部分尽量在STM32的VDD和GND之间加100nF去耦电容,在屏幕供电端加一个470uF电解电容,大部分抖动能得到缓解。

4.4 屏幕回传数据解析不对

迪文屏对0x83读指令的应答帧格式是:帧头 + 长度 + 0x83 + 地址 + 数据。注意“长度”字段的数值不固定,它是3 + 2*读取字数。如果你连续读多个字,返回的数据会跟着变长。很多人在STM32接收处理时,没有做帧同步,导致解析到错误位置。推荐方法是:在中断里用环形缓冲区接收串口数据,主循环里做状态机解析帧头和长度,拿到完整一帧后再提取地址和数据,不要边收边解析。帧尾不需要校验,迪文协议本身没有CRC,但做一下帧头校验可以过滤掉杂波。

4.5 继电器频繁吸合抖动

这是所有控制面板类项目都容易遇到的痛。负载在临界值附近反复切换,不但吵,还容易烧触点。解决办法就是前面说的滞回控制。滞回区间大小要根据现场实际负载调整,比如控制空调启动时要设置至少2℃的回差,控制加湿器则要设置3%以上的回差。另外,如果继电器驱动的是感性负载(如风扇电机),建议在继电器输出端并联一个RC吸收电路(典型值:100Ω电阻加0.1uF电容串联),可以有效减少电弧和电磁干扰。这个细节很多初学者会忽略,但晚了接上就会发现STM32偶尔死机,其实就是继电器吸合瞬间产生的EMI干扰到了MCU的电平。

5. 其他细节与项目后续扩展

5.1 屏幕底图和界面设计技巧

迪文屏的显示效果很大程度取决于你给的底图质量。用纯黑色底加细线条分割区域,配合白色大号字体,显示效果会非常“智能家居”。不要直接拿示例工程的图片来用,明显有套模板的感觉。字号方面,温度数值建议用到80号以上字体,人站在两三米外能一眼看清;触摸按钮的点击区域不要小于60×60像素,不然手指容易误触旁边的控件。

5.2 项目还能怎么扩展

这套系统的框架做好后,扩展非常方便。想加入MQTT联网上报温度?STM32外接ESP8266或ESP32模块,把读取到的温湿度通过MQTT发布到Home Assistant即可。想加入更多控制通道?在DGUS底图上增加一个区域的按钮,地址规划在0x1400,代码里再加一路继电器控制逻辑就行。想把数据存起来做曲线显示?DGUS部分型号支持曲线控件,把历史数据依次写入曲线缓冲区地址即可。整体来说,迪文屏加STM32这套组合的优点是:做出来的东西直接能安装上墙,显示稳定不掉线,程序跑个一年半载也不用操心。

5.3 成本和时间投入说明

整个项目硬件成本控制在150到250元之间,大头是屏幕。如果手头刚好有旧智能手机拆机屏,也可以考虑走ESP32方案,但“DIY的触摸屏面板”的质感和迪文屏其实差得很远。软件开发时间方面,如果你完全没接触过DGUS,第一次从头到尾做到底、包括屏幕界面和STM32代码,大概需要2到3天;如果做过一次,后面再做第二个面板,一天之内就能搞定。

这个项目最值得学习的地方,倒不在于代码多高深,而是“串口屏 + MCU”这种在工业领域非常成熟的架构,搬到智能家居DIY里一样非常好用。它让我真正意识到,所谓智能家居,不一定是全屋设备都接入云端才好用;有时候一个挂在墙上的实体面板,反而比手机App更快更直接。我后来把家里的客厅灯和阳台窗帘也接到了这套系统里,用下来半年多,稳定性确实比之前用便宜WiFi模块的方案靠谱得多。如果你也在做类似的智能家居项目,真心建议试试用串口屏这条路线,省心、可控、效果直观。用迪文屏和STM32做联动控制,无论是毕设还是实际部署,都是一套能快速出成果的组合。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询