
简介HT1621B 驱动笔段式液晶显示屏的完整测试工程包面向嵌入式开发中需要快速验证显示驱动逻辑的工程师也适合正在学习笔段式液晶显示原理的初学者。资源共 31 个文件以 IAR EWARM 完整工程为主体包含 C 源码文件、IAR 工程配置ewp/eww、hex 烧录文件、xcl 链接配置文件以及调试批处理、备份工程和输出目录各部分用途清晰便于对照学习。通过阅读这些文件可掌握串行接口初始化、寄存器配置、显示数据写入和自动消影等关键代码路径理解 HT1621B 驱动最多 48 个笔段、支持多种显示模式的实际用法。工程还体现了低功耗设计思路适合电池供电的电子表、智能家居控制面板等场景从驱动初始化到显示刷新均有完整示例可循。压缩包仅 144KB结构紧凑可直接参考其驱动框架完成移植。已有 1005 人学习配套测试说明覆盖静态显示、动态显示、亮度调节等场景结合示例工程能快速定位硬件连线或时序问题有效缩短液晶驱动开发与验证周期。 前几天整理硬盘里的老物料翻出一个有年份的压缩包HT1621B驱动LCD测试过完整.rar。这个名字很朴素但当年为它熬过好几个晚上。HT1621B这颗芯片在段码LCD驱动领域属于常青树电子秤、温湿度计、血糖仪、万用表、智能电表上到处都有它的身影体积小、外围省、价格低一颗芯片加几颗电阻电容就能把一块液晶玻璃变成“写显存就能显示”的外设。这篇东西不打算复述数据手册而是把这个完整驱动从硬件接线、通信协议到代码实现和实测坑点重新梳理一遍尤其在极化、feedthrough、对比度这几个容易翻车的地方多说几句。正在用51、STM32或ESP32折腾段码屏的朋友可以直接当作业抄。1. 为什么是HT1621B一颗把段码LCD变成“简单外设”的芯片1.1 段码LCD和点阵屏完全不是一回事很多从OLED、TFT入门的开发者第一次拿到段码LCD会懵屏幕怎么没有控制器实际上段码LCD本质是一块电容性玻璃亮度由COM线和SEG线之间的交流电压差决定任何一条线上出现长时间直流分量都会导致液晶材料电解、极化时间长了屏幕会出现永久黑斑。所以驱动段码屏不是简单给引脚加高电平就行需要用固定的波形定时翻转COM和SEG电平专业说法叫交流驱动。这件事听起来不复杂但用单片机纯IO口去做非常难受先是引脚占用——显示8位数字加一堆图标几十个段口一个都不能少再是波形频率——刷新太快MCU忙不过来刷新太慢屏幕会闪还要保证波形严格对称否则直流分量迟早搞坏玻璃。这就是HT1621B这类专用驱动芯片存在的意义。1.2 HT1621B的核心优势HT1621B是Holtek出的段码LCD驱动芯片内部集成128 bit显示RAM、RC振荡器、偏压电阻网络和COM/SEG扫描逻辑。MCU只需要通过3线或4线串行接口把显示数据写进去之后芯片自己生成交流驱动波形MCU完全不用管刷新这件事。它支持的配置也很灵活最多32个SEG段口、4个COM口可选1/2或1/3偏压、1/4到1/1占空比工作电压大概2.4V到5.2V一颗芯片就能带动一整块常用段码玻璃。和同系列对比HT1621B是改进版本HT1621A/B几乎兼容而HT1622能支持更多COM、驱动更大的玻璃屏。对于绝大多数仪表类项目HT1621B的128点已经足够。型号最大点阵典型场景HT1621B128点32 SEG x 4 COM电子秤、温湿度计、血糖仪HT1622256点支持更多COM多图标、多路数字显示面板MCU直接IO驱动看引脚数只适合极少量段且不计成本的情况一句话总结HT1621B把最麻烦的交流扫描和偏压管理全包了MCU负责的只是“告诉它哪个段亮、哪个段灭”。这也是那个rar里驱动能“测试过完整”的根本原因——芯片分担了绝大部分时序压力。2. 硬件连接与上电细节显示正常的第一步2.1 典型接线一览段码LCD模组和HT1621B之间通常是玻璃的COM/SEG引脚直接焊到芯片的COM0~COM3和SEG0~SEG31上这部分由液晶玻璃厂商的图纸决定不需要软件干预。开发者真正要关心的是MCU和HT1621B之间的接口。HT1621B引脚接到哪里说明VDD系统电源3.3V或5V就近放0.1uF去耦电容VSSGND可靠接地VLCD偏压输入决定对比度具体见2.2CSMCU GPIO片选低有效WRMCU GPIO写时钟数据在上升沿锁存DATAMCU GPIO双向数据线RDVDD不需要读显存时直接接高COM0~COM3LCD玻璃COM引脚直接连屏SEG0~SEG31LCD玻璃SEG引脚直接连屏我见过不少人把RD悬空正常工作时问题不大但悬空脚容易引入干扰最好接VDD。如果只往HT1621B里写数据不读显存RD接高就够了读显存功能基本用不到。2.2 VLCD偏压和对比度别看只是颗电阻VLCD是调节对比度的关键。HT1621B内部有偏压发生器外部通常需要配合电阻分压网络或可调电阻把偏压设置在合适电平。偏压太低段码显示淡、像没睡醒偏压太高不该亮的段也会“鬼影”微亮整个屏灰蒙蒙。大多数厂商的段码玻璃模组会直接配套好偏压电阻甚至把电阻做在玻璃柔性板上这种情况直接用默认配置即可。如果自己画板建议VLCD到VDD之间留一个可调电阻焊盘调试时先调到中间值再根据显示效果微调。实测中常见问题是为了追求显示浓把VLCD调过头结果出现全屏微亮这时候不是程序问题而是偏压过冲。偏压和COM数量还要通过命令配置匹配比如玻璃设计是1/3偏压、4 COM软件里就写对应的BIAS/COM配置命令。这部分后面代码里会提到。2.3 上电时序别在电源爬坡时发命令硬件上电时建议等VDD稳定后再拉高CS和WR然后延时几十毫秒再初始化HT1621B。曾经遇到过一个很怪的现象板子上电瞬间屏幕显示一坨乱码过一会儿自己好了。查到最后是MCU比HT1621B先跑起来在电源还没稳定的时候就发出了初始化命令芯片没能正确接收。解决方法是MCU启动后先延时100ms再初始化HT1621B或者让HT1621B的VDD由MCU的IO控制先上电。另外去耦电容要尽量靠近芯片VDD引脚不要省。段码LCD是电容性负载COM/SEG翻转瞬间电流不小电源上有毛刺会导致显示抖动。3. 通信协议和显存映射驱动代码的地基3.1 3线还是4线多数情况用3线HT1621B支持3线和4线两种接法。3线用CS、WR、DATA不接RD适合纯写应用4线多一个RD口可以从芯片读回显存内容。电子秤、仪表这类应用大多数只需要写显示数据3线就够了还能省一个GPIO。时序本身不复杂核心是“数据准备好之后给WR一个上升沿”。CS拉低表示一次通信开始WR上升沿把DATA上的电平锁存进芯片。每发一个bitWR都要从低到高跳变一次。整个过程就是按位把数据“抖”进去跟模拟SPI很像。3.2 命令和数据两种帧结构必须分清HT1621B的通信帧分两种写命令和写数据。格式差别在开头3位标志位。帧类型起始标志后续内容写命令1019位命令码写数据1106位RAM地址 8位数据这就是网上很多代码看着不一样的原因有的函数传参传9位命令码有的函数把“101”也算进去了。我看到过一堆驱动里写WriteCmd(0x28)、WriteCmd(0x52)其实说的都是BIAS/COM配置只是代码里有没有把开头3位标志组装进去的区别。自己写驱动时建议统一按“标志位 内容”的原始格式实现底层函数封装好后面改起来不迷糊。常用命令有这么几条命令含义9位命令码不含101标志说明System Enable0x001打开系统振荡器必发System Disable0x000关闭系统省电LCD On0x003打开LCD输出LCD Off0x002关闭LCD输出显示全灭BIAS/COM配置0x052常见值1/3偏压、4 COM务必按玻璃手册调整注意BIAS/COM配置的值取决于具体液晶玻璃0x052是很多4 COM小玻璃常用的写法但不是所有屏通用。拿到新屏第一件事是查玻璃规格书确认偏压是1/2还是1/3COM是几位再填这个命令。3.3 RAM地址和COM/SEG的关系HT1621B内部显示RAM共128 bit组织方式可以理解为一张表横向SEG地址纵向COM位。写入数据时6位地址指向某个SEG地址8位数据中的每一位对应COM0~COM34 COM模式下只用到低4位。这里有个新手最容易犯的错想点亮某个笔段以为是按COM或SEG直接编址结果写进去发现错位。实际上要拿到液晶玻璃的“段位映射图”看这个笔段接在SEG几、COM几然后到对应的RAM地址和位上去写1。因为一次WriteData会覆盖某个地址的8位数据直接操作某个笔段会破坏同地址其他COM位的状态。稳妥做法是MCU里维护一个32字节的显示缓冲Buffer先改Buffer再整段刷新或者用Read-Modify-Write流程从芯片读回原值再改位。绝大多数驱动都用Buffer方式代码简单还不依赖RD引脚。4. 完整驱动实现可抄作业的代码4.1 底层IO时序WR上升沿锁存下面以8051为例给一套完整实现。IO定义根据自己板子改核心逻辑通用// ht1621b.c 部分 #include reg52.h #include intrins.h sbit HT1621_CS P2^0; sbit HT1621_WR P2^1; sbit HT1621_DAT P2^2; // 简单延时按MCU主频调整 static void HT1621_Delay(void) { _nop_(); _nop_(); _nop_(); } // 发送1bit先WR拉低放数据再WR拉高上升沿锁存 static void HT1621_SendBit(unsigned char dat) { HT1621_WR 0; HT1621_DAT dat ? 1 : 0; HT1621_Delay(); HT1621_WR 1; HT1621_Delay(); } // 发送cnt个bit从高位开始 static void HT1621_SendBits(unsigned long dat, unsigned char cnt) { unsigned char i; for (i 0; i cnt; i) { unsigned char bitv (unsigned char)((dat (cnt - 1 - i)) 0x01); HT1621_SendBit(bitv); } }顺序不能反必须先WR0再送DATA最后WR1。如果先送DATA后拉WR虽然多数情况下也能工作但WR上升沿可能正好落在DATA转换的毛刺上高温或线长时容易随机出错。4.2 命令封装与初始化// 写命令101标志 9位命令码 void HT1621_WriteCmd(unsigned short cmd) { HT1621_CS 0; HT1621_SendBits(0x05, 3); // 0x05 二进制就是 101 HT1621_SendBits(cmd, 9); HT1621_CS 1; } // 写数据110标志 6位地址 8位数据 void HT1621_WriteData(unsigned char addr, unsigned char dat) { HT1621_CS 0; HT1621_SendBits(0x06, 3); // 0x06 二进制就是 110 HT1621_SendBits(addr, 6); HT1621_SendBits(dat, 8); HT1621_CS 1; } // 初始化 void HT1621_Init(void) { HT1621_CS 1; HT1621_WR 1; HT1621_DAT 1; HT1621_Delay(); HT1621_WriteCmd(0x001); // System Enable HT1621_WriteCmd(0x052); // 1/3 bias, 4 COM按你的玻璃手册调整 HT1621_WriteCmd(0x003); // LCD On HT1621_Clear(); }初始化顺序值得注意先System Enable再配置BIAS/COM最后LCD On。反过来先打开LCD输出再配置偏压上电瞬间可能出现短暂乱码。这里把Clear函数放在LCD On之后是有意的——先把显示内容清空再开输出避免旧显存内容在屏幕上闪一下。4.3 显示Buffer和段码表unsigned char HT1621_Buf[32]; // 32个SEG地址4 COM模式低4位有效 // 把某个SEG地址、某个COM位的状态写进Buffer void HT1621_SetSegBit(unsigned char segAddr, unsigned char com, unsigned char on) { if (on) HT1621_Buf[segAddr] | (0x01 com); else HT1621_Buf[segAddr] ~(0x01 com); } // 整屏刷新 void HT1621_Refresh(void) { unsigned char i; for (i 0; i 32; i) HT1621_WriteData(i, HT1621_Buf[i]); } void HT1621_Clear(void) { unsigned char i; for (i 0; i 32; i) HT1621_Buf[i] 0; HT1621_Refresh(); }这里必须强调代码里的HT1621_SetSegBit(segAddr, com, on)只是底层设置函数具体显示“数字0”、“数字1”需要一张段码表把每个笔段对应到具体的SEG地址和COM位。每个厂家玻璃的走线都不一样网上抄来的表基本不能直接用。我拿到新屏的第一件事就是找屏幕厂商要段位走线图然后在Excel里画一张“SEG/COM对应笔段”的表再写成C数组。这一步偷懒后面全是坑。4.4 亮度调节和闪烁两个实用小技巧HT1621B没有直接的“软件亮度寄存器”但可以通过周期性切换LCD On/LCD Off来实现视觉上的亮度调节。思路是在定时器中断里做一个PWM每10ms一个周期LCD On持续时间和LCD Off持续时间按目标亮度分配。unsigned char brightness 8; // 0~10越大越亮 void Timer_ISR(void) // 假设定时器每1ms中断一次 { static unsigned char cnt 0; cnt; if (cnt 10) cnt 0; if (cnt brightness) HT1621_WriteCmd(0x003); // LCD On else HT1621_WriteCmd(0x002); // LCD Off }注意这个方案有代价频繁发命令会占用MCU时间也会增加芯片功耗和EMI。量产品上我更推荐用硬件调VLCD电压或换偏压档位来调节对比度软件PWM只适合调试阶段或临时演示。闪烁功能就简单了定时器里每一定周期让整屏显隐切换即可。只闪某个数字的话在Buffer里把那一位的段全部清零或点亮再调用HT1621_Refresh()。5. 实测踩坑极化、feedthrough和“鬼影”问题5.1 LCD极化不是玄学长时间直流会毁屏段码LCD的液晶材料一旦长时间承受直流电压会发生电化学反应产生不可逆的“极化”损坏表现是屏幕某个区域变黑、出现残影或者某段永远显示。这就是“LCD极化避免”要解决的问题。HT1621B在正常工作时内部会交替改变COM和SEG的电压极性保证每个像素上平均直流分量为零所以芯片本身已经把极化风险处理掉了。但调试时经常有人图省事用杜邦线直接给玻璃的COM和SEG接VDD和GND测试看某个段亮不亮。这种做法很危险几秒钟可能没事时间稍长液晶就废了。正确做法永远是先写好HT1621B的初始化通过WriteData点亮笔段。另外屏幕长时间显示同一内容虽然波形是交流的但部分段长期处于同一偏置状态可能出现类似烧屏的记忆效应软性段码屏尤其明显。我的习惯是产品里做一个“屏幕保护”逻辑如果画面长时间不变每隔一两秒把所有段全亮一下再恢复把肉眼不可见的电荷积累打散。这个在医疗和工控仪表里很常见。5.2 feedthrough是怎么来的寄生电容在捣乱feedthrough穿透效应是段码LCD驱动里一个很经典的现象。LCD的COM线和SEG线在玻璃上并行布得很近之间存在寄生电容。当COM线电压翻转时电荷会通过寄生电容耦合到SEG线上导致SEG电压瞬间被抬高或压低。如果这个瞬态幅度恰好超过液晶的阈值电压本不该亮的段就会“偷亮”一下。屏幕内容一直在变时人眼看到的是某些段有轻微闪烁或重影固定画面时表现为个别笔段微微发灰尤其偏压调高后更明显。解决feedthrough有固定的三板斧降低VLCD电压让偏压刚好满足显示对比度即可别追求越浓越好检查偏压配置的档位1/3偏压和1/2偏压对阈值裕量影响很大在PCB布局上注意COM/SEG走线不要过长平行减少寄生电容耦合软件上能做的有限但有个细节WR翻转不要用超高速给LCD驱动波形留一点爬坡时间有时候能明显减少“偷亮”。我在某个项目里把IO翻转速度从最高档降到中等档鬼影就消失了。5.3 一次花屏排查链路从电源到波形的完整排查有个典型故障值得复盘板子通电后全屏正常但刷新数字时随机出现几条“毛刺段”闪一下有时还出现显示变淡。排查链路是这样的先看电源。示波器表笔贴近HT1621B的VDD引脚发现刷新瞬间电源上有明显毛刺幅度接近200mV。原因屏幕刷新瞬时电流大去耦电容放得太远。在VDD和VSS之间补了0.1uF陶瓷电容毛刺降到50mV以内但问题没消失。再看VLCD电压发现调得偏高屏幕整体有点“蒙”。适当降低偏压后闪段明显减少。最后检查WR线发现MCU的IO翻转速度过快加上杜邦线太长信号反射严重。降低翻转速度、拉长每bit延时后问题彻底解决。这个案例说明段码屏显示异常很多时候不是代码逻辑错而是电源、偏压、信号完整性三个环节的连锁反应。排查顺序建议固定为电源纹波 - VLCD/偏压 - 通信时序 - 布线。5.4 对比度调整的正确顺序对比度太低、太强、有鬼影处理顺序应该是先确认偏压档位命令和玻璃一致再调VLCD电阻最后才考虑是不是feedthrough。很多人一上来就改代码折腾半天发现是VLCD电阻焊错了。另外调试时手上最好有一个精密可调电位器临时代替固定电阻找到合适阻值后再换成固定电阻。我曾经图省事直接焊固定电阻结果换了批次玻璃后对比度偏淡不得不重新打样教训深刻。6. 从51到ESP32快速移植与扩展思路6.1 把IO模拟时序搬走的三个改动点这个驱动最大的优点就是纯IO模拟几乎不依赖单片机外设移植到ESP32、STM32只改三处IO宏定义51的sbit换成gpio_set_level或HAL库的HAL_GPIO_WritePin延时函数51的_nop_()换成几个微秒的延时ESP32上用esp_rom_delay_us底层IO初始化把CS、WR、DAT三个GPIO配成推挽输出SPI硬件外设也能驱动HT1621B但要注意HT1621B不是标准SPI从机没有寄存器地址自动递增这类特性硬件SPI反而容易在时序细节上吃亏。我自己试过用ESP32的SPI主机方式驱动时钟极性、相位都要调而且CS控制不直接最后又换回IO模拟。除非对性能有极致要求否则IO模拟是更稳的选择。6.2 没有段码表怎么下手从网上下载的“完整驱动”最缺的东西往往是段码表。真没有图纸时可以自己“扫”出来写一个测试程序循环对每个SEG地址、每个COM位写1刷新后拍照记录哪个笔段亮了人工整理出一张映射表。这个过程枯燥但很可靠。注意有些玻璃的SEG/COM在PCB上经过了跳线或转接不一定是芯片引脚顺序直接对应玻璃引脚顺序。扫描时要以芯片的SEG0~SEG31、COM0~COM3为基准反复对照照片标注。6.3 这个驱动还能用在哪些项目里HT1621B适合所有段码LCD显示场景典型的有电子秤称重模块HT1621B4位数码段码屏成本极低温湿度计显示温度、湿度、时间、闹钟图标电池电量表显示电量百分比和电池图标小家电面板微波炉、咖啡机的状态显示我后来把这段驱动封装成简洁的接口更换不同液晶玻璃时只需要替换一张段码表和BIAS/COM配置命令其余代码原封不动。那次踩完“换批次玻璃对比度变淡”的坑之后我在每个项目设计阶段都会提前找屏幕厂要段位图并且把偏压电阻位做成可调电阻焊盘。最近还在做的一件事是把HT1621B驱动和低功耗唤醒结合芯片进去休眠前清空显示并关掉LCD On唤醒后重新初始化功耗能压低不少。这个方向如果你也在做电池供电的段码屏产品值得顺带研究一下。本文还有配套的精品资源点击获取