STM32CUBE UART串口驱动TM1652数码管:从配置到动态显示实战
1. 硬件连接与TM1652初识为什么选它大家好我是MCU起航一个在嵌入式领域摸爬滚打了十多年的老鸟。今天咱们不聊那些高大上的复杂协议栈就聊聊怎么用STM32最基础的UART串口去驱动一个看起来有点“古老”的数码管驱动芯片——TM1652。你可能用过TM1638功能强大还能扫按键但有时候项目成本卡得紧或者IO口实在不够用这时候TM1652的优势就出来了它只需要一根数据线对你没听错一根线就能驱动5位8段或者6位7段的数码管这对于那些IO资源捉襟见肘的STM32F0、G0系列单片机来说简直是雪中送炭。我第一次用TM1652是在一个温控器的小项目上主控用的是STM32G030引脚就那么几个还要接温度传感器、继电器和按键留给显示的IO真的一个都挤不出来了。当时就在想有没有一种芯片能用串口“顺便”把显示也给干了结果就找到了天微的TM1652。这芯片典型电压是5V但我实测3.3V供电完全没问题直接和3.3V的STM32对接省去了电平转换的麻烦。不过这里有个坑得先提醒你TM1652只支持共阴极数码管如果你手头是共阳的管子那就得赶紧换货或者用三极管搭个反向电路不然怎么调程序都不会亮的。硬件连接简单到令人发指。TM1652的DIN引脚直接接到STM32任意一个UART_TX引脚上。VCC接3.3V或5VGND接地。然后在芯片的VCC和GND之间靠近芯片引脚的地方放一个0.1uF和一个10uF的电容这是为了电源去耦确保数据传输稳定尤其是用3.3V供电时这一步不能省。数码管呢就把它的每一段a, b, c, d, e, f, g, dp对应接到TM1652的段驱动输出脚SEG1~SEG8把每一位数码管的公共阴极COM1~COM5或COM6接到TM1652的位驱动输出脚GRID1~GRID5/6上。接好线硬件部分就算搞定了是不是比那种需要接一大堆IO的静态驱动方式清爽多了2. STM32CUBEMX配置搞定9位偶校验串口硬件连好了接下来就是让STM32的串口按照TM1652能听懂的方式“说话”。这里的关键点在于串口模式。TM1652的通信协议虽然它自己叫“单线串行接口”但其实质就是固定格式的UART。手册里白纸黑字写着波特率固定19200数据格式是9位数据偶校验1位停止位。这个“9位数据”包含了8位数据位和1位校验位和我们常用的8位无校验模式不一样。打开STM32CubeMX选择你的STM32型号我这里以STM32G030F6P6为例找到你要用的USART外设比如USART2。在配置界面里Mode选择“Asynchronous”异步模式。然后重点来了在下面的“Parameter Settings”里Baud Rate: 填入 19200。Word Length: 选择 “9 Bits (including parity bit)”。注意这个选项的意思是总长度9位其中包含了校验位。Parity: 选择 “Even”偶校验。Stop Bits: 选择 “1”。Data Direction: 因为我们只需要给TM1652发送数据不需要接收所以选择 “Transmit Only”仅发送。这样能稍微节省一点资源。其他设置保持默认就行。配置完成后点击“Generate Code”CubeMX就会帮你生成好初始化代码。这里我踩过一个坑早期有些教程或者自己写寄存器配置时可能会忽略“Word Length”这个选项的精确含义错误地配置成8位字长再加校验位导致实际发送的数据帧格式不对TM1652自然就不会响应。用CubeMX可视化配置就能完美避开这个坑非常省心。生成代码后你可以在main.c的初始化部分看到MX_USART2_UART_Init()函数里面已经把USART2按照我们的要求配置好了。接下来我们只需要调用HAL库的发送函数HAL_UART_Transmit()来发送数据帧就可以了。不过在写发送代码之前我们得先搞清楚TM1652到底想听什么“话”也就是它的数据帧格式。3. 数据帧格式解析TM1652的“语言手册”TM1652的通信指令很简单主要就两类显示数据命令和显示控制命令。你可以把它想象成给一个智能管家下指令先告诉它“把东西放到A房间、B房间、C房间”写显示数据再告诉它“把整个屋子的灯调到最亮模式”写显示控制。第一类显示数据命令帧这帧数据的作用是告诉TM1652在哪个数码管位置上显示什么内容。一帧完整的显示数据操作包含一个“地址命令字”和紧随其后的1到5个“显示数据字”。地址命令字格式是0b0AAA A000。其中低三位固定为0高四位中的AAA三位用来指定起始的显示位地址000对应GRID1001对应GRID2以此类推。最高位bit7是固定0。这里有个超级好用的功能地址自动加1模式。如果我们把地址命令字的bit4置1即0b0AAA 1000那么发送完这个命令字后接下来连续发送的显示数据字会自动依次填充到AAA指定的地址及其后续递增的地址中。比如发送0x080b0000 1000就意味着从GRID1开始后续数据自动给GRID1、GRID2、GR3...这极大地简化了程序我们不用每送一个数据就改一次地址。显示数据字这就是对应数码管上每一段LED亮灭的数据。一个字节的8个bit分别控制一段通常bit0对应a段bit1对应b段...bit7对应dp小数点段。给1就亮给0就灭。比如数字“0”的段码不带小数点就是0x3F0b0011 1111因为a,b,c,d,e,f段亮g段和dp段不亮。第二类显示控制命令帧这帧数据用来设置芯片的整体工作模式一帧包含两个字节。第一个字节显示控制命令固定为0x18。你可以理解为这是一个“准备进行系统设置”的指令头。第二个字节显示调节命令这个字节决定了亮度、段电流和显示模式。其格式是0b000X YZZZ。ZZZ低三位设置显示占空比即亮度从000到111对应1/16到16/16共8级亮度。Ybit3设置段驱动电流0是4/81是8/8更亮。Xbit4设置显示模式0是7段6位1是8段5位。 例如0x1C这个值0b0001 1100就表示亮度为8/16ZZZ100段电流为4/8Y1模式为8段5位X1。这个值在大多数3.3V供电、驱动普通小型数码管的场景下是个比较均衡的选择。理解了这两类帧编程思路就清晰了先发一帧或多帧显示数据命令把要显示的内容灌进去再发一帧显示控制命令让芯片以指定的模式工作起来。4. 代码实战地址自动递增与动态显示理论说再多不如一行代码。我们直接上干货。首先我们需要定义两个关键的数组段码表。这相当于一个“翻译字典”把数字0-9翻译成TM1652能认识的段码。// 定义0-9以及空格的段码不带小数点 const uint8_t seg_no_dot[11] {0x3f, 0x06, 0x5b, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00}; // 定义0-9以及空格的段码带小数点 const uint8_t seg_with_dot[11] {0xbf, 0x86, 0xdb, 0xcF, 0xe6, 0xeD, 0xfD, 0x87, 0xfF, 0xeF, 0x80};注意这里数组大小是11最后一个0x00或0x80代表全灭用于显示空格或清屏。带小数点的段码就是在不带小数点的段码基础上把最高位bit7置1。接下来是核心的发送函数。我强烈推荐使用地址自动加1模式它能让你一次性更新多个连续位的数据代码简洁又高效。/** * brief 使用地址自动加1模式向TM1652连续写入数据 * param addr: 起始地址命令字 (例如 0x08 表示从GRID1开始并启用地址自增) * param dat1: 写入起始地址的数据 * param dat2: 写入下一地址的数据 * param dat3: 写入再下一地址的数据 * retval None */ void address_auto_add1(uint8_t addr, uint8_t dat1, uint8_t dat2, uint8_t dat3) { uint8_t dat_buf[4] {0}; // 第一步发送显示数据命令帧地址数据 dat_buf[0] addr; // 例如 0x08 dat_buf[1] dat1; dat_buf[2] dat2; dat_buf[3] dat3; HAL_UART_Transmit(huart2, dat_buf, 4, 0xFFFF); // 发送4个字节 HAL_Delay(5); // 手册建议延时3ms以上这里给5ms更稳妥 // 第二步发送显示控制命令帧 dat_buf[0] 0x18; // 显示控制命令固定头 dat_buf[1] 0x1C; // 显示调节命令8段5位亮度8/16段电流4/8 HAL_UART_Transmit(huart2, dat_buf, 2, 0xFFFF); HAL_Delay(5); }这个函数干了三件事1. 打包起始地址和三个显示数据2. 用HAL库的串口发送函数发出去3. 发送系统设置命令0x18和0x1C。每次发送后都加了5ms延时这是严格按照TM1652手册来的芯片处理指令需要时间延时不够可能导致数据错乱。那么怎么用这个函数实现动态效果呢比如让三位数码管从“000”滚动显示到“999”。我们可以在主循环里这样写int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t counter 0; uint8_t hundreds, tens, units; while (1) { // 分解出百位、十位、个位 hundreds counter / 100; tens (counter % 100) / 10; units counter % 10; // 使用地址自动加1模式一次性更新三位数码管 // 0x08 表示从GRID1开始地址自动加1 address_auto_add1(0x08, seg_no_dot[hundreds], seg_no_dot[tens], seg_no_dot[units]); counter; if(counter 999) counter 0; HAL_Delay(500); // 每500毫秒计数加1 } }你看代码非常清晰。address_auto_add1函数一次调用就搞定了三位数字的更新。如果你想显示带小数点的数字比如“12.3”只需要把对应位的段码换成seg_with_dot数组里的值即可例如address_auto_add1(0x08, seg_no_dot[1], seg_with_dot[2], seg_no_dot[3])。5. 避坑指南与高级技巧玩转了基本显示咱们再聊聊实际项目中可能遇到的坑和一些提升体验的技巧。第一个坑电源与干扰。TM1652对电源噪声比较敏感尤其是用3.3V系统时。如果发现显示乱码、闪烁或者某些段莫名熄灭首先检查电源。除了之前说的在芯片引脚附近加两个电容0.1uF陶瓷电容和10uF电解电容并联如果布线较长还可以在STM32的UART_TX输出线上串一个几十欧姆的电阻比如33Ω能有效抑制过冲和振铃让信号更干净。我有个项目就因为省了这个电阻在电机启动时显示就花屏加上之后就再也没出过问题。第二个坑时序与延时。TM1652手册强调连续发送两帧指令之间需要至少3ms的间隔。我们的代码里用了HAL_Delay(5)这是阻塞延时在简单的轮询程序里没问题。但如果你的系统用了RTOS或者有严格的实时性要求阻塞延时就会拖慢整个系统。这时候你可以用定时器来产生精确的非阻塞延时或者更优雅的做法是利用HAL库的UART发送完成回调函数。在stm32g0xx_hal_uart.c附近你可以重写HAL_UART_TxCpltCallback()函数当一帧数据发完后在回调函数里设置一个标志位然后再进行下一步操作比如发下一帧或者更新显示数据这样就能把CPU解放出来。第三个技巧亮度调节与节能。显示控制命令里的亮度设置ZZZ位和段电流设置Y位非常有用。在电池供电的设备上你可以根据环境光传感器或者用户设置动态调整亮度。白天调到最亮0x1F晚上调到较暗0x18能显著省电。甚至在设备待机时你可以发送命令0x18和0x00来关闭所有显示占空比1/16几乎全灭而不是简单地停止刷新数据这样更符合芯片的低功耗设计。第四个技巧驱动更多位数。我们的例子驱动了3位数码管。TM1652最多支持5位8段模式或6位7段模式。如果你想驱动5位只需要把发送的数据从3个增加到5个。函数可以改造成更通用的形式void tm1652_write_multi(uint8_t start_addr_cmd, uint8_t *data, uint8_t len) { // 先发送地址命令和多个数据... // 再发送显示控制命令... }这样无论驱动几位调用起来都非常灵活。最后调试时如果数码管完全不亮别慌。先用示波器或者逻辑分析仪抓一下UART_TX引脚上的波形。看看波特率是不是准确的19200数据位是不是9位你会看到10位一帧包括起始位、8位数据、1位偶校验位、停止位。如果没有仪器一个很土但有效的办法是把TX线暂时接到电脑的USB转串口模块的RX上用串口助手以19200波特率、9位数据、偶校验、1停止位的格式去接收。如果你能看到程序里发送的0x08,0x3F,0x18,0x1C等数据流那就证明STM32的发送完全正确问题很可能出在TM1652的供电、硬件连接或者数码管本身了。

