其中并行模式的液晶的读写数据,命令函数如下:
voidWrite_Cmd(ucharcmd)
{
ucharlcdtemp=0;
LCD_RS_L;
LCD_RW_H;
LCD_DataIn;//数据输入单片机
do//判忙
{
LCD_EN_H;
_NOP();
lcdtemp=LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp&0x80);//判断忙标志等待忙
LCD_DataOut;//数据输出到lcd
LCD_RW_L;
MCU2LCD_Data=cmd;//单片机向lcd输入命令
LCD_EN_H;
_NOP();
LCD_EN_L;
}
voidWrite_Data(uchardat)
{
ucharlcdtemp=0;
LCD_RS_L;
LCD_RW_H;
LCD_DataIn;
do//判忙
{
LCD_EN_H;
_NOP();
lcdtemp=LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp&0x80);//等待忙
LCD_DataOut;
LCD_RS_H;
LCD_RW_L;
MCU2LCD_Data=dat;//单片机向lcd中输入数据
LCD_EN_H;
_NOP();
LCD_EN_L;
}
2),串行模式只用到了两根线WREN于单片机进行通信。这种方式可以大大减少单片机IO口的开销,适用于IO口资源有限的单片机(如msp430g2553)。但是这种方式实现起来较麻烦,数据的传输效率不高。对于一般的文字,简单图形的显示还是可以的。(有可能是因为msp430g2553的处理能力较强,我现在用串行连接方式,显示下面的几幅图画,显示效果很好,看不出有什么数据传输速度慢的问题)。
由于我用的是msp430g2553,所以我一直都是使用串行的控制模式。
//下面重点讲一下串行的时序
//SCLK:串行同步时钟线,每操作一位数据都要有一个SCLK跳变沿,而且在这里是上升沿有效。也即是说,每次SCLK由低电平变为高电平的瞬间,液晶控
//制器将SID上的数据读入或输出。
//SID:串行数据,每一次操作都由三个字节数据组成,第一个字节向控制器发送命令控制字,告诉控制器接下来是什么操作,若为写指令则发送11111000
//(0xf8),若为若为写数据则发送11111010(0xfa),若为读状态则发送11111100(0xfc),若为读数据则发送11111110(0xfe)。
//第二个字节的高4位为发送指令或数据的高4位,第二个字节的低4位补0.
//第三个字节的高4位为发送指令或数据的低4位,第三个字节的低4位补0
//具体的可以观察时序进行理解
![]()
其中数据的传输的函数如下:
//12864串行连接写数据,写命令函数按照手册上的时序进行编程
void wr_lcd(uchar dat_comm,uchar content)//
{//要写的数据
uchar a,i,j;
delay_us(50);
a=content;
LCD_SCLK0; //en=0;
LCD_SID1;//wr=1
for(i=0;i<5;i++) //数据时序*****************8前5个高电平的同步码
{
LCD_SCLK1;
LCD_SCLK0;
}
LCD_SID0;//wr=0写操作
LCD_SCLK1;//en=1来一个时钟
LCD_SCLK0;//en=0
if(dat_comm)
LCD_SID1;//RS=1写数据
else
LCD_SID0;//RS=0写指令
LCD_SCLK1; //来一个时钟
LCD_SCLK0;
LCD_SID0;//控制字的最后一位为0
LCD_SCLK1;//来一个时钟
LCD_SCLK0;
for(j=0;j<2;j++)//************一共2*4次循环写写一字节数据,第一次大循环写高4位,第二次大循环写低4位
{
for(i=0;i<4;i++)
{
if(a&0x80)
LCD_SID1;
else
LCD_SID0;
a=a<1;
LCD_SCLK1;
LCD_SCLK0;
}
LCD_SID0;
for(i=0;i<4;i++)//时钟下面来4个时钟脉冲
{
LCD_SCLK1;
LCD_SCLK0;
}
}
}
voidDraw_TX(ucharYaddr,ucharXaddr,constuchar*dp)
{
ucharj;
uchark=0;
//wr_lcd(comm,0x01);//清屏,只能清除DDRAM
wr_lcd(comm,0x34);//使用扩展指令集,关闭绘图显示打开扩展指令集
for(j=0;j<16;j++)
{
wr_lcd(comm,Yaddr++);//Y地址
wr_lcd(comm,Xaddr);//X地址
wr_lcd(dat,dp[k++]);//写入数据
wr_lcd(dat,dp[k++]);
}
wr_lcd(comm,0x36);//打开绘图显示
//wr_lcd(comm,0x30);//回到基本指令集模式
}
5,向液晶全屏写图像的函数如下:
voidDraw_PM(constuchar*ptr)//整屏显示图形
{
uchari,j,k;
wr_lcd(comm,0x34);//打开扩展指令集
i=0x80;
for(j=0;j32;j++)
{
wr_lcd(comm,i++);
wr_lcd(comm,0x80);
for(k=0;k16;k++)
{
wr_lcd(dat,*ptr++);//先写入32*16个数据
}
}
i=0x80;
for(j=0;j32;j++)
{
wr_lcd(comm,i++);
wr_lcd(comm,0x88);
for(k=0;k16;k++)
{
wr_lcd(dat,*ptr++);//再写入32*16个数据
}
}
wr_lcd(comm,0x36);//打开绘图显示
wr_lcd(comm,0x30);//回到基本指令集
}
6,下面我就贴上一个对液晶功能测试的函数,其中用到了液晶的很多功能,可以有实现现象观察得到,注释的也较详细,代码如下:
#include"msp430g2553.h"
#include"ser_12864.h"
voidmain(void)
{
uinti;
ucharlaba[]=//16*16大小图形数据
{0x00,0x00,0x00,0xC0,0x01,0x48,0x02,0x44,0x04,0x52,0xF8,0x49,0x88,0x49,0x88,0x49,
0x88,0x49,0x88,0x49,0xF8,0x49,0x04,0x52,0x02,0x44,0x01,0x48,0x00,0xC0,0x00,0x00};
WDTCTL=WDTPW+WDTHOLD;//关狗
BCSCTL1=CALBC1_12MHZ;//设定cpu时钟DCO频率为12MHz
DCOCTL=CALDCO_12MHZ;
P2DIR|=BIT5+BIT4;//液晶的两条线
init_lcd();//初始化液晶
//下面是显示液晶字符表中的字符
wr_lcd(comm,0x80);//写第一行的显示地址写命令0x80
for(i=0;i16;i++)//每一行可以显示16个字符