简介:HT1621B驱动芯片的笔段式液晶显示测试完整工程包,面向嵌入式开发者、电子爱好者及低功耗显示方案设计者,用于解决液晶屏驱动调试与显示验证问题。资源基于IAR集成开发环境组织,共31个文件、约144KB,包含驱动源码、主测试程序、IAR工程配置文件、编译生成的固件镜像,以及仿真调试用的批处理和项目配置脚本,覆盖从工程打开、编译下载到在线调试的完整流程。已有1010人学习下载。内容围绕HT1621B的串行外设接口通信、初始化配置、显示模式切换、亮度调节与自动消影等关键知识点展开,结合实际例程能帮助理解芯片手册中的寄存器操作;通过完整测试例程,可直接观察不同显示模式的实际效果,减少从零调试的弯路,适合需要快速上手笔段式液晶驱动、验证硬件连接或排查显示异常的项目开发者参考。
1. 先把这块便宜的笔段式LCD驱动芯片点亮再说
做产品成本敏感、只显示数字和单位的时候,别急着上串口屏。最近拆了一份 HT1621B 驱动笔段式LCD 的完整测试工程,解压后看下来,这才是量产项目里最常见的一套东西:一块几个引脚的小面板、三根线的串行驱动、一张段码表,外加一段能跑通的自测代码。这个工程把 HT1621B 从初始化、写命令、写显存到全段点亮做成了可以直接编译烧录的状态,适合正在做家电面板、温湿度计、仪表屏这类低功耗界面的开发者,也适合第一次接触笔段式 LCD、想搞懂三线时序的人。一句话:这份资源不是芯片科普,是一份能烧进板子、能改显示内容的起点工程。
2. 工程全景与架构设计:从引脚分配到128点显存布局
拿到压缩包先别急着刷屏,建议按“外设连接→驱动函数→显存映射”的顺序去读。这份完整工程的价值在于它不是散装代码,而是把一个测试板需要用到的三部分都补齐了:HT1621B 驱动源文件、笔段码映射表、主程序里的点亮流程。主控端用的是很常见的 32 位 Cortex-M 内核 MCU,没有依赖特定封装的冷僻外设,核心操作全部是普通 GPIO 翻转,移植到 51 或者国产 ARM 芯片只是改宏定义的事。
2.1 文件结构:哪些文件是核心,哪些是辅助
工程解压后大致是下面这样,我自己习惯先看头文件再看实现,因为引脚和显存定义都集中在头文件里。
ht1621_drv.c / ht1621_drv.h seg_table.h lcd_screen.c main.c doc/HT1621B_datasheet.pdf doc/lcd_panel_pinout.pnght1621_drv.c 是真正的驱动主体,包含位发送、命令发送、数据发送、初始化四组函数;seg_table.h 放的是显示数字、字母、单位符号对应的段码数组;lcd_screen.c 负责把业务数据,比如温度、电压、百分比,翻译成段码数组;main.c 里是上电初始化、一个循环点亮的测试逻辑,以及 1 秒刷新示例。
这里的重点在 ht1621_drv.c:它把芯片的三线时序封装成了几个零依赖的函数,调用方完全不用关心电平怎么抖,只需要知道“发命令”“写显存”两个动作。doc 目录下的 datasheet 和引脚图是排查接线问题时的依据,建议烧录前先对着引脚图核对一遍。
2.2 HT1621B 的内部结构:32×4 命令通道
HT1621B 是一颗带 RAM 的笔段式 LCD 驱动芯片,内部显存是 32 个地址,每个地址存 4 位,总共 128 个控制点。这 128 个点通过内部的 COM 和 SEG 交叉矩阵映射到液晶面板的各个笔段。
对于开发者来说,只需要理解两个帧格式:发命令的时候先发 3 位命令标志 101,然后跟 8 位命令码;写数据的时候先发 3 位数据标志 100,再跟 6 位地址和 4 位数据。用文本表示就是:
命令帧: 101 | 8bit command 数据帧: 100 | 6bit address | 4bit data参数说明:命令标志由芯片手册固定,不能改;8 位命令码用来控制系统开关、偏压、LCD 显示、写显存使能;数据帧里的 6 位地址范围是 0~31,正好覆盖 32 个 RAM 地址;4 位数据对应某个显存地址的四个控制点,每个 bit 的物理含义取决于 LCD 面板的 COM/SEG 连接方式。
这个结构的直接好处是驱动层很薄。你不需要了解液晶面板内部的电极走线,只需要维护一张 32 字节的显存表,需要显示什么就往对应地址填数据。所以笔段式 LCD 的驱动代码通常都比点阵屏简单,难的地方是段码表的整理,而不是时序。
2.3 硬件连接设计:三根线加电源就够
HT1621B 与 MCU 之间只需要三根线:CS、WR、DATA。CS 低电平选中芯片,WR 上升沿锁存数据,DATA 是双向串行数据线。测试工程里把这三个脚定义在普通 GPIO 上,我用表格列一下常见的接法:
| HT1621B 引脚 | MCU 引脚 | 说明 |
|---|---|---|
| CS | PB12 | 片选,低有效 |
| WR | PB13 | 写时钟,上升沿锁存 |
| DATA | PB14 | 串行数据 |
| VDD | 3.3V | 逻辑电源 |
| VLCD | 3.3V 或调节点 | 驱动 LCD 的偏压来源 |
VLCD 是很多人忽略的点。HT1621B 的 LCD 驱动电压可以直接接系统电源,但有些面板对比度不够时,会把 VLCD 接到一个可调电阻分压点,用来微调显示深浅。测试工程里直接接到了 3.3V,如果你的面板字迹很淡,先改这一步,不要急着怀疑程序。
电源旁路建议按常见做法在 VDD 和 GND 之间放一个 0.1μF 陶瓷电容,靠近芯片引脚放置。HT1621B 内部有 RC 振荡器,不需要外部晶振,所以整个最小系统就一颗芯片加两个电容,比用数码管加译码器的老方案清爽得多。
3. 核心驱动拆解:一次写段动作从MCU到液晶的完整链路
驱动 HT1621B 的关键不是调库,而是把三线时序吃透。这个完整工程的核心代码集中在 ht1621_drv.c 里,我拆开来逐步讲。第一次看的时候,建议把逻辑分析仪接在 WR 和 DATA 上,对比参考代码的波形,一次就能明白整条链路。
3.1 位发送函数:三线时序的底层动作
所有读写动作最后都会落到一个基础函数:按位把数据送到 DATA 线上,再用 WR 上升沿让芯片锁存。工程里的实现大致长这样:
void ht1621_write_bits(unsigned char data, unsigned char cnt) { unsigned char i; for (i = 0; i < cnt; i++) { if (data & (1 << (cnt - 1 - i))) HT1621_DATA = 1; else HT1621_DATA = 0; HT1621_WR = 0; ht1621_delay_us(1); HT1621_WR = 1; ht1621_delay_us(1); } }逻辑说明:循环次数由 cnt 决定,cnt=8 表示发送一个完整字节,cnt=3 表示发命令标志,cnt=6 表示发地址。高位先出,第一个 for 循环里用1 << (cnt-1-i)把最高有效位移到当前要发送的位置。每写一个 bit,先把 WR 拉低,数据准备好后拉高,上升沿生效,然后延时保证时序满足周期要求。
参数说明:data 的低 cnt 位是有效数据,调用时不要传超出位数的值。ht1621_delay_us(1) 是极短延时,目的不是让芯片处理,而是保证 IO 翻转沿不重叠。如果 MCU 主频很高,这段延时尤其重要,后面避坑部分会讲。
3.2 命令与数据函数:区分 101 和 100 标志
有了底层位发送,命令帧和数据帧就只是封装问题。工程里的实现是:
#define HT1621_CMD_MODE 0x05 /* 101 */ #define HT1621_DATA_MODE 0x04 /* 100 */ void ht1621_send_cmd(unsigned char cmd) { HT1621_CS = 0; ht1621_write_bits(HT1621_CMD_MODE, 3); ht1621_write_bits(cmd, 8); HT1621_CS = 1; } void ht1621_send_data(unsigned char addr, unsigned char dat) { HT1621_CS = 0; ht1621_write_bits(HT1621_DATA_MODE, 3); ht1621_write_bits(addr, 6); ht1621_write_bits(dat, 4); HT1621_CS = 1; }逻辑说明:ht1621_send_cmd 里 CS 拉低后先发 101,再发 8 位命令码,整帧完成拉高 CS。ht1621_send_data 先发 100,再发 6 位地址和 4 位数据。注意这两个函数的位拼接来自地址和数据的低位,和 3.1 的移位方式配套,不要混用另一种高位先出的实现,容易错位。
参数说明:addr 范围 0~31,对应内部 RAM 地址;dat 是 4 位数据,超出部分会被舍弃。发送完一帧后 CS 必须拉高,否则芯片可能把下一帧误判为同一个事务,这是乱码的一个来源。
3.3 初始化与显示刷新:从配置到点亮
初始化过程按数据手册的顺序执行:开启系统、设偏压、选背极数、点亮 LCD。测试工程里给了一组经过验证的配置值:
void ht1621_init(void) { ht1621_send_cmd(0x01); /* 打开系统振荡器 */ ht1621_send_cmd(0x52); /* 1/3偏压,4COM模式 */ ht1621_send_cmd(0x29); /* 选择偏压档位 */ ht1621_send_cmd(0x03); /* 打开LCD显示 */ }逻辑说明:0x01 是系统使能命令,芯片内部振荡器启动后才有后续动作;0x52 配置偏压和背极数,四个 COM 是最常见的笔段式 LCD 接法;0x29 是偏压档位,直接影响显示对比度;0x03 打开 LCD 驱动输出。这四个命令缺一不可,少任何一个都可能出现屏幕不亮或全亮。
参数说明:0x52 里的偏压档位要参考 LCD 面板规格,如果面板是 1/2 bias,需要换成对应命令值。0x29 在不同资料里可能不同,建议以配套 datasheet 为准。
刷新显示时,工程维护了一个 32 字节显存数组,写段命令全部走一个函数:
void ht1621_refresh(const unsigned char *ram, unsigned char addr_count) { unsigned char i; ht1621_send_cmd(0xA0); /* 使能写RAM */ for (i = 0; i < addr_count; i++) { ht1621_send_data(i, ram[i]); } }逻辑说明:先发送 0xA0 命令让芯片进入写 RAM 状态,然后从地址 0 开始逐个写入 4 位数据。这个函数的效率不如连续写模式,但胜在简单可靠,初学者不容易搞错地址自增逻辑。addr_count 最大 32,如果向下兼容其他型号的 HT1621,可以只刷新前几个地址,节省一点时间。
参数说明:ram 数组每个元素是 4 位有效数据,但为了 C 语言访问方便,通常按 unsigned char 存储。刷新完不需要额外操作,硬件会自动把 RAM 内容映射到 LCD 笔段。
4. 跑通工程:烧录、点亮与对比度调节的实战步骤
这一章没有任何玄学,按步骤走就能点亮。我第一次跑这个工程时栽在引脚配置上,折腾了半小时才发现是因为 PB14 被复用成了调试口。所以下面的每条步骤都带一个检查点,提醒自己在哪儿容易翻车。
4.1 准备最小硬件
需要的东西很少:一块带 LCD 面板的测试板,或者自己接的 HT1621B 模块;一个 32 位 MCU 的调试板;逻辑分析仪不是必须,但强烈建议备一个。接线就按第二章的表格,重点检查 VLCD 不要接错。
上电之前用万用表量一遍 HT1621B 的 VDD 和 VLCD 对地电压,确认是 3.3V 或者面板标称的电压。很多“屏幕不亮”的案例最后查出来是 VLCD 没接,芯片逻辑在跑,但驱动 LCD 的偏压没有来源,玻璃上的笔段自然出不来。
4.2 编译烧录与观察现象
工程是标准 C 代码,打开调试工程后先编译。烧录时用常见的 ARM 调试器即可,没有特殊配置。烧录完成后复位,正常情况下笔段式 LCD 应该全段点亮 2 秒,然后逐段扫描一次,最后停在主循环显示测试数字,类似“18:88”。
如果你看到的是全黑或者全亮,先别改代码,做两个检查:第一,CS 和 WR 两根线是不是接反了;第二,HT1621B 的 VLCD 有没有电压。这两个问题在实战中出现频率最高,程序怎么查都不可能解决硬件错误。用逻辑分析仪抓 CS、WR、DATA,如果波形静止没有任何电平变化,回头看主循环是否真的执行到了刷新函数,或者初始化函数有没有被调用。
4.3 全段自检与对比度调整
完整工程里包含一个自检函数,作用是从左到右逐个点亮面板上的每个笔段,方便确认段码表和实际玻璃的对应关系:
void lcd_self_test(void) { unsigned char addr; unsigned char bit; for (addr = 0; addr < 32; addr++) { for (bit = 0; bit < 4; bit++) { ht1621_send_data(addr, (unsigned char)(1 << bit)); } } }逻辑说明:外层循环遍历 32 个 RAM 地址,内层循环把当前地址的 4 位分别置 1。运行时你会看到液晶面板上一段的点阵被逐点点亮,如果某一段一直不亮,要么是该段对应地址和 bit 映射没对上,要么是面板本身漏接。
自检通过后如果觉得显示偏淡,修改初始化里 0x29 这个偏压档位命令。偏压档位越高,驱动电压越接近 VLCD,显示越深,但功耗也会上升。建议从低档位开始试,找到视觉舒适且不重影的档位。还有一种常见做法是调节 VLCD 分压电阻,两者可以搭配使用。
5. 避坑与排查:HT1621B 驱动中最容易翻车的5个位置
HT1621B 本身时序不复杂,但因为它和 LCD 玻璃是强绑定关系,很多问题看起来像程序 bug,实际是映射或配置问题。这一章是我拆完这个工程后整理出来的高频踩坑记录,每条都按现象、原因、解决三部分写,方便你快速对照。
5.1 屏幕全黑或全亮
现象:上电后 LCD 面板所有笔段都显示,或者全部消失,程序怎么看逻辑都没问题。
原因:HT1621B 的偏压或 COM 配置和面板不匹配,最常见的是没有设置正确的 1/2 bias 或 1/3 bias。另外 VLCD 悬空也会导致全黑,芯片没有足够的驱动偏压输出。
解决:先量 VLCD 电压,确认有电;再检查初始化命令里的偏压配置,对照 datasheet 的偏压选择位换成面板需要的值。我用这个工程时,全黑就是 VLCD 没接,当时查了半天代码,后来一量电压就明白了。
5.2 数字错位或乱码
现象:显示“12”却变成“21”,或者某个笔段一直多亮。程序逻辑看起来正确,显示数组也是按位填的。
原因:段码表和 LCD 面板硬件对应关系不一致。HT1621B 的 RAM 地址和 bit 位是与面板 COM/SEG 走线绑定的,不是通用规则。你按程序里的 seg_table.h 填数,但实际板子的 COM 走线方向可能反了。
解决:使用第四章的自检函数逐个点亮笔段,把每个地址和 bit 对应的实际玻璃笔段记录成一张表,再反推出正确的段码数组。测试工程里提供的就是一套已知正确的映射,但换面板后必须重新走一遍这个流程。
5.3 上电瞬间出现杂乱闪烁
现象:MCU 上电后,LCD 先闪几下乱码,再稳定显示正常内容。
原因:HT1621B 的 VDD 稳定比 MCU 慢,或者 MCU 复位期间 GPIO 处于高阻态,CS、WR、DATA 三个脚电平不定,芯片误收到随机数据。我在用这个工程时也遇到过,因为测试板上 MCU 和 LCD 共用电源,主控复位期间三根线全悬空。
解决:最常见做法是在 VDD 上电到稳定后,主程序延时几十毫秒再调用 ht1621_init;或者给 CS、WR、DATA 配上默认上拉或下拉电阻,让未初始化前的电平固定。工程里 main 函数第一步就是延时,把开 LCD 的时机放到系统稳定之后。
5.4 对比度太低,字迹发白
现象:能显示内容,但字很淡,特别是在视角偏斜时几乎看不清。
原因:偏压档位选得太低,或者 VLCD 电压不足。有些面板需要 3.3V 以上的驱动电压,此时 VLCD 直接接 VDD 不够。
解决:先把初始化里的偏压命令调高一档,观察对比度变化。如果还是淡,就在 VLCD 和电源之间加一个分压,或者把 VLCD 接到独立的可调电源。调对比度是个很吃经验的过程,我的习惯是先用不同偏压命令各跑一次,用手机拍下对比效果,再决定最终值。
5.5 刷新一闪一闪,肉眼可见闪烁
现象:数字变化时能明显看到扫描感,尤其多个笔段同时关闭时,残影重。
原因:HT1621B 的帧刷新率由系统振荡器分频决定,当写入 RAM 的速率和扫描帧不同步,或者 VLCD 上并联电容过大,都会让刷新变得不均匀。还有一个原因是刷新函数被放在高优先级中断里频繁调用,导致显示被切碎。
解决:把 ht1621_refresh 放进主循环,用定时器控制刷新频率,不要在中断里高频写显存。如果必须中断刷新,就把中断频率调到 200Hz 以内,并且刷新过程要一气呵成,中间不要被其他操作打断。
6. 二次开发:把自测程序改成你的产品显示界面
跑通自测只是第一步。真正做产品时,你需要把“全段点亮”的测试代码改成“显示业务数据”的界面代码。这里的改造重点是段码表、刷新机制和功耗。
6.1 先整理一张段码映射表
先把面板的显示区域拆成数字位、单位位、小数点,再为每个位置建立独立地址。常用做法是定义类似下面的结构体:
typedef struct { unsigned char addr; /* HT1621B RAM地址 */ unsigned char bit; /* 数据位 */ } seg_point; const seg_point digit_high = { 0x01, 0x02 };逻辑说明:通过结构体把逻辑显示元素,比如“小时十位”,和物理映射绑定。以后改板子只需要更新结构体里的 addr 和 bit,不用改业务代码。参数说明:addr 对应 RAM 地址 0~31,bit 对应 4 位数据中的 0~3。
6.2 用定时器驱动每秒刷新
产品界面必须由定时器驱动状态更新,不能用纯延时等待。用一个 1Hz 定时器标志位,在主循环里检查到标志后,更新显存数组并调用 ht1621_refresh。这样做有两个好处:刷新频率稳定,不会因为其他任务卡顿造成闪烁;而且主循环还有空闲时间处理按键和通信。
6.3 低功耗改造
笔段式 LCD 本身适合电池供电,但 HT1621B 默认可能不需要一直全速刷新。睡眠前调用关 LCD 命令,再关闭系统振荡器,能明显降低功耗。唤醒后重新 ht1621_init 并刷新显存。需要注意睡眠期间 CS、WR、DATA 三个引脚要拉高,防止芯片进入错误状态。
从那以后,我每次拿到新的笔段式 LCD 开发板,都强制走一遍完整流程:先查硬件接线,再跑全段自检,然后把显存映射表写在纸上,最后才写业务界面。前两步没做完,后面写再多代码也是空的。这个习惯帮我省掉了不少半夜加班的麻烦,希望帮到你。
本文还有配套的精品资源,点击获取