相关新闻

从零构建Qt Ribbon界面:SARibbon控件的深度集成与实战

从零构建Qt Ribbon界面:SARibbon控件的深度集成与实战

1. 为什么你的Qt桌面应用需要一个Ribbon界面? 如果你正在用Qt开发一个给公司内部用的数据分析工具,或者是一个小团队的设计软件,甚至是一个给客户用的数据管理平台,你肯定想过怎么把界面做得更专业、更好用。回想一下,…

2026/7/3 6:24:03 阅读更多 →
实战指南:在eNSP中配置USG6000V防火墙WEB管理页面

实战指南:在eNSP中配置USG6000V防火墙WEB管理页面

1. 环境准备:搭建你的第一个虚拟网络实验室 很多刚接触网络技术的朋友,一听到“防火墙配置”、“命令行”这些词,可能就觉得头大,感觉是专业工程师才能玩转的东西。其实不然,借助华为的eNSP模拟器,我们完全…

2026/7/4 6:28:34 阅读更多 →
树莓派4B——串口通信优化与实战应用

树莓派4B——串口通信优化与实战应用

1. 为什么你的树莓派串口总是不稳定?从根上理解串口资源 很多朋友拿到树莓派4B,兴冲冲地接上传感器或者单片机,想玩转串口通信,结果第一步就卡住了:数据时有时无,时不时蹦出乱码,或者干脆就没反…

