YL1621 LCD驱动芯片完全指南:从原理到STM32实战(附完整驱动代码)
在嵌入式产品开发中,LCD段码屏因其低功耗、高对比度、宽视角等优点,被广泛应用于电表、水表、血糖仪、空调面板、电动车仪表等场景。但直接用MCU驱动LCD屏不仅占用大量IO口,还需要复杂的时序控制和偏压电路。
今天给大家介绍一款高集成度的LCD驱动控制专用芯片——YL1621,它内置32×4点阵显示RAM,支持1/2或1/3偏置、2/3/4 COM配置,只需4根线就能和MCU通信,还自带蜂鸣器驱动、看门狗、时基定时器等实用功能,是段码LCD驱动的理想选择。
本文将从芯片特性、引脚定义、通信协议、命令体系到实际编程应用,全方位带你掌握YL1621。
一、YL1621 芯片概述
YL1621是远乐科技推出的一款存储器映射多功能LCD驱动电路,显示矩阵为32×4(共128点阵),专为扩展MCU I/O口而设计。其软件特性使其非常适合各类LCD显示应用,包括LCD模块和显示子系统。
1.1 核心特性
特性项 参数说明
LCD驱动 32 SEG × 4 COM(128点阵)
显示RAM 32×4位,直接映射LCD显示
偏置方式 1/2 或 1/3 Bias
占空比 1/2、1/3 或 1/4 Duty
通信接口 4线串行接口(CS/RD/WR/DATA)
系统时钟 内建256kHz RC振荡 / 外接32.768kHz晶振 / 外接256kHz时钟
工作电压 2.2V ~ 5.2V(宽电压)
工作温度 -40℃ ~ +85℃
蜂鸣器 2kHz / 4kHz 两种频率可选
时基/WDT 8级时基发生器 + 看门狗,8种时钟频率可选
低功耗 Power down模式,待机电流典型0.1μA
封装形式 SOP24/SSOP24/SOP28/SSOP28/SSOP48/LQFP44/LQFP48
1.2 典型应用领域
🚲 两轮电动自行车仪表
🏠 中央空调控制面板
⚡ 仪器仪表(水表、电表、煤气表)
💊 健康量测产品(血压计、血糖仪等)
🌬️ 家电产品(空气净化器、智能消毒柜等)
🧰 工业控制仪表、手持设备
二、引脚排列与功能说明
YL1621提供多种封装形式,从24脚到48脚不等,核心功能引脚一致,主要区别在于SEG输出的数量和封装尺寸。
2.1 引脚功能总览
类别 引脚名称 方向 功能说明
控制信号 CS I 片选信号(带上拉)。高电平时禁止通信并复位串行接口,低电平时允许传输
RD I 读时钟(带上拉)。下降沿输出数据,上升沿锁存数据
WR I 写时钟(带上拉)。上升沿锁存数据
DATA I/O 串行数据输入/输出(带上拉)
电源 VDD — 电源正
VSS — 电源地
VLCD I LCD电压输入,必须 ≤ VDD
时钟 OSCI I 振荡输入。接晶振或外部时钟,RC模式悬空
OSCO O 振荡输出。接晶振,RC模式悬空
中断 IRQ O 时基或WDT溢出输出,N沟道开漏输出
蜂鸣器 BZ, BZ O 蜂鸣器差分输出(2kHz/4kHz)
LCD驱动 COM0~COM3 O LCD公共端输出
SEG0~SEG31 O LCD段输出
💡 提示:不同封装的SEG数量不同,24脚封装通常只有20个SEG,28脚有24个,48脚才有全部32个SEG。选型时注意根据LCD屏的段数选择合适的封装。
2.2 封装选型参考
封装 引脚数 SEG数量 典型尺寸 适用场景
SOP24 24 ~20 15.4mm宽 小家电、简单仪表
SSOP24 24 ~20 8.66mm宽 空间紧凑的产品
SOP28 28 ~24 17.9mm宽 中等复杂度LCD
SSOP28 28 ~24 9.9mm宽 紧凑+中等段数
SSOP48 48 32 15.88mm宽 全段数应用
LQFP44 44 32 10×10mm 高密度PCB
LQFP48 48 32 7×7mm 超小体积产品
三、电气特性参数
3.1 极限参数
参数 符号 极限值 单位
电源电压 VDD -0.3 ~ +5.5 V
输入电压 VIN VSS-0.3 ~ VDD+0.3 V
工作温度 TOPG -40 ~ +85 ℃
储存温度 TSTG -50 ~ +125 ℃
ESD(HBM)VDD/VSS — ±6K V
ESD(HBM)其他引脚 — ±8K V
3.2 关键电气特性
工作电流
工作模式 条件 典型值 最大值 单位
工作电流(RC振荡) 3V,LCD开,无负载 60 100 μA
工作电流(RC振荡) 5V,LCD开,无负载 120 200 μA
工作电流(晶振) 3V,LCD开,无负载 30 50 μA
待机电流(Power down) 3V,无负载 0.1 5 μA
待机电流(Power down) 5V,无负载 0.3 10 μA
⚡ 低功耗亮点:Power down模式下待机电流仅0.1μA(典型值),非常适合电池供电的低功耗产品,如水表、燃气表等。
LCD驱动能力
参数 条件 典型值 单位
COM端灌电流 5V,VOL=0.5V 250 μA
COM端源电流 5V,VOH=4.5V -200 μA
SEG端灌电流 5V,VOL=0.5V 200 μA
SEG端源电流 5V,VOH=4.5V -100 μA
通信速率
参数 条件 最大值 单位
WR写时钟 5V 300 kHz
RD读时钟 5V 150 kHz
四、功能架构详解
4.1 显示存储器(RAM)
YL1621的显示RAM结构为 32×4位,直接映射到LCD驱动器。RAM的地址对应SEG编号(0~31),每个地址的4位数据对应4个COM端。
RAM地址映射:
地址 0 (SEG0) → D3 D2 D1 D0 → COM3 COM2 COM1 COM0
地址 1 (SEG1) → D3 D2 D1 D0 → COM3 COM2 COM1 COM0
地址 2 (SEG2) → D3 D2 D1 D0 → COM3 COM2 COM1 COM0
...
地址 31 (SEG31) → D3 D2 D1 D0 → COM3 COM2 COM1 COM0
📌 注意:RAM地址6位(A5A0),数据4位(D3D0)。写入时先传地址,再传数据,地址可自动累加。
4.2 系统振荡器
YL1621支持三种系统时钟源,可通过软件命令选择:
时钟源 命令 特点 适用场景
片内RC振荡 RC 256k 256kHz,无需外围元件 成本敏感、精度要求不高
外接晶振 XTAL 32k 32.768kHz,精度高 时钟、计时、精准蜂鸣
外接时钟 EXT 256k 256kHz,外部输入 同步系统时钟
💡 选择建议:如果需要精准的蜂鸣器频率或IRQ定时输出,建议使用外接32.768kHz晶振;对成本敏感且精度要求不高的应用,使用内部RC即可。
4.3 时基(Time base)与看门狗(WDT)
YL1621内置8级时基发生器和看门狗电路,共有8种时钟频率可选:
命令 时基输出频率 WDT溢出时间
F1 1Hz 4s
F2 2Hz 2s
F4 4Hz 1s
F8 8Hz 0.5s
F16 16Hz 0.25s
F32 32Hz 0.125s
F64 64Hz 0.0625s
F128 128Hz 0.03125s
时基 vs WDT的区别:
时基(Timer):周期性输出脉冲到IRQ引脚,可用于MCU的定时中断
看门狗(WDT):超时后将IRQ拉低,需要定期喂狗(CLR WDT),否则一直保持低电平
4.4 蜂鸣器输出
YL1621内置蜂鸣器驱动电路,提供一对差分输出BZ和BZ(反相),可直接驱动压电蜂鸣器。
频率选择:2kHz 或 4kHz
控制方式:TONE ON / TONE OFF 命令
输出形式:差分推挽输出,音量更大
五、通信协议详解
YL1621采用4线串行接口,通信协议比较有特色,下面详细讲解。
5.1 信号定义
信号 方向 功能
CS MCU→YL1621 片选,低电平有效。高电平时复位串行接口
WR MCU→YL1621 写时钟,上升沿锁存数据
RD MCU→YL1621 读时钟,下降沿输出数据
DATA 双向 串行数据,高位在前
5.2 操作模式
YL1621有两种操作模式,通过模式ID来区分:
模式 ID代码 功能
命令模式 100 发送配置命令
读模式 110 从RAM读取数据
写模式 101 向RAM写入数据
读改写模式 101 读-修改-写操作
📌 重要:模式ID出现在每次操作的最前面。如果是连续命令或连续数据,第一个之后的模式ID可以省略。当CS变高后,操作模式被复位,下次操作需要重新发模式ID。
5.3 写操作时序
写操作流程:
CS拉低,选中芯片
发送模式ID 101(写模式)
发送6位地址(A5~A0,高位先传)
发送4位数据(D3~D0,高位先传)
如果继续写,地址自动累加,直接发下一个4位数据
CS拉高,结束操作
写操作时序示意:
CS ──┐ ┌──────
└───────────────────────────────────┘
WR ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
───┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘
DATA [1][0][1][A5][A4][A3][A2][A1][A0][D3][D2][D1][D0]
↑模式ID↑ ↑ 6位地址 ↑ ↑ 4位数据 ↑
5.4 读操作时序
读操作流程:
CS拉低,选中芯片
发送模式ID 110(读模式)
发送6位地址(A5~A0)
切换DATA为输入方向
RD下降沿后数据出现在DATA线上
MCU在RD上升沿读取数据
继续读则地址自动累加
CS拉高,结束操作
5.5 命令操作时序
命令操作流程:
CS拉低
发送模式ID 100(命令模式)
发送9位命令码
如果是连续命令,后续命令的模式ID可省略
CS拉高
六、命令体系详解
YL1621的命令非常丰富,下面按功能分类整理。
6.1 系统控制命令
命令名称 命令代码(9位) 功能说明
SYS DIS 0000-0000-X 关闭系统时钟和LCD偏置(Power down)
SYS EN 0000-0001-X 打开系统时钟
LCD OFF 0000-0010-X 关闭LCD偏置发生器
LCD ON 0000-0011-X 打开LCD偏置发生器
⚠️ 上电默认状态:SYS DIS + LCD OFF。使用前必须先发送 SYS EN 和 LCD ON 命令,否则不显示。
6.2 时钟源选择命令
命令名称 命令代码 功能说明
XTAL 32k 0001-01XX-X 系统时钟:外接32.768kHz晶振
RC 256k 0001-10XX-X 系统时钟:内部RC振荡(默认)
EXT 256k 0001-11XX-X 系统时钟:外接256kHz时钟
6.3 LCD配置命令
命令名称 命令代码 功能说明
BIAS 1/2, 2COM 0010-00X0-X 1/2偏置,2个COM
BIAS 1/2, 3COM 0010-01X0-X 1/2偏置,3个COM
BIAS 1/2, 4COM 0010-10X0-X 1/2偏置,4个COM
BIAS 1/3, 2COM 0010-00X1-X 1/3偏置,2个COM
BIAS 1/3, 3COM 0010-01X1-X 1/3偏置,3个COM
BIAS 1/3, 4COM 0010-10X1-X 1/3偏置,4个COM
📌 怎么选偏置?
1/2偏置:适合2COM或3COM的LCD,驱动电路简单
1/3偏置:适合4COM的LCD,对比度更好,鬼影更少
6.4 蜂鸣器控制命令
命令名称 命令代码 功能说明
TONE OFF 0000-1000-X 关闭蜂鸣器
TONE ON 0000-1001-X 打开蜂鸣器
TONE 4k 010X-XXXX-X 蜂鸣频率4kHz
TONE 2k 011X-XXXX-X 蜂鸣频率2kHz
6.5 时基/WDT命令
命令名称 命令代码 功能说明
TIMER DIS 0000-0100-X 禁止时基输出
WDT DIS 0000-0101-X 禁止WDT溢出标志输出
TIMER EN 0000-0110-X 允许时基输出到IRQ
WDT EN 0000-0111-X 允许WDT溢出标志输出到IRQ
CLR TIMER 0000-11XX-X 清空调时基发生器
CLR WDT 0000-111X-X 清零看门狗(喂狗)
IRQ DIS 100X-0XXX-X 禁止IRQ输出
IRQ EN 100X-1XXX-X 允许IRQ输出
F1 ~ F128 101X-Xnnn-X 设置时基/WDT频率(8档)
6.6 其他命令
命令名称 命令代码 功能说明
NORMAL 1110-0011-X 普通模式(默认)
TEST 1110-0000-X 测试模式(仅工厂测试用)
七、典型应用电路
7.1 参考电路图
VDD
│
┌─────┴─────┐
│ 47uF 104 │ 电源滤波
└─────┬─────┘
│
┌──────┴──────┐
│ YL1621 │
│ │
CS──┤CS VDD ├─── VDD
WR──┤WR VSS ├─── GND
RD──┤RD VLCD ├───┐
│ │ │ 可调电阻
MCU─┤DATA OSCI ├───┤ 调节LCD对比度
│ OSCO├───┤
│ IRQ ├───→ MCU中断
│ BZ ├───┐
│ BZ ├───┤ 压电蜂鸣器
│ │ └──┐
│ COM0~COM3 ├───┐ │
│ SEG0~SEG31 ├───┤ │
└─────────────┘ │ │
│ │
┌────┴──┴────┐
│ LCD段码屏 │
└────────────┘
7.2 硬件设计注意事项
VLCD电压:VLCD必须 ≤ VDD,通过可调电阻调节LCD对比度。电阻值根据LCD屏的工作电压调整,一般在100k~1M之间。
电源滤波:VDD与GND之间接104(0.1μF)和47μF电解电容,尽量靠近芯片。
晶振选择:
使用内部RC:OSCI和OSCO悬空
使用外接晶振:接32.768kHz晶振,负载电容根据晶振参数选择(一般10~20pF)
晶振尽量靠近芯片,减少干扰
通信线:CS、WR、RD、DATA内部已有23kΩ上拉电阻,一般不需要额外上拉。
IRQ引脚:开漏输出,需要外接上拉电阻才能读回高电平。
蜂鸣器:BZ和BZ是差分输出,直接接压电蜂鸣器的两端即可,音量比单端驱动大很多。
八、STM32驱动代码示例
下面提供一份基于STM32 HAL库的YL1621驱动代码,包含LCD显示、蜂鸣器、时基等完整功能。
8.1 引脚定义
#include "stm32f1xx_hal.h"
/* YL1621 引脚定义 - 根据实际硬件修改 */
#define YL1621_CS_PORT GPIOA
#define YL1621_CS_PIN GPIO_PIN_0
#define YL1621_WR_PORT GPIOA
#define YL1621_WR_PIN GPIO_PIN_1
#define YL1621_RD_PORT GPIOA
#define YL1621_RD_PIN GPIO_PIN_2
#define YL1621_DATA_PORT GPIOA
#define YL1621_DATA_PIN GPIO_PIN_3
/* 快捷操作宏 */
#define CS_HIGH() HAL_GPIO_WritePin(YL1621_CS_PORT, YL1621_CS_PIN, GPIO_PIN_SET)
#define CS_LOW() HAL_GPIO_WritePin(YL1621_CS_PORT, YL1621_CS_PIN, GPIO_PIN_RESET)
#define WR_HIGH() HAL_GPIO_WritePin(YL1621_WR_PORT, YL1621_WR_PIN, GPIO_PIN_SET)
#define WR_LOW() HAL_GPIO_WritePin(YL1621_WR_PORT, YL1621_WR_PIN, GPIO_PIN_RESET)
#define RD_HIGH() HAL_GPIO_WritePin(YL1621_RD_PORT, YL1621_RD_PIN, GPIO_PIN_SET)
#define RD_LOW() HAL_GPIO_WritePin(YL1621_RD_PORT, YL1621_RD_PIN, GPIO_PIN_RESET)
#define DATA_HIGH() HAL_GPIO_WritePin(YL1621_DATA_PORT, YL1621_DATA_PIN, GPIO_PIN_SET)
#define DATA_LOW() HAL_GPIO_WritePin(YL1621_DATA_PORT, YL1621_DATA_PIN, GPIO_PIN_RESET)
#define DATA_READ() HAL_GPIO_ReadPin(YL1621_DATA_PORT, YL1621_DATA_PIN)
8.2 GPIO方向切换函数
/* 设置DATA引脚为输出 */
static void DATA_SetOutput(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = YL1621_DATA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(YL1621_DATA_PORT, &GPIO_InitStruct);
}
/* 设置DATA引脚为输入 */
static void DATA_SetInput(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = YL1621_DATA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(YL1621_DATA_PORT, &GPIO_InitStruct);
}
8.3 底层写操作函数
/* 写1位数据 */
static void YL1621_WriteBit(uint8_t bit)
{
WR_LOW();
if(bit)
DATA_HIGH();
else
DATA_LOW();
// 小延时,确保建立时间
HAL_Delay_us(1);
WR_HIGH(); // 上升沿锁存
HAL_Delay_us(1);
}
/* 写多个bit(高位在前) */
static void YL1621_WriteBits(uint32_t data, uint8_t bits)
{
uint8_t i;
for(i = 0; i < bits; i++)
{
if(data & (1 << (bits - 1 - i)))
YL1621_WriteBit(1);
else
YL1621_WriteBit(0);
}
}
/* 发送命令 */
void YL1621_SendCmd(uint16_t cmd)
{
DATA_SetOutput();
CS_LOW();
// 发送命令模式ID: 100
YL1621_WriteBits(0x04, 3);
// 发送9位命令码
YL1621_WriteBits(cmd, 9);
CS_HIGH();
}
/* 连续发送多个命令(省掉后续的模式ID) */
void YL1621_SendCmdMulti(uint16_t *cmds, uint8_t count)
{
uint8_t i;
if(count == 0) return;
DATA_SetOutput();
CS_LOW();
// 第一个命令带模式ID
YL1621_WriteBits(0x04, 3);
YL1621_WriteBits(cmds[0], 9);
// 后续命令省略模式ID
for(i = 1; i < count; i++)
{
YL1621_WriteBits(cmds[i], 9);
}
CS_HIGH();
}
8.4 RAM读写函数
/* 向指定地址写数据(4位) */
void YL1621_WriteRAM(uint8_t addr, uint8_t data)
{
DATA_SetOutput();
CS_LOW();
// 写模式ID: 101
YL1621_WriteBits(0x05, 3);
// 6位地址
YL1621_WriteBits(addr & 0x3F, 6);
// 4位数据
YL1621_WriteBits(data & 0x0F, 4);
CS_HIGH();
}
/* 从指定地址开始连续写 */
void YL1621_WriteRAM_Continuous(uint8_t startAddr, uint8_t *data, uint8_t len)
{
uint8_t i;
if(len == 0) return;
DATA_SetOutput();
CS_LOW();
// 写模式ID
YL1621_WriteBits(0x05, 3);
// 起始地址
YL1621_WriteBits(startAddr & 0x3F, 6);
// 连续写数据,地址自动累加
for(i = 0; i < len; i++)
{
YL1621_WriteBits(data[i] & 0x0F, 4);
}
CS_HIGH();
}
/* 从指定地址读数据(4位) */
uint8_t YL1621_ReadRAM(uint8_t addr)
{
uint8_t data = 0;
uint8_t i;
DATA_SetOutput();
CS_LOW();
// 读模式ID: 110
YL1621_WriteBits(0x06, 3);
// 6位地址
YL1621_WriteBits(addr & 0x3F, 6);
// 切换为输入
DATA_SetInput();
// 读4位数据
for(i = 0; i < 4; i++)
{
RD_LOW();
HAL_Delay_us(1);
data <<= 1;
if(DATA_READ())
data |= 0x01;
RD_HIGH();
HAL_Delay_us(1);
}
CS_HIGH();
return data;
}
8.5 初始化函数
/* YL1621 初始化 */
void YL1621_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO时钟使能 - 根据实际端口修改 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* 配置CS、WR、RD、DATA为推挽输出 */
GPIO_InitStruct.Pin = YL1621_CS_PIN | YL1621_WR_PIN | YL1621_RD_PIN | YL1621_DATA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 初始状态:所有信号高电平 */
CS_HIGH();
WR_HIGH();
RD_HIGH();
DATA_HIGH();
HAL_Delay(10); // 等待上电稳定
/* 发送初始化命令序列 */
uint16_t init_cmds[] = {
0x018, // SYS EN - 打开系统时钟
0x030, // RC 256k - 内部RC振荡
0x052, // BIAS 1/3, 4COM - 1/3偏置,4个COM
0x006, // LCD ON - 打开LCD
};
YL1621_SendCmdMulti(init_cmds, 4);
/* 清屏 */
YL1621_Clear();
}
/* 清屏 */
void YL1621_Clear(void)
{
uint8_t i;
uint8_t zero = 0;
for(i = 0; i < 32; i++)
{
YL1621_WriteRAM(i, 0);
}
}
8.6 蜂鸣器控制
/* 蜂鸣器开启 */
void YL1621_BuzzerOn(uint8_t freq)
{
uint16_t cmds[2];
if(freq == 2)
cmds[0] = 0x0C0; // TONE 2k
else
cmds[0] = 0x080; // TONE 4k (默认)
cmds[1] = 0x012; // TONE ON
YL1621_SendCmdMulti(cmds, 2);
}
/* 蜂鸣器关闭 */
void YL1621_BuzzerOff(void)
{
YL1621_SendCmd(0x010); // TONE OFF
}
/* 蜂鸣器响指定时长(ms) */
void YL1621_BuzzerBeep(uint16_t ms)
{
YL1621_BuzzerOn(4);
HAL_Delay(ms);
YL1621_BuzzerOff();
}
8.7 时基/WDT设置
/* 设置时基频率并使能IRQ输出 */
void YL1621_TimerInit(uint8_t freq_sel)
{
uint16_t cmds[4];
cmds[0] = 0x100 | (freq_sel & 0x07); // F1~F128
cmds[1] = 0x01C; // CLR TIMER
cmds[2] = 0x00C; // TIMER EN
cmds[3] = 0x140; // IRQ EN
YL1621_SendCmdMulti(cmds, 4);
}
/* 看门狗初始化 */
void YL1621_WDT_Init(uint8_t timeout_sel)
{
uint16_t cmds[4];
cmds[0] = 0x100 | (timeout_sel & 0x07); // 设置溢出时间
cmds[1] = 0x01E; // CLR WDT
cmds[2] = 0x00E; // WDT EN
cmds[3] = 0x140; // IRQ EN
YL1621_SendCmdMulti(cmds, 4);
}
/* 喂狗 */
void YL1621_WDT_Feed(void)
{
YL1621_SendCmd(0x01E); // CLR WDT
}
8.8 低功耗模式
/* 进入Power down模式 */
void YL1621_PowerDown(void)
{
uint16_t cmds[2];
cmds[0] = 0x004; // LCD OFF
cmds[1] = 0x000; // SYS DIS
YL1621_SendCmdMulti(cmds, 2);
}
/* 从Power down唤醒 */
void YL1621_WakeUp(void)
{
uint16_t cmds[2];
cmds[0] = 0x018; // SYS EN
cmds[1] = 0x006; // LCD ON
YL1621_SendCmdMulti(cmds, 2);
}
九、LCD段码屏显示编程技巧
9.1 显示缓冲区设计
建议在MCU中建立一个显示缓冲区,和YL1621的RAM一一对应,修改缓冲区后统一刷新:
uint8_t lcd_buf[32]; // 32个SEG,每个4位
/* 刷新整个LCD */
void YL1621_Refresh(void)
{
YL1621_WriteRAM_Continuous(0, lcd_buf, 32);
}
/* 设置某个段的亮灭 */
void YL1621_SetSeg(uint8_t seg, uint8_t com, uint8_t on)
{
if(seg >= 32 || com >= 4) return;
if(on)
lcd_buf[seg] |= (1 << com);
else
lcd_buf[seg] &= ~(1 << com);
}
9.2 数字显示函数
对于7段数字显示,需要根据LCD屏的实际段定义来写。下面是一个通用的数字显示模板:
/* 7段数字段码表 - 根据实际LCD屏修改
段定义:A B C D E F G 对应不同的SEG+COM组合 */
/* 假设数字的8个段(含小数点)分别在SEG0~SEG7,COM0 */
const uint8_t digit_table[] = {
0x3F, // 0: A B C D E F
0x06, // 1: B C
0x5B, // 2: A B G E D
0x4F, // 3: A B G C D
0x66, // 4: F G B C
0x6D, // 5: A F G C D
0x7D, // 6: A F G C D E
0x07, // 7: A B C
0x7F, // 8: 全亮
0x6F, // 9: A B C D F G
};
/* 显示一个数字(示例,需根据实际LCD修改) */
void LCD_ShowDigit(uint8_t pos, uint8_t num)
{
uint8_t seg_base = pos * 8; // 每个数字占8个SEG
uint8_t code = digit_table[num % 10];
uint8_t i;
for(i = 0; i < 7; i++)
{
if(code & (1 << i))
lcd_buf[seg_base + i] |= 0x01; // COM0亮
else
lcd_buf[seg_base + i] &= ~0x01;
}
}
📌 重要提醒:每款LCD屏的段定义都不一样,必须根据你手上LCD屏的规格书来确定每个SEG和COM对应的显示段。建议先做一个"全亮测试"程序,逐个点亮每个段来确认对应关系。
十、常见问题与调试技巧
10.1 LCD完全不亮
检查初始化顺序:必须先 SYS EN,再 LCD ON
检查VLCD电压:用万用表测VLCD引脚,应该有电压
检查偏置和COM设置:确保和LCD屏匹配
检查通信是否正常:用示波器或逻辑分析仪看WR和DATA波形
10.2 显示模糊、对比度低
调整VLCD电压:增大VLCD电压提高对比度
检查偏置设置:4COM建议用1/3偏置
检查LCD工作电压:确认LCD屏的额定工作电压
10.3 有鬼影(不该亮的段微亮)
检查偏置设置:偏置太低容易有鬼影
检查VLCD:VLCD电压过高可能导致鬼影
检查COM和SEG的接线:确认没有接错
10.4 蜂鸣器不响
检查命令顺序:先设频率(TONE 2k/4k),再 TONE ON
检查BZ和BZ:确认蜂鸣器接在两个输出之间
检查系统时钟:确保系统时钟已开启(SYS EN)
10.5 IRQ无输出
检查IRQ命令:先 TIMER EN 或 WDT EN,再 IRQ EN
检查上拉电阻:IRQ是开漏输出,需要上拉
检查时基设置:确认频率设置正确
10.6 调试小技巧
全亮测试:往所有RAM写0x0F,看是否所有段都亮
逐段测试:逐个SEG点亮,确认段对应关系
用逻辑分析仪:抓CS/WR/DATA波形,对照时序图检查
十一、总结
YL1621是一款功能非常全面的LCD驱动芯片,主要优势有:
✅ 高集成度:32×4 LCD驱动 + 蜂鸣器 + WDT + 时基,一颗芯片搞定多种功能 ✅ 节省IO:只需4根线(CS/WR/RD/DATA)就能控制 ✅ 低功耗:Power down模式仅0.1μA,电池供电产品首选 ✅ 宽电压:2.2V~5.2V,兼容3.3V和5V系统 ✅ 多封装:从SOP24到LQFP48,满足各种空间需求 ✅ 工业级:-40℃~+85℃,适应恶劣环境
对于电表、水表、血糖仪、空调面板、电动车仪表等段码LCD应用,YL1621能大大简化硬件设计,降低BOM成本,是一款非常值得推荐的LCD驱动芯片。
如果你正在做相关的项目,不妨试试这款芯片。有任何问题欢迎在评论区交流讨论!
参考资料:YL1621产品说明书 V01(远乐科技,晶圆代码YLE011A)
如果本文对你有帮助,欢迎点赞、收藏、关注三连支持!有问题可以在评论区留言,我会尽量回复。
更多推荐

所有评论(0)