TM1640驱动代码解析:从原理到代码实现 | 零基础入门STM32第四十六步
师从洋桃电子,杜洋老师
📑文章目录
-
- 一、TM1640芯片概述
- 二、驱动代码结构分析
-
- 2.1 代码模块结构图
- 2.2 核心代码模块说明
-
- 2.2.1 底层通信协议
- 2.2.2 初始化配置
- 2.2.3 显示控制函数
- 2.2.4 LED流水灯实现
- 三、关键数据结构解析
- 四、开发注意事项
- 五、典型应用场景
- 六、相关资源
▲ 回顾上期🔍TM1640数码管驱动芯片详解与应用实践 | 零基础入门STM32第四十五步


一、TM1640芯片概述
TM1640是一款LED驱动控制芯片,具有以下特性:
▲ 🔍 TM1640 数据手册
二、驱动代码结构分析
2.1 代码模块结构图
#mermaid-svg-u4mUauOAdtwtmguL {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-u4mUauOAdtwtmguL .error-icon{fill:#552222;}#mermaid-svg-u4mUauOAdtwtmguL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-u4mUauOAdtwtmguL .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-u4mUauOAdtwtmguL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-u4mUauOAdtwtmguL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-u4mUauOAdtwtmguL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-u4mUauOAdtwtmguL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-u4mUauOAdtwtmguL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-u4mUauOAdtwtmguL .marker.cross{stroke:#333333;}#mermaid-svg-u4mUauOAdtwtmguL svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-u4mUauOAdtwtmguL .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-u4mUauOAdtwtmguL .cluster-label text{fill:#333;}#mermaid-svg-u4mUauOAdtwtmguL .cluster-label span{color:#333;}#mermaid-svg-u4mUauOAdtwtmguL .label text,#mermaid-svg-u4mUauOAdtwtmguL span{fill:#333;color:#333;}#mermaid-svg-u4mUauOAdtwtmguL .node rect,#mermaid-svg-u4mUauOAdtwtmguL .node circle,#mermaid-svg-u4mUauOAdtwtmguL .node ellipse,#mermaid-svg-u4mUauOAdtwtmguL .node polygon,#mermaid-svg-u4mUauOAdtwtmguL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-u4mUauOAdtwtmguL .node .label{text-align:center;}#mermaid-svg-u4mUauOAdtwtmguL .node.clickable{cursor:pointer;}#mermaid-svg-u4mUauOAdtwtmguL .arrowheadPath{fill:#333333;}#mermaid-svg-u4mUauOAdtwtmguL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-u4mUauOAdtwtmguL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-u4mUauOAdtwtmguL .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-u4mUauOAdtwtmguL .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-u4mUauOAdtwtmguL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-u4mUauOAdtwtmguL .cluster text{fill:#333;}#mermaid-svg-u4mUauOAdtwtmguL .cluster span{color:#333;}#mermaid-svg-u4mUauOAdtwtmguL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-u4mUauOAdtwtmguL :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 主程序 TM1640初始化 显示控制 LED控制 GPIO配置 通信协议配置 段码转换 地址设置 LED数据移位
2.2 核心代码模块说明
2.2.1 底层通信协议
void TM1640_start(){ //通信时序 启始(基础GPIO操作)(低层)GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1delay_us(DEL);GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0delay_us(DEL);GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0delay_us(DEL);}void TM1640_stop(){ //通信时序 结束(基础GPIO操作)(低层)GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1delay_us(DEL);GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1delay_us(DEL);}void TM1640_write(u8 date){//写数据(低层)u8 i;u8 aa;aa=date;GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0for(i=0;i<8;i++){GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0delay_us(DEL);if(aa&0x01){GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1delay_us(DEL);}else{GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0delay_us(DEL);}GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1delay_us(DEL);aa=aa>>1; }GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0}
时序特点:
- 下降沿锁存数据
- 低位(LSB)先发送
- 每个时钟周期传输1bit
2.2.2 初始化配置
void TM1640_Init(void){ // GPIO初始化(略) TM1640_start(); TM1640_write(0x44); // 固定地址模式 TM1640_stop(); TM1640_start(); TM1640_write(0x8C); // 显示开启,亮度等级4 TM1640_stop();}
关键配置说明:
0x44
:固定地址模式(推荐避免显示错位)0x8C
:显示使能 + 亮度设置(值范围0x88-0x8F)
2.2.3 显示控制函数
void TM1640_display(u8 address,u8 date){ //固定地址模式的显示输出 const u8 buff[21]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00};//数字0~9及0~9加点显示段码表 //--------------- 0 1 2 3 4 5 6 7 8 9 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 无 TM1640_start(); TM1640_write(0xC0+address); //传显示数据对应的地址 TM1640_write(buff[date]); //传1BYTE显示数据 TM1640_stop();
地址映射规则:
- 数码管地址范围:0xC0~0xC7(对应8位数码管)
- LED地址固定为0xC8(控制8个独立LED)
2.2.4 LED流水灯实现
// 主程序中的LED控制逻辑u8 c = 0x01;while(1){ TM1640_led(c); // 输出LED数据 c <<= 1; // 左移实现流水效果 if(!c) c = 0x01;// 循环复位 delay(125);}
移位逻辑说明:
• 初始值0x01(二进制00000001)
• 每次左移1位实现LED流动效果
• 0x01 → 0x02 → 0x04 → … → 0x80 → 复位
▲ 完整工程代码示例⏬数码管RTC显示程序
三、关键数据结构解析
段码对照表
四、开发注意事项
- 时序稳定性:调整
DEL
值确保通信可靠 - 地址模式选择:
• 固定地址(0x44):需指定每个显示位置
• 自动增量(0x40):连续写入多个数据 - 亮度调节:根据环境光照选择合适等级(0x88-0x8F)
- 段码自定义:修改buff数组实现特殊符号
五、典型应用场景
- 电子时钟(如文中RTC时间显示)
- 工业仪表显示
- LED状态指示面板
- 智能家居控制面板
六、相关资源
[1] 洋桃电子B站课程-STM32入门100步
[2] STM32F103xx官方数据手册
[3] STM32F103X8-B数据手册(中文)
[4] STM32F103固件函数库用户手册(中文)
[5] 数码管RTC显示程序
[6] TM1640 数据手册
💬 技术讨论(请在评论区留言~)
📌 下期预告:下一期将探讨旋转编码器原理与驱动,欢迎持续关注!
点击查阅🔍往期【STM32专栏】文章
版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志:
- v1.0 初始版本(2025-03-05)