2026/7/3 6:23:58 阅读更多 →

最新新闻

3步解决Navicat试用限制:macOS数据库开发者的终极方案

3步解决Navicat试用限制:macOS数据库开发者的终极方案

3步解决Navicat试用限制:macOS数据库开发者的终极方案 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 你是否也曾…

2026/7/4 19:33:32 阅读更多 →
蓝凌EIS平台SQL注入漏洞(CVE-2025-22214)深度剖析与实战复现

蓝凌EIS平台SQL注入漏洞(CVE-2025-22214)深度剖析与实战复现

1. 项目概述:一次针对企业协同平台的SQL注入漏洞深度剖析最近在安全圈里,蓝凌EIS智慧协同平台的一个SQL注入漏洞(CVE-2025-22214)引起了我的注意。这个漏洞出在fi_message_receiver.aspx这个接口上,攻击者甚至不需要登…

2026/7/4 19:33:32 阅读更多 →
使用DALL·E 3和Python自动生成AI配图PPT

使用DALL·E 3和Python自动生成AI配图PPT

1. 为什么需要自动生成带AI配图的PPT?在商业汇报、学术展示和日常工作中,PPT制作往往占据大量时间。传统流程需要经历内容整理、版式设计、图片搜索/制作等多个环节,尤其配图部分最耗时——要么花费数小时在免费图库中寻找合适素材&#xff0…

