本帖最后由 kk5290122 于 2013-1-12 23:19 编辑
不知不觉已经有一个多月没有与大家一起分享我在学习过程中遇到的一些问题以及一些技术心得了,寒假临近,很快就要回家过年了,回家前再不与大家分享写我近来的一些学习心得,就真的有点对不住xinxin,对不住爱板了。今天我要与大家分享的是:如何使用PSOC3来驱动LCD12864液晶? 之前我有与大家分享过一些用PSOC3来驱动LCD1602液晶的技术心得,对液晶有所了解的朋友都知道LCD12864液晶和LCD1602液晶在本质上没有多大区别,不论是二者的读写操作时序,还是二者与MCU的接口以及驱动函数都大同小异,区别主要是二者所支持显示的内容以及可以容纳显示字符的个数有所不同。LCD1602只支持显示英文字符和数字,而LCD12864则不仅可以显示英文、数字,还可以显示汉字和图形,而且所能够容纳显示字符的个数也比LCD1602多很多,所以在一些需要显示的字符个数比较多或者需要显示汉字和图形的地方则只能使用LCD12864液。学过51单片机的朋友都知道用51单片机或者其他一些MCU来驱动这两种液晶,基本上也是大同小异,最基本的底层驱动函数以及与MCU的外部接口都一样,无非就是LCD12864相对于LCD1602来说增加了一些可以支持显示汉字或图形的驱动函数,或许有的朋友会说既然都一样,那还有什么好说的呢? 我今天既然又专门把用PSOC3来驱动LCD12864液晶单独拿来与大家分享,就一定会有与用PSOC3来驱动LCD1602液晶的不同之处,在PSOC3的开发环境Creator中有专门用来驱动字符液晶LCD1602的模块组件,我们可以直接用来驱动LCD1602字符液晶,而不需要自己再编写驱动函数,而且在原理图中不需要任何连接就可以实现LCD1602的显示,即模块组件实现了芯片内部与外部液晶的软件和硬件接口。而LCD12864液晶在Creator中则没有相应的驱动模块组件,要想使用PSOC3来驱动LCD12864,则必须要开发者自己编写相应的驱动函数以及在原理图中建立内部芯片与外部液晶的接口,即人为建立PSOC3芯片内部与外部液晶的软件和硬件接口。 对于硬件接口即PSOC3芯片内部与外部液晶的接口来说,我们都知道如果使用51单片机的话,由于51单片机的IO端口本身就具有直接与外部交换数据的功能,所以只需要把51单片机的IO控制引脚和相应的液晶控制引脚连接起来,然后根据液晶的读写操作时序,分别控制不同的IO引脚即可实现对液晶的读写;而PSOC3则不同于51单片机,PSOC3所能够实现的每一部分功能都是需要用户自己配置的,这也就致使我们无法像51单片机那样只要把51单片机相应的IO引脚和外部引脚连接起来就能够实现对外部器件的操作,它要求用户必须人为建立芯片内部与外设的映射,那我们又该怎样实现这种映射关系呢?这也正是我所要与大家分享的关键之所在! 对于软件接口即底层驱动函数来说,用PSOC3和用51单片机的操作时序是一样的,只是完成相应时序操作所使用的方式不同,大家都知道使用51单片机的话只要直接读写相应的IO引脚即可,而对于PSOC3来说要实现对相应IO口的操作,则需要通过软件控制能够建立芯片内部与外部接口的器件来实现。 要建立芯片内部与外设的映射,Creator模块组件里的控制寄存器就起到了重要作用,当然我们也可以不经过控制寄存器,而通过直接控制引脚(Pin)组件来实现对液晶的控制操作,此时原理图中只需要在把控制寄存器组件删除,并且把引脚(Pin)组件配置中的HW Connection去除,同时把液晶的底层驱动函数中把以LCD_开头的控制寄存器读写函数改为以Pin_开头的引脚读写函数即可。我们这里重点是要介绍如何通过控制寄存器组件来实现对液晶的控制操作。打开控制寄存器的数据手册,我们可以看到有如下图1所示描述:
控制寄存器介绍
图1
即控制寄存器有允许固件输出数字信号的功能,当固件需要与数字系统交互时使用控制寄存器,而且从图1中可以看出每个控制寄存器可以有最多8个输出,刚好可以实现对8位并行数据的整体操作。 此外我们还可以看到对控制寄存器的应用程序编程接口有如下图2所示描述:
控制寄存器API函数
图2
固件通过这两个读写函数就可以实现对控制寄存器的读写操作,以此来设置控制寄存器输出端的值,其他一些有关控制寄存器的介绍,大家可以参考具体的数据手册。
原理图
图3
引脚配置
图4
其中LCD_RS、LCD_RW、LCD_EN、LCD_PSB是控制端,分别对应LCD12864液晶的数据/命令选择端、读写选择端、使能端、串并行选择端;LCD_DATA是液晶8位并行数据端。通过对这些控制寄存器端口的读写操作,就可以实现对外部液晶的控制操作。 具体的函数代码在这里我就不和大家多说,就跟大家介绍一下程序中所用到的两个最主要的底层驱动函数:液晶写数据函数和液晶写命令函数。 - /*写指令到LCD*/
- void LCD_Write_Command(uchar cmd)
- {
- // while(LCD_Read_Busy()); //
- LCD_RS_Write(0); //指令命令,等价于51单片机中LCD_RS=0;
- LCD_RW_Write(0); //写命令,等价于51单片机中LCD_RW=0;
- LCD_EN_Write(0); //使能端重新拉低,等价于51单片机中LCD_EN=0;
- CyDelay(1);
- LCD_DATA_Write(cmd); //指令送液晶数据口,等介于51单片机中:P0=cmd
- CyDelay(50); //延时
- LCD_EN_Write(1); //使能写操作,等价于51单片机中LCD_EN=1;
- CyDelay(50); //
- LCD_EN_Write(0); //使能端重新拉低,等价于51单片机中LCD_EN=0;
- }
- /*写8位数据到LCD*/
- void LCD_Write_Data8(uchar data8)
- {
- // while(LCD_Read_Busy()); //
- LCD_RS_Write(1); //数据命令,等价于51单片机中LCD_RS=1;
- LCD_RW_Write(0); //写命令,等价于51单片机中LCD_RW=0;
- LCD_EN_Write(0); //液晶使能端初始置低
- CyDelay(1);
- LCD_DATA_Write(data8); //数据送液晶数据口,等介于51单片机中:P0=cmd
- CyDelay(50);
- LCD_EN_Write(1); //使能写操作,等价于51单片机中LCD_EN=1;
- CyDelay(50); //
- LCD_EN_Write(0); //使能端重新拉低,等价于51单片机中LCD_EN=0;
- }
复制代码 我们从这两个函数可以看出,他与51单片机中写数据和写命令驱动函数的主要区别在于:51单片机中对某一位IO端口的操作是通过对相应端口进行赋值操作来实现的,而这里对端口的操作则是通过对相应控制寄存器的写操作函数来实现的,但操作时序都是一样的。有了这两个最基本的底层驱动函数,其他一些对LCD12864液晶的操作也就是重复对这两个函数的调用,基本不会有什么问题,当然LCD1602液晶也可以采用这种方法来控制。 我这次所实现的也只是一些最基本的功能,只是起一个抛砖引玉的作用,而且目前还只能显示字母和数字,不知道为什么不能正常显示汉字?另外还有一点就是程序中的读忙函数不能实现,有知道的各位还望不吝赐教,期待大家更精彩的分享!下面是我所实现的实际效果图,以次来献给爱板,感谢爱板为我们大家提供了一个良好的学习交流平台! |