PSOC3之LCD12864液晶串行驱动
本帖最后由 kk5290122 于 2013-1-14 09:22 编辑昨天刚与大家分享了如何使用PSOC3并行驱动LCD12864液晶,应各位热心坛友的支持,今天再和大家分享一下如何使用PSOC3串行驱动LCD12864液晶。
我想大家对串行和并行应该都有一定的了解,并行就是将每一个数据字节的各位用多条数据线同时进行传送,一次可以发送多位数据,每一位数据都需要一条传输线,显然此时需要的数据传输线也就会相应增加许多;而串行则是将数据字节按一位一位的形式在一条传输线上逐个传送,此时只需要一条数据线,外加若干控制线就可以完成信号的传输。由于串行方式一次只能传送一位数据,所以传输速率在相同的条件下明显会比并行传输慢许多,但这样所带来的好处就是传输线的大量减少,尤其是在长距离传输时,可以大幅降低成本,这对用户来说是一个相当大的优势;相对于串行方式,并行方式则传输速度较快,控制也比串行方式简单,但由此而付出的代价也正是传输线的增加所带来的成本的大幅增加。总之串行方式和并行方式各有利弊,我们在使用时要根据自身的实际需要来择优选取,在近距离和对传输速率要求比较高的地方我们一般选择并行方式,而在远距离和对传输速率要求不高的地方我们则通常会选择串行方式。
既然我们上面提到了串行和并行的不同之处,下面我们就针对我们的具体工程来说一下用PSOC3来实现这两种方式的相同和不同之处。首先要声明的一点是,在上次并行驱动的介绍时我们使用了控制寄存器,为了避免与上次的重复以及体现使用控制寄存器与不使用控制寄存器的区别我们这里就只使用Creator模块组件中的引脚组件来建立我们的工程,具体的工程建立步骤有需要的还是请大家参考:
jlj8315292 的【玩转PSoC3】之TFT液晶篇 https://www.cirmall.com/bbs/thread-3063-1-1.html。
我们这里主要是介绍用PSOC3来实现这两种方式的不同之处,打开这两种方式在Creator中所建立的原理图,如下图1和2所示。我们明显可以看到串行方式比并行方式少了右边的8条数据线(Pin_DATA引脚),而左边的4条线则是二者为了实现各自的信号控制所需要的控制线,其中在并行方式原理图中Pin_RS、Pin_RW和Pin_EN分别是LCD12864液晶的数据/命令选择端、读写选择端和使能端;而在串行方式原理图中Pin_CS、Pin_SID和Pin_SCLK则分别是LCD12864液晶的串行片选端、串行数据端和串行同步时钟端,而Pin_PSB则是二者共有的串并行选择端。分别根据液晶的串行和并行读写操作时序来操作不同的控制线就可以实现对液晶的串行和并行操作。当然由于串行和并行所需要的引脚数不同,在引脚配置里面也就会有相应差别,具体差别大家可以下载工程文件查看。
图1
图2
下面我们就来具体介绍一下LCD12864液晶的串行读写操作时序,液晶的串行读/写操作时序如下图3所示:
图3
其中:(1) CS:液晶的片选信号线,每次在进行数据操作时都必须将CS端拉高。(2) SCLK:串行同步时钟线,每操作一位数据都要有一个SCLK跳变沿,而且在这里是上升沿有效。也就是说,每次SCLK由低电平变为高电平的瞬间,液晶控制器将SID上的数据读入或输出。(3) SID:串行数据,每一次操作都由三个字节数据组成,第一字节向控制器发送命令控制字,告诉控制器接下来是什么操作,若为写指令则发送11111000,若为写数据则发送11111010。第二字节的高4位发送指令或数据的高4位,第二字节的低4位补0。第三字节的高4位发送指令或数据的低4位,第三字节的低4位同样补0。有了上面的时序图,以及对相应控制线的操作说明,我们就可以像并行操作那样通过读写相应的引脚来编写我们的底层驱动函数了,这也正是并行驱动与串行驱动在软件方面最大的区别了。我们只需把并行驱动中对液晶进行写指令和写数据的底层驱动函数按照串行操作的时序分别对不同的控制引脚进行读写操作,其他的例如主函数,只要保证这两个底层驱动函数的函数名一样,无需任何改动就可以实现对液晶的串行驱动。下面是这两个底层驱动函数的具体代码,我这里使用的函数与并行时有所不同,大家可以参看注释,在此就不做具体说明了。/*串行写指令到LCD*/
void LCD_Serial_Send_Command(uchar serial_cmd)
{
uchar i,in_data; //
while(LCD_Read_Busy()); //
in_data=0xf8; //发送写指令控制命令
Pin_CS_Write(1); //片选信号拉高,有效
for(i=0;i<8;i++) //发送第1个字节,将8位控制命令由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
in_data=serial_cmd;
in_data&=0xf0; //取要发送指令命令的高4位
for(i=0;i<8;i++) //发送第2个字节,将8位指令数据的高4位由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
in_data=serial_cmd; //
in_data<<=4; //左移4位,取要发送指令命令的低4位
for(i=0;i<8;i++) //发送第3个字节,将8位指令数据的低4位由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
Pin_CS_Write(0); //完成指令发送,片选拉低
CyDelay(10); //延时10ms
}
/*串行写数据到LCD*/
void LCD_Serial_Send_Data(uchar serial_data)
{
uchar i,in_data; //
while(LCD_Read_Busy()); //
in_data=0xfa; //发送写数据控制命令
Pin_CS_Write(1); //片选信号拉高,有效
for(i=0;i<8;i++) //发送第1个字节,将8位控制命令由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
in_data=serial_data;
in_data&=0xf0; //取要发送数据命令的高4位
for(i=0;i<8;i++) //发送第2个字节,将8位数据的高4位由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
in_data=serial_data; //
in_data<<=4; //左移4位,取要发送数据命令的低4位
for(i=0;i<8;i++) //发送第3个字节,将8位数据的低4位由高到低1位1位的送到串行数据端
{
Pin_SCLK_Write(0);
Pin_SID_Write((bit)(in_data&0x80));//最高位送数据端
Pin_SCLK_Write(1); //产生时钟上升沿,数据有效
in_data=in_data<<1; //数据左移1位
}
Pin_CS_Write(0); //完成数据发送,片选拉低
CyDelay(10); //延时10ms
}
到此PSOC3对LCD12864液晶的串行驱动也基本分享完毕,希望可以对大家的学习有所帮助。此外在学习串行驱动的过程中我还解决了一个上次使用控制寄存器组件的并行驱动中所遇到的一个问题:液晶读忙函数的实现。由于上次用到了控制寄存器组件,没能实现,而这次只用了引脚组件,只要在并行驱动中把引脚组件的配置属性设为双向的,就可以实现液晶的读忙函数。而且在串行驱动中也实现了读忙函数,大家不妨看一下串行驱动中读忙函数的实现技巧,想必会有所收获的,下面是几张实现的实际效果图,大家明显可以看出串行驱动比并行驱动少用了很多线在,在连线较多的情况下一般都可以使用串行驱动。
lz给力啊,扫盲贴~~·谢谢了·· 楼主非常给力!顶~~~ tao475824827 发表于 2013-3-29 21:06 static/image/common/back.gif
刚才在书上看到一段话,泪奔了
“为了保证代码容易移植到PSoC5上,可以使用‘CYBIT’关键字替换‘bit’关 ...
hehe ^收获挺多额…… 本帖最后由 tao475824827 于 2013-3-29 21:08 编辑
kk5290122 发表于 2013-3-24 12:48 https://www.cirmall.com/bbs/static/image/common/back.gif
一个51内核,一个M3内核,应该不同吧,
刚才在书上看到一段话,泪奔了
“为了保证代码容易移植到PSoC5上,可以使用‘CYBIT’关键字替换‘bit’关键字。”
崩溃了,把这个一改就好了
我之前还改了那么久 kk5290122 发表于 2013-3-29 09:01 static/image/common/back.gif
我也好久没有弄了……
感觉想显示汉字,只能通过绘图的方法了。。
还好我要显示的汉字很固定。。。
不过一直用的你的驱动,这下要画图可能还得加东西。。 tao475824827 发表于 2013-3-28 21:14 static/image/common/back.gif
是啊。。。我实在想不懂为什么汉字显示就是乱码。。你有想法么?
我也好久没有弄了…… kk5290122 发表于 2013-3-28 19:02 static/image/common/back.gif
呵呵……时序图是基本哦……
感觉在PSoC Creator里面,对汉字的解码不对啊
比如我定义的数组
但实际table4[]在内存里是:
一个汉字占掉了3个字符位置。。这明显解码的不对啊。。
应该是两个才对啊
kk5290122 发表于 2013-3-28 19:02 static/image/common/back.gif
呵呵……时序图是基本哦……
是啊。。。我实在想不懂为什么汉字显示就是乱码。。你有想法么? tao475824827 发表于 2013-3-28 17:09 static/image/common/back.gif
懂了。。。没看时序图就上来说话了。。。囧
呵呵……时序图是基本哦…… 懂了。。。没看时序图就上来说话了。。。囧