两个IO口,四根线!51单片机IIC控制LCD1602的究极偷懒方案!!! 51单片机51单片机是一个历史悠久、应用极其广泛、且非常适合初学者入门的8位微控制器系列。它并非特指某一种芯片而是泛指所有兼容Intel 8051指令系统的单片机统称。自20世纪80年代诞生以来它在工业控制、仪器仪表、消费电子等领域留下了深刻的印记至今仍是国内高校单片机教学和无数电子爱好者入门的首选平台。技术特点与核心优势51单片机能经久不衰主要得益于以下几点极简架构易于上手其经典的哈佛结构和精简的指令集让初学者能快速理解单片机的底层工作原理。成本低廉选择丰富芯片本身价格低配套的开发工具和学习资源也非常成熟丰富降低了入门门槛。资源典型覆盖广泛集成了CPU、RAM、ROM、I/O端口、定时器、中断系统以及UART等串行通信接口足以应对大多数基础的控制任务。主要产品与型号演进可以从以下几个维度来了解51单片机家族的产品经典51子系列与52子系列这是最基础的分类。主要的区别在于内部存储资源的多少。以经典8051为例其内部有128字节RAM和4KB ROM而52子系列如8052则增加到256字节RAM和8KB ROM。主流厂商与芯片市场上涌现了大量兼容芯片主流厂商包括Intel英特尔鼻祖MCS-51系列的创造者其80C51、87C51等是原始设计的基础。Atmel艾特梅尔其AT89C51、AT89S51系列曾风靡一时是早期开发板和DIY项目的首选。STC宏晶科技国产厂商其STC89C52等系列凭借增强性能、在线编程ISP和中文资料在国内极受欢迎。其他厂商还包括Philips飞利浦、华邦、Dallas达拉斯、Siemens西门子等。应用场景虽然性能已非顶尖但凭借极高的性价比51单片机仍在许多领域发挥着作用。工业自动化广泛用于可编程逻辑控制器PLC、传感器接口和数据采集系统。消费电子许多家用电器如洗衣机、空调、微波炉等其核心控制单元可能就是一颗51单片机。教育与科研作为高校“单片机原理”等课程的教学核心用于验证基本原理和培养编程思维。智能家居常用于家庭安防系统、智能照明等逻辑相对简单的子系统。I2C介绍I2CInter-Integrated Circuit内部集成电路是一种由飞利浦公司现恩智浦半导体在1980年代开发的两线式串行通信总线。它主要用于在电路板级别的短距离、低速设备之间进行数据传输比如连接微控制器、传感器、存储器、LCD驱动器如你之前问到的PCF8574等。简单来说I2C是一种让多个芯片之间只用两根线就能“通话”的协议因其引脚少、连接简单、支持多设备在嵌入式系统中极其常用。核心特点两线制仅需两根信号线。SDA (Serial Data Line)串行数据线用来传输实际的数据。SCL (Serial Clock Line)串行时钟线用来同步数据传输的节奏。主从架构总线上可以挂载多个设备。主设备通常是单片机负责产生时钟、发起和结束通信从设备如传感器、PCF8574则听从主设备的指令。多主设备支持理论上总线上可以有多个主设备它们之间通过仲裁机制决定谁获得控制权。设备寻址每个从设备都有一个唯一的7位或10位地址。主设备通过发送这个地址来指定要与哪个设备通信。半双工数据可以在两个方向上传输但不能同时进行。内置应答机制接收方在收到每字节数据后会回复一个应答位发送方能据此确认传输是否成功提高了可靠性。物理层与电气特性总线需要接上拉电阻通常为4.7kΩ。在空闲时SDA和SCL线都被上拉至高电平。设备通过将线路拉低来输出信号。支持多种速率模式由慢到快标准模式100 kbit/s快速模式400 kbit/s高速模式3.4 Mbit/s协议层一次完整的数据传输一次典型的数据传输包含以下几个清晰的步骤就像一次标准的对话起始信号主设备发号施令。在SCL高电平时主设备将SDA线从高电平拉低到低电平。这告诉所有从设备“注意要开始新的通信了”发送设备地址主设备发送7位或10位的从设备地址再加上一位读写控制位0表示“我要写”1表示“我要读”。等待应答主设备释放SDA线。被寻址到的从设备会拉低SDA线来回应“收到我在呢” 这个应答位就是ACK。发送/接收数据主设备和从设备开始按约定的方向传输数据。每个字节是8位最高有效位MSB先发。每发送完一个字节都会跟着一个应答位由接收方发出。停止信号通信结束。在SCL高电平时主设备将SDA线从低电平拉高到高电平。这告诉所有设备“本次通信结束总线空闲了。”I2C的优缺点优点缺点引脚占用极少只需2个GPIO口。速度相对较慢不如SPI串行外设接口快。支持多主多从结构灵活。功耗相对较高因为上拉电阻会消耗电流。连接简单设备挂在同一条总线上不需要像SPI那样用片选线区分。每个设备都需要唯一地址地址冲突会导致通信失败。有应答机制增强了通信可靠性。协议比UART稍复杂需要理解起始、停止、应答等概念。应用广泛几乎所有微控制器和无数传感器都支持。受限于总线电容线缆不能太长通常建议几米以内。常用iic器件序号器件类型典型型号主要功能 / 应用场景1I/O 扩展器PCF8574, MCP23017通过I2C扩展数字I/O引脚常用于驱动LCD1602、按键矩阵等2EEPROM 存储器AT24C02, CAT24C256非易失性数据存储保存系统配置、用户参数、小容量数据日志3温湿度传感器SHT30, AHT20, HDC1080测量环境温度和相对湿度用于智能家居、气象站、温室监控4气压/高度传感器BMP280, LPS22HB测量大气压力和海拔高度应用于无人机定高、手机气压计5环境光传感器BH1750, OPT3001测量光照强度Lux用于屏幕亮度自动调节、智能照明6OLED 显示驱动SSD1306, SH1106驱动小型OLED单色屏幕如0.96英寸 128×64显示文字和图形7实时时钟 (RTC)DS1307, PCF8563, DS3231提供精确的日期和时间带电池备份用于电子钟、数据记录器8ADC / DAC 转换PCF8591, ADS1115, MCP4725模数转换读取模拟电压或数模转换输出模拟信号9姿态/惯性测量MPU6050, ICM-20948集成加速度计和陀螺仪部分带磁力计用于计步、平衡车、姿态解算10I2C 多路复用器TCA9548A将一路I2C总线扩展为8个独立通道解决多设备地址冲突问题LCD1602 字符型液晶显示模块LCD1602是一种工业级字符型液晶模块由HD44780控制器驱动可显示2行、每行16个ASCII字符。它采用5V供电内置192个常用字符的字库含英文字母、数字、日文假名及特殊符号也支持用户自定义8个5×8点阵字符。模块采用16引脚接口核心信号包括RS数据/命令选择、RW读/写选择、EN使能脉冲以及8位或4位并行数据线D0~D7。为节省I/O口常与PCF8574等I2C转并行芯片配合使用此时仅需SDA、SCL两线即可控制。使用时需注意通过外接电位器调节VO引脚电压以改变显示对比度背光通常由A和K引脚供电初始化必须严格按时序设置如4位模式、显示开/关、清屏等。其低功耗、高可靠性、显示清晰的优点使其广泛应用于电子表、温度计、智能仪表等嵌入式设备是初学者的理想入门模块。IIC转LCD1602模块介绍IIC转LCD1602模块本质上是一个为LCD1602字符液晶显示屏专门设计的“转接板”或“驱动板”。它通过一个I2CIIC接口芯片通常是PCF8574将LCD1602所需的众多并行控制引脚转换为仅需两根线的I2C串行接口。模块通常由LCD1602显示屏、PCF8574 I2C I/O扩展芯片和一个用于调节屏幕对比度的蓝色电位器三部分组成。PCF8574芯片的I2C地址可通过其引脚A0、A1、A2进行修改以此避免总线上多个设备的地址冲突。其中一些模块可能还会有背光控制的跳线帽用于开启/关闭背光、背光调节电阻以及数据位选择电阻。引进配置VCC接电源正极通常为5V。GND接电源地线。SDAI2C数据线接单片机的对应I2C数据引脚。SCLI2C时钟线接单片机的对应I2C时钟引脚。PCF8574实物图LCD1602实物图:iic转lcd1602实物图proteus 仿真电路图51代码实现#include REG52.H #include intrins.H /* PCF8574 地接的常见情况? PCF8574接地方式与I2C接线完整说明 A0、A1、A2引脚接地主要用于设置PCF8574的I2C设备地址。PCF8574默认7位地址为0x20实际写地址计算方式为(0x20 1) | 0 0x40。 若A0、A1、A2全部接地设备7位地址为0x20对应写地址为0x40若A0接VCC、A1和A2接地设备7位地址为0x21对应写地址为0x42。 在LCD1602与PCF8574搭配使用时R/W引脚通常固定接地设置为只写不读模式能够简化程序逻辑同时节省单片机IO资源。 PCF8574的INT引脚为开漏输出引脚主要用于中断信号通知常规使用场景下直接悬空即可。该引脚接地会影响中断功能若项 目无需使用中断功能可忽略该影响接地或悬空都不影响屏幕正常显示。 PCF8574的P0~P3引脚对应LCD1602的RS、R/W、E控制引脚P4~P7对应LCD1602的D4~D7数据引脚部分转接板引脚定义存在差异使用前需查阅对应模块官方文档。 I2C地址配置示例 PCF8574模块A0、A1、A2全部接地时7位设备地址为0x20I2C写操作发送地址为0x40。市面上常见的蓝色PCF8574转接板默认自带引脚拉高 7位地址为0x27对应I2C写地址为0x4E。实际使用中建议通过I2C扫描工具确认模块真实设备地址从根源避免I2C通信失败、屏幕不显示、乱码等问题。 关键注意事项 LCD1602的R/W引脚建议接地51单片机开发中一般无需读取LCD状态该接法可节省IO口同时规避读写时序异常问题。I2C通信总线需要在SDA、SCL引脚 分别接入4.7kΩ上拉电阻至VCC保障总线通信稳定。使用PCF8574驱动LCD1602必须遵循HD44780标准初始化流程依次发送三次0x30指令再发送0x28指令 切换四线工作模式完成屏幕初始化配置。 */ // PCF8574T 驱动 #define PCF8574T_W_Address 0x40 //4e #define PCF8574T_R_Address 0x4F // IIC 底层 sbit IIC_SDA P3^7; sbit IIC_SCL P3^6; void IIC_Delay6us() { _nop_(); } void IIC_Start() { IIC_SDA 1; IIC_SCL 1; IIC_Delay6us(); IIC_SDA 0; IIC_Delay6us(); IIC_SCL 0; } void IIC_Stop() { IIC_SCL 0; IIC_SDA 0; IIC_Delay6us(); IIC_SCL 1; IIC_Delay6us(); IIC_SDA 1; } void IIC_WriteByte(unsigned char Byte) { unsigned char i; for(i 0; i 8; i) { IIC_SDA Byte (0x80 i); IIC_SCL 1; IIC_Delay6us(); IIC_SCL 0; } } unsigned char IIC_ReceptionAck() { unsigned char BitAck; IIC_SDA 1; IIC_SCL 1; BitAck IIC_SDA; IIC_Delay6us(); IIC_SCL 0; return BitAck; } // PCF8574T 驱动 //#define PCF8574T_W_Address 0x40 //4e //#define PCF8574T_R_Address 0x4F void PCF8574T_Write_Byte(unsigned char dat) { IIC_Start(); IIC_WriteByte(PCF8574T_W_Address); IIC_ReceptionAck(); IIC_WriteByte(dat); IIC_ReceptionAck(); IIC_Stop(); } // LCD1602 四线驱动 void LCDPCF_1ms() //11.0592MHz { unsigned char i, j; _nop_(); i 2; j 199; do { while (--j); } while (--i); } void LCDPCF1602_WriteCmd(unsigned char Cmd) { unsigned char cd; //高四位 cd (Cmd / 16) 4; PCF8574T_Write_Byte(cd); PCF8574T_Write_Byte(cd | 0x04); LCDPCF_1ms(); PCF8574T_Write_Byte(cd); LCDPCF_1ms(); //低四位 cd (Cmd % 16) 4; PCF8574T_Write_Byte(cd); PCF8574T_Write_Byte(cd | 0x04); LCDPCF_1ms(); PCF8574T_Write_Byte(cd); LCDPCF_1ms(); } void LCDPCF1602_WriteDat(unsigned char Dat) { unsigned char da; //高四位 da (Dat / 16) 4; PCF8574T_Write_Byte(da | 0x01); PCF8574T_Write_Byte(da | 0x05); LCDPCF_1ms(); PCF8574T_Write_Byte(da | 0x01); LCDPCF_1ms(); //低四位 da (Dat % 16) 4; PCF8574T_Write_Byte(da | 0x01); PCF8574T_Write_Byte(da | 0x05); LCDPCF_1ms(); PCF8574T_Write_Byte(da | 0x01); LCDPCF_1ms(); } void LCDPCF1602_SetCursor(unsigned char line,unsigned char column) { if(line 1) { LCDPCF1602_WriteCmd(0x80 | (column - 1)); } else { LCDPCF1602_WriteCmd(0x80 | (column - 1) 0x40); } } void LCDPCF1602_Init() { LCDPCF_1ms(); LCDPCF1602_WriteCmd(0x28); //4线2行 LCDPCF_1ms(); LCDPCF1602_WriteCmd(0x0C); //开显示 无光标 LCDPCF1602_WriteCmd(0x06); //地址自增 LCDPCF1602_WriteCmd(0x01); //清屏 LCDPCF_1ms(); } //显示字符串 void LCDPCF1602_ShowStr(unsigned char line,unsigned char column,unsigned char *string) { unsigned char i; LCDPCF1602_SetCursor(line,column); for(i 0; string[i] ! 0; i) { LCDPCF1602_WriteDat(string[i]); } } // 主函数 void main(void) { LCDPCF1602_Init(); LCDPCF1602_ShowStr(1, 1, Hello World); LCDPCF1602_ShowStr(2, 1, PCF8574LCD1602); while(1) { } }现象演示