本帖最后由 13395410441 于 2016-2-4 10:32 编辑
19264+12864
几种常见的12864图形点阵模块
12864点阵液晶模块分为带汉字库和不带汉字库两大类,目前带汉字库的通常是ST7920驱动,它可以工作在汉字字符方式和图形点阵方式,很多制作都用它,如果需要显示较多汉字,用它最为方便。
在显示汉字数量很少的场合,我们可以使用更加廉价的、不带字库的点阵液晶模块,这正是本文重点介绍的。它们的控制电路有KS0108和ST7565两种:KS0108很简单,一共只有7条指令,可是它没有串行接口;ST7565有20多条指令(最常用的也就几条),有串行接口,可选串行或并行工作。KS0108和ST7565的指令和上述带字库的ST7920区别较大,所以初学者买液晶时一定要搞清楚是哪种驱动电路。即使同样的驱动电路,不同厂家或者不同型号的产品,具体细节仍可能不同。例如有的片选信号是高电平有效,有的却是低电平有效,有的把显示区分为左右两半分别选取,有的却不加区分。所以使用前要仔细看厂家说明,如果没有,就要看液晶模块背面给出的具体型号,根据这个型号去查找使用手册。
我使用的是ST7565P。JLX12864G-102-ST7565R中文说明书这个文档说的很详细,你可以选择串行、并行,可以选择6800时序、8080时序。不同的选择引脚的接法和名称会有不同奥。
1、引脚定义:
P/S(PIN33) 高是并行,低是串行。
C86(PIN32)高是6800,低是8080时序。
我选择的是8080时序、并行通信,所以我的引脚名称和功能如下:
CS(PIN3):低电平片选芯片
RES(PIN4):低电平复位,回到高电平液晶开始工作
RS(PIN5):高电平时选择数据寄存器,低电平选择指令寄存器
/WR(PIN6):高电平禁止写,低电平写数据
/RD(PIN7):高电平禁止读,低电平读数据
这样就很明了了。
2、指令简介:二十几个指令也就是用12种指令:1.清除,2.返回,3.输入方式设置,4.显示开关,5.控制,移位,6.功能设置,7.CGRAM地址设置,8.DDRAM地址设置,9.读忙标志,10.写数据到CG/DDRAM,11.读数据由CG/DDRAM等。 其中指令20可以不设,指令17液晶模块通过外置电阻设置,此指令失效。
1、开显示:0XAF 2、设置显示存储器的显示初始行:(0x40)0x40 - 0x7f(第一行到最后一行) 3、设置页地址Y轴,每8行为1页,64行为8页,1011 0000为第一页。(0XB0 - 0XB7 ),换句话说,一页就是一个八位的字节,一共8个字节。 4、128列的对应列(X轴)的高4位、低四位,第一列是0000 0001(正常的话 即8指令设为a0的话),8指令设为a1则为0000 0004,最大是1000 0000/1000 0004设完初值,他会自动增加的。2^7 = 128。3 4指令就涵盖了128*64的全部坐标 所以输入0x0001 0000 0x0000 0001(两个数字高四位是不变的) 8、显示列地址增减(ADC select):常规0xa0,从右到左;0xa1。 9、显示正显/反显 (Display normal/reverse):常规0xa7(白字黑背景),反显0xa6(黑字白背景)。 10、显示全部点阵 (Display all points):常规0xa4,全显0xa5。 11、LCD 偏压比设置 (LCD bias set):1/9 0xa2 ,1/7 0xa3。 14、软件复位:0xe2 15、行扫描顺序选择:普通0xc0,上下方向反向扫描0xc8。 16、选择内部电压供应操作模式:(0x2f)0x24-0x2f。 17、选择内部电阻比例(Rb/Ra),本液晶模块通过外置电阻设置,此指令失效:(0x25)0x20-0x27。 18、设置内部电阻微调,以设置液晶电压,此两个指令需紧接着使用: 1、电压模式:0x81 2、电压值:(0x23)0x00 - 0x3f 19多的 20(代码中的19):选择升压倍数: 00:2倍,3倍,4倍 01:5倍 11:6倍。本模块外部已设置升压倍数为4倍,不必使用此指令 1、0xf8 2、0x01 五倍,起始和四倍差不多,可以不使用这个指令
---------------------------------华丽的分割线----------------------------------- 代码操作很简单,就是先选择好命令配置LCD,然后自己到汉字取模软件弄几个字库存在一个头文件中,然后在代码中指定坐标写入数据就可以。下面是摘抄的代码,有的地方可能不准确,但是思路很清晰了,自己写入自己的LCD12864中慢慢调试到自己喜欢的样子就可以了 3、指令代码: 写命令 void LcdSt7565_WriteCmd(cmd) { LCD12864_CS = 0; //打开片选 LCD12864_RS = 0; //选择命令 LCD12864_RD = 1; //禁止读 LCD12864_RW = 0; //写使能 _nop_(); _nop_();
DATA_PORT = cmd; //写入命令 _nop_(); _nop_();
LCD12864_RW = 1; //禁止写,执行命令 } 写数据 void LcdSt7565_WriteData(dat) { LCD12864_CS = 0; //片选 LCD12864_RS = 1; //选择数据 LCD12864_RD = 1; //禁止读 LCD12864_RW = 0; //选择写 _nop_(); _nop_();
DATA_PORT = dat; //写入数据 _nop_(); _nop_();
LCD12864_RW = 1; //禁止写,执行数据 }
初始化 void Lcd12864_Init() { uchar i; LCD12864_RSET = 0; for (i=0; i<100; i++); LCD12864_CS = 0; LCD12864_RSET = 1;
LcdSt7565_WriteCmd(0xE2); //reset复位重启 for (i=0; i<100; i++);//延时
LcdSt7565_WriteCmd(0xA1); //ADC select segment direction 左右反向 LcdSt7565_WriteCmd(0xC8); //Common direction 上下反向
LcdSt7565_WriteCmd(0xA6); //reverse display 反显-白字黑背景
LcdSt7565_WriteCmd(0xA4); //normal display 像素正常显示 LcdSt7565_WriteCmd(0xA2); //bias set 1/9 偏压
LcdSt7565_WriteCmd(0xF8); //Boost ratio set 增压指令 LcdSt7565_WriteCmd(0x01); //x5 5倍增压 LcdSt7565_WriteCmd(0x81); //V0 a set 液晶电压调节指令 LcdSt7565_WriteCmd(0x23);//调节电压改变对比度
LcdSt7565_WriteCmd(0x25); //Ra/Rb set 使用外部电阻则此命令失效
LcdSt7565_WriteCmd(0x2F); //内部供应电压全开 for (i=0; i<100; i++);
LcdSt7565_WriteCmd(0x40); //start line 开始位置是第一行首部
LcdSt7565_WriteCmd(0xAF); // display on 开显示 for (i=0; i<100; i++); }
清屏用到3 4两个指令,
void Lcd12864_ClearScreen(void)
{
uchar i, j;
for(i=0; i<8; i++)//第三个命令。64行,8*8位,1字节就是8位,所以循环8个字节从0XB0 - 0XB7
{
//-//第三个命令。64行,8*8位,1字节就是8位,所以循环8个字节从0XB0 - 0XB7-//
LcdSt7565_WriteCmd(0xB0+i);
//--这是第四个命令,取决于第八个命令。命令8是0XA0 则这里写 0X01 0X00,命令8是0XA1 则这里写 0X01 0X04.意思是设置X轴起始位置,默认写一个字节自动增加的--//
LcdSt7565_WriteCmd(0x10);
LcdSt7565_WriteCmd(0x04);
//--上面说了X轴128位,所以每位写0X00,如果命令--//
for(j=0; j<128; j++)
{
LcdSt7565_WriteData(0x00); //命令9设为0XA7时写0X00,命令9设为0XA6时写0XFF
}
}
}
写数据:参数,X坐标、Y坐标、字符串
uchar Lcd12864_Write16CnCHAR(uchar x, uchar y, uchar *cn)
{
uchar j, x1, x2, wordNum;
//--Y轴不能大于7,因为只有8个字节,0-7--//
if(y > 7)
{
return 0;
}
//--X不能大于128,因为只有0 - 128--//
if(x > 128)
{
return 0;
}
y += 0xB0; //根据传进来的y坐标值,转换成可用的Y坐标,等待赋值
//--设置Y坐标--//
LcdSt7565_WriteCmd(y);
while ( *cn != '\0') //判断字符串结尾,C字符串以‘\0结尾’
{
//--设置Y坐标--//
LcdSt7565_WriteCmd(y);
x1 = (x >> 4) & 0x0F; //获取X高四位
x2 = x & 0x0F; //获取X低四位
//--设置X坐标--//
LcdSt7565_WriteCmd(0x10 + x1);
LcdSt7565_WriteCmd(0x04 + x2);
for (wordNum=0; wordNum<50; wordNum++)
{
//--查询要写的字在字库的位置,自然,这是自己在一个.h中自己写的字库,一个包含多个汉字编码的数组--//
if ((CN16CHAR[wordNum].Index[0] == *cn)
&&(CN16CHAR[wordNum].Index[1] == *(cn+1)))
{
for (j=0; j<32; j++) //写一个字
{
if (j == 16) //16*16需要两个Y轴,当大于等于16时切换坐标
{
//--Y轴加1--//
LcdSt7565_WriteCmd(y + 1);
//--设置X轴--//
LcdSt7565_WriteCmd(0x10 + x1);
LcdSt7565_WriteCmd(0x04 + x2);
}
LcdSt7565_WriteData(CN16CHAR[wordNum].Msk[j]);
}
x += 16;
}//if查到字结束
} //for查字结束
cn += 2;
} //while结束
return 1;
}
void main()
{
uchar i = 128;
Lcd12864_Init();
Lcd12864_ClearScreen();
while (1)
{
for (i=0; i<8; i += 2)
{
Lcd12864_ClearScreen();
Lcd12864_Write16CnCHAR(0, i, "大家学习要细心啊");
Delay10ms(100);
}
}
}
|