小尺寸段码屏编程实战:用最少IO口驱动数十个段码的低功耗方案
段码屏省IO的核心不是“每个段一根线”,是把段排成COM×SEG矩阵做动态扫描。静态驱动每段独占一根SEG+单COM,32段就要33根线;改1/4 duty后COM只有4根,SEG按列数走,几十段也能压到十几根IO。
一、先吃透三个参数
屏厂规格书必给:
Duty:COM数量倒数,1/4 duty=4个COM轮流选通
Bias:偏压比,1/2或1/3,决定非选通段上的残余电压
VLCD:驱动电压,一般3V屏
偏压配错最典型现象是“该灭的段微微发灰”,重影去不掉。 常见搭配:1/2 duty配1/2 bias,1/4 duty配1/3 bias。
液晶必须交流驱动,COM和SEG之间平均直流电压要为0,否则屏会极化报废。
二、两种方案选型
方案A:MCU带LCD控制器(SLCD/IPLcd)
最省事,配好时钟/占空比/偏压寄存器,显存放RAM,硬件自动扫,主循环休眠。
方案B:纯GPIO模拟
COM少(2~4)、SEG不多时能用。COM脚配三态,扫描到某COM时设为推挽输出,其他COM高阻经电阻偏到VDD/2;SEG脚按显示位输出同相/反相。
方案C:外挂HT1621/1622
性价比最高,I2C或3线串口,MCU只写RAM,芯片自己扫。段数≤128、COM≤4直接选它。
量产穿戴/仪表基本走C,纯GPIO模拟适合成本抠到极致的电子秤、水表。
三、显存结构:按COM分组
别按“数字位”存,按COM存。4COM屏显存就是4个字节数组,每个字节的bit对应各SEG:
#define COM_NUM 4
#define SEG_BYTES 8
static uint8_t lcd_ram[COM_NUM][SEG_BYTES]; // 1=亮
数字“8”的7段a~g落在不同COM上,建映射表:
/* 某位数digit的段→(com, bit) */
typedef struct { uint8_t com; uint8_t seg; uint8_t bit; } seg_pin_t;
const seg_pin_t seg_map[7] = {
{0,0,0},{1,0,1},{1,0,2},{3,0,3},
{2,0,4},{0,0,5},{2,0,6} // a,b,c,d,e,f,g示例
};
void digit_set(uint8_t dig, uint8_t val){
for(int s=0;s<7;s++){
const seg_pin_t*p=&seg_map[s];
if(val & (1<<s))
lcd_ram[p->com][p->seg] |= (1<<p->bit);
else
lcd_ram[p->com][p->seg] &= ~(1<<p->bit);
}
}
拿到屏先问厂要COM-SEG映射图,不然段位错乱查半天。
四、GPIO模拟扫描
定时器中断里只做一件事:选通当前COM,按lcd_ram刷SEG。
static uint8_t cur_com = 0;
void lcd_scan_tick(void){
com_set_hiz_all();
com_drive(cur_com, phase); // 当前COM推挽输出
uint8_t inv = phase ^ 1;
for(int s=0;s<SEG_BYTES;s++){
uint8_t out = lcd_ram[cur_com][s];
seg_write(s, phase ? out : ~out); // 显示段反相=加压差
}
phase ^= 1;
if(phase==0){
cur_com = (cur_com+1)%COM_NUM;
}
}
时序要点:
扫描周期总时长≈COM数×2相位,4COM每相位2ms→刷新约60Hz
非选通COM高阻经47k偏到VDD/2
SEG在显示位与COM反相,非显示位同相
相位交替翻转,保证交流
五、HT1621类:只写脏数据
带驱动IC时MCU完全不用扫时序,写RAM即可:
static uint8_t lcd_dirty = 0;
void lcd_update(void){
if(!lcd_dirty) return; // 没变不通讯
ht1621_write_ram(0, &lcd_ram[0][0], COM_NUM*SEG_BYTES);
lcd_dirty = 0;
}
初始化按手册配duty/bias,先清RAM再开显示,避免开机乱码:
ht1621_cmd(SYS_EN);
ht1621_cmd(LCD_ON);
ht1621_cmd(RC_32K | BIAS_1_3 | DUTY_1_4);
ht1621_clear_ram();
六、低功耗落地
段码玻璃本身μA级,功耗大头在MCU和背光。 做法:
显示内容不变→不写驱动IC
MCU进STOP/Sleep,定时唤醒或中断唤醒
HT1621独立供电,RAM保持屏幕不闪
背光能省就省,非要亮用PWM调低占空
进深睡前发LCD OFF,唤醒再ON
典型手持测温:1秒醒一次→读传感→刷RAM→睡,平均电流个位数μA级。
七、落坑清单
直流驱动段码→屏永久残影报废
bias配错→灭段发灰重影
显存按“数字”排→扫描时四个COM都得拆,代码乱
每次改都重发全屏→I2C占用高、闪
COM没高阻→非选通段也被加压
扫描周期太长→肉眼闪;太短→IO翻转吃电流
映射表不找厂要→段位对不上
背光常亮→段码屏省的那点全白省
八、落地顺序
确认屏duty/bias/VLCD
小段数用HT1621,多COM用MCU SLCD
建lcd_ram[COM][SEG]
段码映射表对齐物理屏
定时器扫描(GPIO方案)或写RAM(IC方案)
脏标记更新
MCU休眠+周期唤醒
段码屏“最少IO”的本质就是动态扫描+显存位映射:COM分时选通,SEG按位输出,交流压差交给偏压网络或驱动IC。MCU不直接盯屏、只改RAM、脏了才写、闲了就睡,几十段界面用十来根IO就能稳住,续航也比TFT省一个数量级。





