学习单片机,总要驱动LCD屏幕,但是对于没有引脚定义的LCD屏幕该如何应对?
本人研究不深,只谈体会。
比如下面这款屏幕
一、第一种方法
百度大法查引脚定义。查询条件可以是FPC上的丝印,或者是屏幕的尺寸,引脚数,如2.2寸,19pin,屏幕,这些信息。
有一定概率可以查到一模一样的屏幕,并且有引脚定义。之前通过这个方法查询到过2个屏幕,真是运气爆棚了。
但是,大部分情况一无所获。
二、第二种方法
1、准备工作
在开始工作以前先准备一些工具:
1、带英寸刻度的尺子
2、一个放大镜,不用太高级,当然放大倍数越高越好
3、还需要一个手机
2、开始
第一种方法不行,就只能自力更生,自己来判断。
LCD的显示IC本身是一种芯片,和所有IC一样只要和IC手册对应上,就可以判读引脚定义。但显示IC实在是太小了,必须要放大。有显微镜最好,没有用前面准备的工具一样可以做到。
1、首先用尺寸测量以下屏幕对角线
上面的屏幕测量了一下,大概2.2寸。百度一下,2.2寸大概率是ST7775,ili9225这些。
2、用手机微距功能叠加加放大镜拍下屏幕和引脚情况
电脑上放大一些屏幕的白点大概是220*176分辨率,ST7775,ili9225恰好是这个分辨率。
已经很清楚了,可以用电脑的看图工具放大观察了。
3、找出手册对引脚定义
然后找来ST7775手册,找的PAD ARRANGEMENT 的一页,有引脚定义,截了一段如下:
这个屏是19pin的,大概率是8位并口屏,并口屏要用到DB17-DB10做为数据传输总线,所以截取了上面的部分。
两张图对应上去,可得:
还可以确定IM3-IM0:[0011],8080,8bit
4、跟踪线路确认引出定义
1-BL-,2-BL+,3-GND,4-VDD,5-VDD,6-/CS ,7-/RESET,8-/RS ,9-/WR ,10-/RD,11-18-DB7-DB0(高8位),19-GND
5、GND和VDD是怎么确认的
GND和覆铜部分连接。VDD的线路比数据线路粗一些。
三、接好线找来例程跑一下,如果运行OK,就基本没问题了
略
四、进一步明确,就查Driver Code ID吧
ST775的寄存器命令:
可以看到如果查询00h寄存器,返回0x7775就可以得到最准确的确认。
void lcd_write_comm_word(uint16_t cmd);
//
void SetLcdDBIn(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.GPIO_Pin = LCD_DB8|LCD_DB9|LCD_DB10|LCD_DB11|LCD_DB12|LCD_DB13|LCD_DB14|LCD_DB15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//
void SetLcdDBOut(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.GPIO_Pin = LCD_DB8|LCD_DB9|LCD_DB10|LCD_DB11|LCD_DB12|LCD_DB13|LCD_DB14|LCD_DB15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @prief LCD_ReadData
*/
uint16_t LCD_ReadData(void)
{
uint16_t dat=0x0000;
SetLcdDBIn();
LCD_CS_CLR;
LCD_RS_SET;
LCD_WR_SET;
LCD_RD_CLR;
Delay_Us(20);
//dat=LCD_DB_IN;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB8)<<0)&0x01;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB9)<<1)&0x02;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB10)<<2)&0x04;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB11)<<3)&0x08;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB12)<<4)&0x10;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB13)<<5)&0x20;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB14)<<6)&0x40;
dat|=(GPIO_ReadInputDataBit(GPIOB,LCD_DB15)<<7)&0x80;
LCD_RD_SET;
LCD_CS_SET;
SetLcdDBOut();
return dat;
}
//查Driver code ID
uint16_t ReadID(void)
{
uint16_t id;
lcd_write_comm_word(0x0000);
LCD_ReadData();
LCD_ReadData();
id=LCD_ReadData();
id=id<<8;
id|=LCD_ReadData();
return id;
}
//查其他寄存器
uint16_t ReadRegister(unsigned char reg)
{
uint16_t id;
lcd_write_comm_word(reg);
LCD_ReadData();
LCD_ReadData();
id=LCD_ReadData();
id=id<<8;
id|=LCD_ReadData();
return id;
}
void gpio_lcd_write_data(unsigned char *data, size_t size) {
LCD_RD_SET;
for (int i=0;i<size;i++) {
GPIO_WriteBit(GPIOB, LCD_DB8,data[i]&0x01);
GPIO_WriteBit(GPIOB, LCD_DB9,data[i]&0x02);
GPIO_WriteBit(GPIOB, LCD_DB10,data[i]&0x04);
GPIO_WriteBit(GPIOB, LCD_DB11,data[i]&0x08);
GPIO_WriteBit(GPIOB, LCD_DB12,data[i]&0x10);
GPIO_WriteBit(GPIOB, LCD_DB13,data[i]&0x20);
GPIO_WriteBit(GPIOB, LCD_DB14,data[i]&0x40);
GPIO_WriteBit(GPIOB, LCD_DB15,data[i]&0x80);
LCD_WR_CLR;
LCD_WR_SET;
}
}
void lcd_write_comm_word(uint16_t cmd)
{
unsigned char c[2];
c[0] = (cmd >> 8) & 0xFF;
c[1] = cmd & 0xFF;
LCD_CS_CLR;
LCD_RS_CLR;
gpio_lcd_write_data(c, 2);
LCD_CS_SET;
}
ReadID()返回0x7775就OK了。
五、其他
1、为什么了不从ili9225入手?
因为ili9225需要好多外围电容,而这个FPC上没有。
2、分辨率和显示IC(以ST为例)对应关系
ST | 其他 | |
128*128 | ST7735 | |
220*176 | ST7775 | |
320*240 | ST7789 | |
128*64 | ST7567 |