简介面向嵌入式开发者的HT1621B笔段式LCD驱动完整工程包适用于低功耗显示模块的选型、硬件验证与固件调试。资源基于IAR Embedded Workbench搭建共收录31个文件、压缩后仅144KB包含驱动源码、头文件、IAR工程与工作区配置、调试下载脚本、批处理文件、Hex固件以及编译中间产物覆盖代码编辑、编译链接、烧录调试全流程。已有1005人学习参考。文件中自带完整的LCD测试例程可直接复用芯片初始化、数据发送与显示亮度控制等底层驱动帮助读者快速掌握通过SPI接口操作HT1621B的时序与寄存器配置减少逐位翻阅数据手册的麻烦对智能仪表、小家电控制面板等笔段屏项目的快速落地很有价值。 通常看到这种带“.rar”的工程包第一反应都是“又是个能跑就行的demo”。但这个HT1621B的驱动包不一样标题里“测试过完整”四个字说明作者把驱动、电路、验证、甚至下载链路都整整齐齐沉淀下来了。我从事单片机开发这么多年接到过不少LCD显示的需求从最早的1602字符屏、12864点阵屏到后来段码屏配合HT1621系列驱动芯片这中间踩过的坑比很多人想象中要多得多。这篇就借HT1621B驱动LCD这套工程把从芯片原理、硬件连接、驱动编写到实际调试的完整链路盘一遍尤其针对8051这类经典平台把那些“文档上不会写、但实战一定会遇到”的细节翻出来晒晒。1. 项目拆解为什么是HT1621B而不是直接驱动LCD1.1 8051直驱LCD的局限与HT1621B的核心价值先回答一个很多新手会问的问题LCD背后的引脚不多为什么还要加一颗HT1621B要知道8051单片机要直接驱动段码LCD面临的麻烦是结构性的第一引脚资源根本不够。常见的8位段码屏一个数字“8”就要7段再加上小数点一个字符就是8个段。一个4位显示就需要32个段8051一共就32个IO口光驱动显示屏就用光了后面别想接任何按键和传感器。第二LCD驱动需要AC信号不能加直流。LCD的显示原理是靠电场控制液晶分子偏转如果让某个段长期处于恒定直流电压下液晶材料会不可逆地劣化这就是常说的“极化”。8051直接操作IO拉高拉低没有专门的时序产生AC波形稍微一疏忽就是永久性损坏屏幕。第三扫描刷新本身就是CPU的负担。即便引脚够MCU还得不停扫描刷新、维持对比度、处理偏压极性翻转占用的CPU资源会直接影响主业务。HT1621B解决的就是这三个核心痛点。它内部集成了LCD偏压发生器、AC波形产生电路、显示RAM和4*4键盘扫描接口是妥妥的“LCD显示协处理器”。8051只需要通过3根线CS、WR、DATA和它交换数据剩下的显示刷新全由HT1621B自动完成。选型思路总结来说就是主控只管业务逻辑显示刷新交给专用芯片分工清晰后续移植到STM32、ESP32上只需要改底层IO操作显示逻辑可以原封不动搬走。1.2 “测试过完整”四个字的实际分量说句实话做嵌入式的都懂能把外设驱动“调亮”和“测试过完整”完全是两码事。“调亮”是碰运气“测试过完整”是一种工程交付标准。我个人理解这套工程能贴上这个标签背后应该覆盖了四层验证第一层是硬件通路验证CS、DATA、WR三根线时序是否正确屏的偏压是否正常每一个SEG和COM引脚是否能正常点亮对应的段。第二层是功能验证所有显示位逐一亮灭测试、动态刷新测试、显示稳定性测试至少持续数小时无明显闪烁。第三层是软件健壮性验证驱动不干扰主程序运行、按键扫描不漏检不误检、低电压环境下显示依然清晰。第四层是交付完整性验证代码注释清楚、接线图明确、常见问题有记录。这套工程里有这么完整的东西放在网上基本可以当教材用了。2. 硬件连接与原理图设计的几个关键抉择2.1 三线SPI连接方式与上拉电阻的取舍HT1621B和主控之间的通信接口可以配置成3线或4线模式这套工程用的是3线模式CS片选、WR写时钟、DATA双向数据线。在连接8051的时候我通常建议在DATA线上加一个10kΩ的上拉电阻。上拉电阻这件事是热词里提到“4*4键盘用不用上拉电阻”所关联的问题但放在通信线上也同样适用。HT1621B的DATA线在大部分时间里是输入模式只有在读按键状态的时候才切换成输出模式。8051的IO口如果是准双向口内部有弱上拉不加电阻多数时候也能跑但抗干扰能力会弱一截。如果用的是开漏模式或者外部扩展IO不加电阻就完全无法工作。所以在DATA线上保留1个10kΩ电阻是稳妥习惯成本几分钱换来的是时序稳定性的提升。CS和WR线上其实不必额外上拉因为正常时序下这两条线有明确的高低电平驱动加上拉反而可能影响信号边沿。另外有个很多人忽略的细节HT1621B的VDD范围是2.4V到5.2V8051常见的5V系统可以直接供电但如果系统电压是3.3V需要注意HT1621B的输出高电平是否和8051的电平兼容。老款8051的输入高电平阈值是2.0V3.3V供电的HT1621B输出高电平通常在3.0V以上理论上兼容实际跑也基本没问题但稳妥起见在批量产品上建议加电平转换或者选用带5V容忍功能的单片机型号。2.2 4x4键盘扫描上拉电阻到底要不要这个问题被问得很多直接给结论需要而且必须接。HT1621B的键盘扫描功能是通过内部的上拉/下拉开关配合读引脚电平实现的。当它在扫描某个按键行时内部会临时开启该行引脚的上拉然后去读列引脚的电平。这种情况下如果键盘引脚外部没有接任何上拉电阻检测结果会完全依赖内部那点微弱的上拉力量在潮湿环境、长走线场景下很容易误触发。我遇到过一次真实案例一块板子键盘扫描偶发性误触发查到最后就是没加上拉电阻导致的。HT1621B内部上拉在开启瞬间有毛刺按键按下瞬间电平拉升不够陡峭导致读到的电平状态不稳定。最后在8根键盘线4行4列上各加了一个10kΩ排阻问题彻底消失。如果你也在用HT1621B做键盘扫描这8个电阻别省。2.3 LCD偏压、亮度与极化避免的电路实现LCD亮度调节这件事在段码屏上跟背光完全是两回事。段码屏没有背光所谓的“亮度”实际是对比度。HT1621B内部有一个偏压选择寄存器BIAS通过命令字设置常见配置是1/3偏压或1/4偏压对应不同工作电压的液晶屏。具体的选压逻辑是显示屏的驱动电压大约等于LCD工作电压的1/31/3偏压模式或1/41/4偏压模式剩余电压通过内部分压电阻网络产生。LCD液晶材料对电压比较挑剔电压过高会变黑糊成一团过低则显示极淡。实际调试时我一般先把BIAS配置成数据手册推荐值然后通过调节VLCD引脚外部电容通常1μF到2.2μF以及电源电压来微调对比度。如果屏幕显示“全黑”大概率是偏压设置过高如果显示“白茫茫一片”则要检查偏压是否过低。至于极化避免HT1621B内部会自动产生AC波形翻转液晶驱动电压极性这个不需要用户干预。需要外界配合的是不要在软件里强制设置某些段常亮这会导致对应段长期处于直流偏置状态。正确做法是所有需要亮起的段都通过正常的显示RAM写入不需要亮的段保持清零让芯片的AC波形自然管理极性。3. 软件驱动核心逻辑与工程实现细节3.1 命令系统梳理写命令、写数据、读按键在写驱动代码之前务必要先理解HT1621B的三类通信操作。这三类操作通过CS和WR的时序配合来区分而不是通过不同的指令码。第一类是命令操作Command Operation。主机往HT1621B写入一个命令字用于配置偏压、开启振荡器、设置显示模式等。命令字长度通常是9位1位标志8位数据但有的命令更长。命令写入时CS必须拉低然后在WR的上升沿或下降沿按位写入。第二类是数据操作Data Operation。主机写入显示RAM的数据。HT1621B的显示RAM是32个4位的半字节正好对应128个点和4个COM口。写数据前必须先设置写模式WRMOD命令然后连续写入地址会自动递增。第三类是读操作Read Operation。主机从HT1621B读取按键扫描结果。读操作需要先把DATA线切换成输入模式然后主机给WR时钟从DATA线上一位一位读回来。初次接触这套体系的时候容易混淆命令和数据特别是网上能找到的代码风格五花八门有的用GPIO模拟SPI有的用硬件SPI但底层通信协议是一样的。抓住“命令先写、RAM后写、按键最后读”这个主线驱动就清晰了。3.2 初始化序列一步都不能少的开机流程HT1621B的初始化其实很容易踩坑尤其是刚上电时如果不先开振荡器就写显示RAM数据会丢。正常的初始化顺序应该是这样void HT1621_Init(void) { // 1. 系统配置命令使能偏压发生器、打开振荡器 HT1621_WriteCmd(0x29); // 1010 1001: sys_en1, sys_dis0, bias1/3, sys_clk1 // 2. 显示配置命令开启显示、设置占空比1/4占空比 HT1621_WriteCmd(0x02); // 1010 0010: lcd_on1, duty1/4 // 3. 清空显示RAM for (uint8_t i 0; i 32; i) { HT1621_WriteData(i 2, 0x00); } }命令字0x29和0x02的具体格式不同厂家的数据手册标注略有差异但底层含义一致。初始化之后显示RAM是全零状态屏幕不会乱显示这时候再往指定地址写数据屏幕就能按预期显示内容。有个细节值得注意每次写命令时需要把CS拉低再拉高形成一个片选周期确保命令被正确锁存。连续操作时CS可以保持低电平但中间要留足够的时钟间隔一般至少几个微秒。USB转TTL下载调试的时候时序如果被下载工具的中断打断偶尔会出现花屏就是这些时序间隔不够稳定导致的。3.3 段位地址映射与显示中文的处理思路HT1621B的显示RAM映射非常直观每个COM口对应一个位每个SEG口对应一个RAM半字节中的一位。显示屏上的段位置与RAM地址的对应关系要看屏幕厂家提供的段位表。比如一个“8”字标准7段加上小数点会分布在若干个SEG引脚上软件层面就要把这些段拼成一个完整的字形编码。驱动代码里核心是一个“显示缓存”数组长度32字节专门对应HT1621B的全部显示RAM。每次要更新显示内容先改这个缓存数组再把整个缓存刷到芯片上。这样做的好处是避免了零散写数据导致的中间态闪烁。至于中文显示段码屏不同于点阵屏它不能自由显示任意汉字。段码屏能显示的中文是有限的通常是预先在玻璃上刻好的固定字符比如“电压”、“电流”、“温度”、“报警”等。软件只能控制这些预刻字符段的亮灭不能像点阵屏那样逐点子显示。如果你想用段码屏显示任意中文只能换用点阵LCD或者OLED方案但如果是固定几个汉字的显示场景段码屏加HT1621B的成本优势是点阵方案无法比拟的。3.4 键盘扫描代码的时序细节HT1621B的按键扫描原理很巧妙扫描时它会按顺序驱动COM口作为行检测SEG口的电平状态如果在某个COM口为高电平的时段内SEG口也读到高电平就说明该点有按键按下。整个过程全由芯片硬件完成软件只需要读出结果。读键盘的代码大致结构如下uint8_t HT1621_ReadKey(void) { uint8_t value 0; // 先切换到读模式 HT1621_WriteCmd(0x40); // READ_MODE命令 // DATA线切换为输入 GPIO_Data_Mode(GPIO_MODE_INPUT); // 拉低CS等待D0按键有效标志 CS_LOW(); // 读取key data8位 for (uint8_t i 0; i 8; i) { WR_HIGH(); value 1; if (DATA_READ()) value | 0x80; WR_LOW(); } CS_HIGH(); // 恢复DATA线为输出 GPIO_Data_Mode(GPIO_MODE_OUTPUT); return value; }这段代码里最关键的是主机读之前必须给HT1621B足够的准备时间。这个准备时间通常在命令发出后的毫秒级别如果太快去读芯片还没准备好读回来的全是0xFF。有人在这地方卡了很久其实是时序微调的问题。4. 工程代码的模块化设计与CH340下载链路4.1 驱动文件怎么组织才算“完整”参考这套“测试过完整”的工程组织方式我建议驱动代码按三层拆分而不是把所有函数堆在一个main.c里第一层是硬件抽象层HAL对应HT1621_HAL.c和HT1621_HAL.h。这一层负责最底层的IO操作包括CS、WR、DATA三条线的拉高拉低、方向切换、微秒级延时。将来换平台比如从8051换成STM32只需要改这一层。第二层是芯片驱动层对应HT1621.c和HT1621.h。这层基于HAL层实现HT1621B的命令读写、显示RAM刷新、键盘读取。对外提供类似HT1621_Init、HT1621_DisplayString、HT1621_ReadKey这样的接口。第三层是应用层对应main.c或者app_display.c。这一层只和芯片驱动层打交道不直接碰IO业务逻辑和显示逻辑完全分离。三段式设计的好处不仅仅是结构清晰更重要的是方便复用。比如你要把这个驱动移植到ESP32上HAL层重写一遍换GPIO操作芯片驱动层几乎不用动应用层完全不动工作量直接下降了80%。4.2 CH340串口下载与调试工具链经验8051平台的程序下载老思路是并口下载器但现在的笔记本根本没有并口主流做法是用USB转串口芯片接单片机的最小系统下载。热词里提到的CH340是非常常用的USB转UART芯片稳定性比最早的PL2303方案好得多驱动安装也方便。实际使用CH340连接8051做下载调试时有几个注意点一是下载速度别拉太高。8051的烧录时序受限于内部RC振荡器的精度速度太高容易烧录失败。我一般习惯用9600或者19200的波特率烧录稳定且不容易出幺蛾子。二是下载后要断电重新上电。CH340连接下如果单片机在上电状态下直接切换烧录模式偶发会遇到程序烧成功了但运行异常的情况重新上电一下就好。三是USB电源的干净程度。CH340如果直接给目标板供电而目标板上又有HT1621B这类对电压敏感的芯片务必在目标板的VCC和GND之间并联一个100μF电解电容和0.1μF陶瓷电容。USB口供电浪涌比较多不加电容HT1621B的偏压发生器偶尔会抽风屏幕会出现莫名其妙的闪动。4.3 显示内容的编码表与字库处理段码屏的显示和字形码是强绑定的。具体来说一个“共阴”或“共阳”的段码屏要显示出“0-9”和“A-F”以及一些特殊符号需要手动做一张编码表。以下是一段针对典型段码屏的0-9编码示例对应SEG0-SEG6分别是a,b,c,d,e,f,g段COM映射到字节位const uint8_t code font_table[] { 0xC0, // 0: abcdef (a1,b1,c1,d1,e1,f1,g0,dp0) 0xF9, // 1: bc 0xA4, // 2: abdeg 0xB0, // 3: abcdg 0x99, // 4: bcfg 0x92, // 5: acdfg 0x82, // 6: acdefg 0xF8, // 7: abc 0x80, // 8: abcdefg 0x90 // 9: abcdfg };注意不同厂家的屏幕段与引脚的对应关系可能有差异这份表是“标准段序”下的编码实际使用前必须对着自己手里的屏的规格书核对。有的屏把DP小数点接在了高电平有效端有的接低电平有效同一个数字编码可能显示完全不一样。比较稳妥的办法是调试阶段用“逐段点亮”的方式校准编码表先只点亮a段再只点亮b段逐个确认段序后再填入编码表。看起来多花十分钟实际能省下一个下午的瞎猜时间。5. 调试血泪史从“不亮”到“亮得漂亮”的排查路径5.1 LCD完全不亮时的排查顺序遇到屏幕完全不亮先别急着怀疑代码。我总结了一个排查顺序基本能覆盖九成以上的情况第一步查电源用万用表量HT1621B的VDD和GND看电压是否在芯片工作范围内。第二步查振荡器HT1621B内置振荡器可以通过命令打开或关闭。如果初始化时忘了开振荡器芯片完全不工作。测试这个的最快方法初始化之后去读按键寄存器如果所有按键都读不到有效数据大概率是振荡器没开。第三步查CS和WR时序用示波器或者逻辑分析仪抓CS、WR、DATA三根线确认波形是否符合数据手册的时序要求。没有示波器的话可以在软件里反复拉高CS、延时、再拉低听屏幕有没有反应。这种“盲敲”方式虽然不优雅但有时候真的好使。第四步查偏压设置如果屏幕发黑或者完全不显示把BIAS相关命令逐条尝试。偏压设置错误不会让芯片死掉但会让液晶的驱动电压完全不对显示效果会很差。5.2 显示乱码、闪烁与feedthrough干扰的抑制经验乱码的原因九成是通信时序不稳定或者显示RAM数据被意外改写。比较典型的场景是在主程序执行长延时比如处理其他传感器的时候刷新显示不及时屏幕出现局部残影或者闪烁。解决思路是把显示刷新放到定时中断里比如每5ms刷新一次。段码屏对刷新率要求不高但低于30Hz的刷新会有明显闪烁感。中断里刷屏主循环专心跑业务逻辑两者互不干扰。还有一类更隐蔽的问题是feedthrough干扰。这个词在段码屏行业里指的是液晶像素的寄生电容耦合效应当某个COM口切换电压时会对其他段的显示状态产生瞬态干扰。在电路板布线时SEG线和COM线尽量远离特别是高频信号线比如晶振引脚要避开LCD排线区域。还有包地处理在LCD排线下方连续覆铜接地能明显降低feedthrough引起的鬼影现象。软件层面可以在刷新前先延时几个毫秒等LCD驱动电压稳定再写入下一批数据虽然降低了刷新率上限但换来的是更干净的显示效果。在注重显示质量的场合这个取舍值得做。6. 这套工程的扩展思路与个人实践心得说实话HT1621B这颗芯片虽然年纪不小但用好了是真的省心。到目前为止我在三个量产项目上用过它一个温控器、一个定时插座、一个简单的电压表全部稳定运行没有一例显示相关的售后问题。对于拿到这套“HT1621B驱动LCD测试过完整.rar”的朋友建议先照下面的顺序来操作第一步准备好最小硬件系统8051/STM32C8T6或类似开发板HT1621B模块段码LCD屏。第二部打开工程包里的原理图对照自己手上的屏的引脚定义确认SEG和COM的接法。第三步编译驱动代码先只跑初始化全段点亮测试确认每一段都能亮。第四步跑自带的Demo显示程序验证数字、字母显示。第五步接上4x4键盘测试按键扫描。把这五步走完整套驱动的心法基本就掌握了。还有一点关于后续扩展如果你想把这个驱动从8051平台移植到STM32或者ESP32上重点只改HAL层。8051代码里的sbit定义换成GPIO操作延时函数换成SysTick或HAL_Delay上层命令和数据结构完全不用动。我试过从8051移植到STM32F103顺畅的话一个小时就能跑通这个复用效率就是分层设计带来的最大红利。最后再分享一个调试小技巧。HT1621B写显示数据时如果一次要刷很多字节中间可以故意加一个微小的延时比如每4字节延时10μs这样能避免极端情况下DATA线上的电平建立时间不够导致数据错位。这个方法在普通环境下不是必须的但在屏线比较长超过20cm的时候你会发现这个延时是性价比非常高的抗干扰手段。本文还有配套的精品资源点击获取