关于STM32板上的12864液晶
Nov 27, 2013
Technology
板子是09年入手的,但是一直没时间好好玩,最近端起来觉得有必要好好研究一番。为了以后翻阅方便,全中文记下来。
###12864
通常所说的12864LCD显示块是所说的点阵液晶显示模块,就是由128X64个液晶显示点组成的一个128列X64行的阵列,所以也就叫成了12864。每个显示点都对应着有一位二进制数,0表示灭,1表示亮。存储这些点阵信息的RAM被称为显示数据存储器。如果要显示某个图形或汉字就是将相应的点阵信息写入到对应的存储单元中。图形或汉字的点阵信息是由自己设计,这时候问题的关键是显示点在液晶屏上的位置与其在存储器中的地址之间的关系。
显示点在64X64液晶屏上的位置由列号(line,0~63)与行号(line,0~63)确定。512X8 bits RAM中某个存储单元的地址由页地址(Xpage,0~7)和列地址(Yaddress,0~63)确定。每个存储单元存储8个液晶点的显示信息。也就是说,一个页的大小是8. 运算关系则是64x64=(64x8)x8=512x8.
由于多数液晶显示模块的驱动电路是由一片行驱动器和两片列驱动器构成,所以12864液晶屏实际上是由左右两块独立的64X64液晶屏拼接而成,每半屏有一个512X8 bits显示数据RAM。左右半屏驱动电路及存储器分别由片选信号CS1和CS2选择。(少数厂商为了简化用户设计,在模块中增加译码电路,使得128X64液晶屏就是一个整屏,只需一个片选信号。)
如如果点亮12864的屏中(20,30)位置上的液晶点,因列地址30小于64,该点在左半屏第29列,所以CS1有效;行地址20除以8取整得2,取余得4,该点在RAM中页地址为2,在字节中的序号为4;所以将二进制数据00010000(也可能是00001000,高低顺序取决于制造商)写入Xpage=2,Yaddress=29的存储单元中即点亮(20,30)上的液晶点。
这是为了为了使液晶点位置信息与存储地址的对应关系更直观关,将64X64液晶屏从上至下8等分为8个显示块,每块包括8行X64列个点阵。每列中的8行点阵信息构成一个8bits二进制数,存储在一个存储单元中。(需要注意:二进制的高低有效位顺序与行号对应关系因不同商家而不同)存放一个显示块的RAM区称为存储页。即64X64液晶屏的点阵信息存储在8个存储页中,每页64个字节,每个字节存储一列(8行)点阵信息。因此存储单元地址包括列地址(Yaddress,0~63)和页地址(Xpage,0~7)。
以上就是对于12864点阵液晶显示器的原理介绍。
在DX32开发板上的液晶是怎么一回事呢?它的封装图如下:
Datasheet有72页,乱七八糟的会讲一大堆。但是事实上我们只需要关注和软件有关的方面,拿一个很简单的开启/关闭LCD的例子来说,DataSheet里有这样的表格:
Command | A0 /RD /WR | D7 D6 D5 D4 D3 D2 D1 D0 | Function |
---|---|---|---|
Display On/OFF | 0 1 0 | 1 0 1 0 1 1 1 1 | LCD Display ON |
Display On/OFF | 0 1 0 | 1 0 1 0 1 1 1 0 | LCD Display OFF |
那么会有对应的代码:
/**************************************************************
**函数名:LcdOnOff
**功能:开关LCD
***************************************************************/
void LcdOnOff(u8 onoff)
{
if(onoff>0)
LcdCmd(0xaf); //开显示
else
LcdCmd(0xae); //关显示
}
0xaf的二进制的值是1010 1111, 而0xae的值则是1010 1110, 这点在手册中容易引起混淆,因为它操蛋的把前面的一系列值都省略了,表格里的才是完整的应该发送的命令。
再拿一个例子来说,
/**************************************************************
**函数名:LcdInit
**功能:初始化LCD,初始化后需要用LcdCmd(0xaf)命令打开显示
***************************************************************/
const u8 LCD_Tab[] = { /*0x26改0x27可增加对比度*/
0xa2,0xa0,0xc8,0xf8,0x00,0x26,0x2f,0x81,0x05,0xa4,0xa6,0xac,0x00,0xee,0x40
};
void LcdInit(void)
{
u16 i;
RSTLCDS_L;
for(i=0;i<65530;i++);
RSTLCDS_H;
/* Why we have to write 15 times for the LCD_Tab? */
for(i=0;i<15;i++)
LcdCmd(LCD_Tab[i]);
LcdCmd(0xaf); //开显示
}
在初始化LCD的时候我们需要依次写入命令,这里我们把命令做成一个数组,就是LCD_Tab数组, 那么命令的格式如下:
0xa2 LCD bits set, 0 means normal displaying
0xa0 ADC Select. Set the display RAM address SEG output corresponding, 0 means normal.
0xc8 Common Output Set, means reverse direction.
0xf8 Booster ratio.
所有这些在DataSheet中均有详细说明。
总之,对于12864,我们只要把它看成是一个“黑盒子”,输入对应的值,盒子上就能显示出怎样的值,如此就可以得到我们要的结果。