介绍
网上寻遍了资料发现驱动LCD1602液晶屏的程序几乎都是4线或8线数据线。基本思路都是直接操作I/O,但是缺点是接线太多,十分麻烦。PCF8574和PCF8574AT这两种芯片都是IIC芯片,可以将并行的八根数据线转换只用两根数据线进行控制,减少了I/O口的使用,提高所使用微处理器的控制能力。
故此记录用PCF8574AT代替直接操作I/O驱动LCD1602。以下内容是编写程序时发现并修正的一些错误和使用该款芯片时需要注意的细节,希望能够抛砖引玉。如有错误还请指正!
PCF8574AT
某宝上有一款LCD1602驱动板,能够极大程度节约引脚资源。用IIC协议驱动屏幕。
选址
其中值得注意的点,芯片名称有所区别,根据实际芯片找到对应的地址才能寻址成功。A2 A1 A0是硬件选址,默认不接均为1。最低bit为读写位。
以PCF8574AT为例,查找其地址。
最后芯片写地址是
0x7e
芯片接线图
LCD1602
数据手册
提取:mp91
显示问题
我使用野火指南者板子stm32f103vet6,程序烧写后需要复位才能正常显示lcd1602内容。这个问题可以在lcd初始化命令补一句。
LCD_WriteCMD(0x02);
//必须要,如果没有了第一次上电会没内容
void LCD_Init(void)
{
i2c_CfgGpio(); /* 配置GPIO */
LCD_WriteCMD(0x02);/*必须要,如果没有了第一次上电会没内容*/
LCD_WriteCMD(0x28);/* 0x28 4线操作模式 0x38 8线模式 */
/* 0000 1DCB D开关显示 C开关光标 B开关光标闪烁 */
LCD_WriteCMD(0x0c);/* 开显示,关光标 */
LCD_WriteCMD(0x06);/* 文字不动,地址自动加1 */
LCD_WriteCMD(0x01);/* 清屏 */
SysTick_Delay_Ms( 5);
}
上述初始化之后,完美解决了上电复位后才显示文本的问题。
乱码问题
快速复位lcd1602会出现乱码是因为没有读忙函数
。
读忙函数
51实现:
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
STM32实现:
void LCD1602_Wait_Ready(void)
{
uint8_t sta;
LCD_data |= 0xf0; //数据高四位置1
i2c_WriteByte(LCD_data);
LCD_data &=~(1<<(1-1));//RS=0; // 0 0 0 0 0 0 0 0
LCD_data |=(1<<(2-1));//RW=1; // D7 D6 D5 D4 E RW RS
i2c_WriteByte(LCD_data);
do
{
LCD_data |= 1<<2; // 0000(数据)0000(控制位)
// 0xxx 0100 -------> E=1
i2c_WriteByte(LCD_data);
SysTick_Delay_Ms(5); //延时
sta = i2c_R_Byte(); /* 读取状态字 */
LCD_data ^= 1<<2; //异或运算(还原)
// 0xxx 0000 ----------> E=0
//or LCD_data &=~(1<<2)
//I2C_WriteByte(LCD_data);//1→0 执行指令
i2c_WriteByte(LCD_data);
}while(sta &0x80); /* 状态字的最高位 1忙,0空闲 */
}