2. 硬件连接与初始化:LCD引脚定义、电源与背光电路、初始化时序、复位序列
好,咱们进入正题。上一章我们把LCD的选型聊完了,这一章要动真格的了——把屏幕焊上去,让它亮起来。
说实话,硬件连接这块,我见过太多人栽跟头。明明代码写得没问题,屏幕就是不亮。最后拿万用表一量,哦,背光没供电。或者复位引脚悬空了。嗯,这些坑我都踩过,今天咱们一个一个填上。
2.1 LCD引脚定义:别被密密麻麻的引脚吓到
你拿到一块LCD模块,翻到背面,看到一排引脚——少则16个,多则40个。别慌。其实真正要你操心的,就那么几个。
我以最常用的128×64点阵屏为例,它通常是20个引脚。咱们挑关键的讲:
| 引脚编号 | 符号 | 功能说明 | 我给你的建议 |
|---|---|---|---|
| 1 | VSS | 电源地(GND) | 必须接,别偷懒 |
| 2 | VDD | 电源正(3.3V或5V) | 看数据手册,别猜 |
| 3 | VO | 对比度调节 | 接电位器到VDD,调到你看着舒服 |
| 4 | RS | 数据/指令选择 | 高电平=数据,低电平=指令 |
| 5 | R/W | 读/写选择 | 我们一般只写,直接接地 |
| 6 | E | 使能信号 | 下降沿锁存数据,关键信号 |
| 7~14 | DB0~DB7 | 8位数据总线 | 4位模式只用高4位 |
| 15 | LED+ | 背光正极 | 串电阻限流,别直连 |
| 16 | LED- | 背光负极 | 接地 |
我个人习惯,把RS、E、DB4~DB7这四个信号接到MCU的连续GPIO上,方便后面用位操作。你想想看,如果引脚分布得乱七八糟,写代码时移位操作能把你逼疯。
2.2 电源与背光电路:供电不稳,一切白搭
LCD模块的电源,说白了就两路:一路给逻辑电路,一路给背光。
逻辑电源: 大部分模块支持3.3V或5V。但注意,有些老模块只认5V。我建议你养成好习惯——先看数据手册的“Supply Voltage”一栏。我曾经在一个项目里,直接把3.3V接到一个5V模块上,结果屏幕灰蒙蒙的,字都看不清。后来加了电平转换才搞定。
背光电路: 这里有个坑。背光LED的典型电流是20mA~80mA,但很多模块的背光引脚没有内置限流电阻。你要是直接接3.3V,电流可能飙到100mA以上,轻则屏幕发烫,重则烧掉背光。
正确的做法是串一个电阻。阻值怎么算?很简单:
R = (VCC - V_LED) / I_LED
举个例子:
VCC = 3.3V,V_LED ≈ 3.0V(白光LED典型值)
I_LED = 40mA(取中间值)
R = (3.3 - 3.0) / 0.04 = 7.5Ω
实际取标称值10Ω,电流约30mA,够亮了。
如果你想让MCU控制背光开关(比如血糖仪在待机时关掉背光省电),可以用一个NPN三极管:
// 伪代码示意
#define BACKLIGHT_PIN PB0
void backlight_on() {
set_gpio_high(BACKLIGHT_PIN); // 三极管导通,背光亮
}
void backlight_off() {
set_gpio_low(BACKLIGHT_PIN); // 三极管截止,背光灭
}
2.3 初始化时序:别急着发数据,先让屏幕醒过来
LCD模块上电后,不会马上准备好接收指令。它内部有个复位过程,需要一点时间。这个时间,数据手册上叫“Power-on Reset Time”,一般是10ms~100ms。
我见过有人上电后立刻发指令,结果屏幕没反应。为什么?因为模块还在“睡懒觉”。正确的初始化流程应该是:
- 上电——给VDD和VSS供电
- 等待——延时至少40ms(保守点给100ms)
- 发复位指令——0x30(8位模式)或0x20(4位模式)
- 再等待——延时4.5ms以上
- 发功能设置——告诉屏幕用几线、几行、什么字体
- 发显示开关——先关掉显示,配置好再打开
- 清屏——把显存里的垃圾数据清掉
- 开显示——终于可以显示内容了
这里我贴一段实际项目里用过的初始化代码,用的是4位模式:
void LCD_Init(void) {
// 1. 上电后等待
delay_ms(50);
// 2. 复位序列(4位模式专用)
// 先发三次0x30,让屏幕进入8位模式
LCD_WriteCmd_4bit(0x30);
delay_ms(5);
LCD_WriteCmd_4bit(0x30);
delay_ms(5);
LCD_WriteCmd_4bit(0x30);
delay_ms(5);
// 3. 切换到4位模式
LCD_WriteCmd_4bit(0x20);
delay_ms(5);
// 4. 功能设置:4位模式,2行,5x7点阵
LCD_WriteCmd(0x28);
delay_ms(1);
// 5. 显示开关:关显示
LCD_WriteCmd(0x08);
delay_ms(1);
// 6. 清屏
LCD_WriteCmd(0x01);
delay_ms(2);
// 7. 输入模式:光标右移,不移位
LCD_WriteCmd(0x06);
delay_ms(1);
// 8. 开显示,关光标
LCD_WriteCmd(0x0C);
delay_ms(1);
}
2.4 复位序列:硬件复位 vs 软件复位
LCD模块通常有两种复位方式:
- 硬件复位: 通过RST引脚拉低再拉高。简单粗暴,但需要多占用一个GPIO。
- 软件复位: 通过发指令序列来复位。省引脚,但时序要求严格。
我个人更倾向于软件复位,因为省引脚。在血糖仪这种小设备上,GPIO是稀缺资源,能省一个是一个。
但如果你发现屏幕初始化后显示异常(比如花屏、乱码),可以试试硬件复位。我曾经在一个项目中,屏幕偶尔上电后显示错位,加了硬件复位后问题就消失了。说白了,硬件复位更可靠,但软件复位更方便。
硬件复位的典型时序是这样的:
void LCD_HardReset(void) {
// 拉低RST引脚
set_gpio_low(RST_PIN);
delay_ms(10); // 保持低电平至少10ms
// 拉高RST引脚
set_gpio_high(RST_PIN);
delay_ms(50); // 等待内部复位完成
}
小结
这一章的内容,说白了就是三件事:
- 引脚连接: 别接错,尤其是电源和背光
- 电源电路: 背光要串电阻,别直连
- 初始化时序: 上电后等一等,复位序列别省
下一章,咱们要开始写驱动函数了——往屏幕上写一个字符,让它真正显示出来。到时候你会发现,前面这些硬件工作做得越扎实,后面写代码就越顺手。
嗯,今天就到这儿。有问题欢迎在评论区留言,我看到会回复。