2026/7/4 19:31:32 阅读更多 →
面向钓鱼邮件研判的智能体 AI 流水线架构与工程实践研究

面向钓鱼邮件研判的智能体 AI 流水线架构与工程实践研究

摘要 全球钓鱼攻击总量持续高速增长,2025 年全年钓鱼攻击总量突破 380 万起,仅第二季度上报钓鱼邮件数量超 110 万封,海量可疑邮件上报给安全运营中心(SOC)带来巨大人工研判压力。传统单一大模型检测方案存在可解释性差…

2026/7/4 19:31:32 阅读更多 →
反潜航空深弹命中概率问题的数学建模与优化研究

反潜航空深弹命中概率问题的数学建模与优化研究

反潜航空深弹命中概率问题的数学建模与优化研究 副标题:基于随机过程理论与 Monte Carlo 模拟的航空深弹投弹策略最优设计 竞赛:2024年高教社杯全国大学生数学建模竞赛 D题 关键词:航空深弹 命中概率 截尾正态分布 Monte Carlo模拟 阵列优化 摘要:本文针对2024年全国大…

2026/7/4 19:31:32 阅读更多 →
PCB阻抗线设计与立创EDA专业版设置指南

PCB阻抗线设计与立创EDA专业版设置指南

1. 阻抗线基础概念与设计要点在PCB设计中,阻抗线是指具有特定特性阻抗的传输线,主要用于高频信号传输(如射频、高速数字信号)。阻抗匹配是确保信号完整性的关键因素,不匹配会导致信号反射、振铃和功率损耗。阻抗线的特…

2026/7/4 19:27:31 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