首页>>论坛 >>技术社区 >>Ramtron社区论坛 >>微控制器
|
我要发帖  | 我要投票  | 我要回复  | 收藏
1

玩转12864液晶(1)--显示字符

玩转12864液晶(1)--显示字符
 

在我们常用的人机交互显示界面中,除了数码管,LED,以及我们之前已经提到的LCD1602之外,还有一种液晶屏用的比较多。相信接触过单片机的朋友都知道了,那就是12864液晶。顾名思义,12864表示其横向可以显示128个点,纵向可以显示64个点。我们常用的12864液晶模块中有带字库的,也有不带字库的,其控制芯片也有很多种,如KS0108
T6963,ST7920等等。在这里我们以ST7920为主控芯片的12864液晶屏来学习如何去驱动它。(液晶屏采用金鹏的OCMJ4X8C)

screenshot1.jpg



关于这个液晶屏的更多信息,请参考它的DATASHEET,附件中有下载。
我们先来了解一下它的并行连接情况。
下面是电路连接图

screenshot2.jpg



从上面的图可以看出,液晶模块和单片机的连接除了P0口的8位并行数据线之外,还有RS,RW,E等几根线。其中R/S是指令和数据寄存器的选择控制线(串行模式下为片选),R/W是读写控制线(串行模式下是数据线),E是使能线(串行模式下为时钟线)。
通过这几根控制线和数据线,再结合它的时序图,我们就可以编写出相应的驱动程序啦。
看看并行模式下的写时序图:

screenshot3.jpg



根据这个时序图,我们就可以写出写数据或者写命令到LCD12864液晶的子程序。
读时序图如下:

screenshot4.jpg



根据这个时序图我们就可以从LCD12864液晶模块内部RAM中读出相应的数据,我们的忙检测函数就是根据这个时序图写出来的。以及后面章节中讲的画点函数等都要用到读时序。
有了这两个时序图,然后我们再看看OCMJ4X8C的相关指令集,就可以编写出驱动程序了。
这里要注意的是指令集分为基本指令集和扩充指令集,其中扩充指令集主要是与绘图相关,在此后的章节中会有相应的介绍。
下面让我们根据这些编写出它的驱动程序吧。
我的硬件测试条件为:STC89C516(11.0592MHz) + OCMJ4X8C
实际显示效果图片如下:

screenshot5.jpg



程序部分如下,请结合液晶模块的DATASHEET看程序,这样能够更加快速的弄懂程序的流程。大致有如下几个函数:写数据,写指令,忙检测,初始化,指定地址显示字符串等等。

  1. #include "reg52.h"
     
  2. #include "intrins.h"
     
  3. sbit io_LCD12864_RS = P1^0 ;
     
  4. sbit io_LCD12864_RW = P1^1 ;
     
  5. sbit io_LCD12864_EN = P1^2 ;
     

  6.  
  7. #define io_LCD12864_DATAPORT P0
     

  8.  
  9. #define SET_DATA  io_LCD12864_RS = 1 ;
     
  10. #define SET_INC  io_LCD12864_RS = 0 ;
     
  11. #define SET_READ  io_LCD12864_RW = 1 ;
     
  12. #define SET_WRITE io_LCD12864_RW = 0 ;
     
  13. #define SET_EN    io_LCD12864_EN = 1 ;
     
  14. #define CLR_EN    io_LCD12864_EN = 0 ;
     

  15.  

  16.  
  17. void v_Lcd12864CheckBusy_f( void )      //忙检测函数
     
  18. {
     
  19.     unsigned int nTimeOut = 0 ;
     
  20.     SET_INC
     
  21.     SET_READ
     
  22.     CLR_EN
     
  23.     SET_EN
     
  24.     while( ( io_LCD12864_DATAPORT & 0x80 ) && ( ++nTimeOut != 0 ) ) ;
     
  25.     CLR_EN
     
  26.     SET_INC
     
  27.     SET_READ
     
  28. }
     

  29.  
  30. void v_Lcd12864SendCmd_f( unsigned char byCmd )      //发送命令
     
  31. {
     
  32.     v_Lcd12864CheckBusy_f() ;
     
  33.     SET_INC
     
  34.     SET_WRITE
     
  35.     CLR_EN
     
  36.     io_LCD12864_DATAPORT = byCmd ;
     
  37.     _nop_();
     
  38.     _nop_();
     
  39.     SET_EN  
     
  40.     _nop_();
     
  41.     _nop_();
     
  42.     CLR_EN
     
  43.     SET_READ
     
  44.     SET_INC
     
  45. }
     
  46. void v_Lcd12864SendData_f( unsigned char byData )    //发送数据
     
  47. {
     
  48.     v_Lcd12864CheckBusy_f() ;
     
  49.     SET_DATA
     
  50.     SET_WRITE
     
  51.     CLR_EN
     
  52.     io_LCD12864_DATAPORT = byData ;
     
  53.     _nop_();
     
  54.     _nop_();
     
  55.     SET_EN  
     
  56.     _nop_();
     
  57.     _nop_();
     
  58.     CLR_EN
     
  59.     SET_READ
     
  60.     SET_INC
     
  61. }
     

  62.  
  63. void v_DelayMs_f( unsigned int nDelay )              //延时
     
  64. {
     
  65.     unsigned int i ;
     
  66.     for( ; nDelay > 0 ; nDelay-- )
     
  67.     {
     
  68.         for( i = 125 ; i > 0 ; i-- ) ;
     
  69.     }
     
  70. }
     

  71.  
  72. void v_Lcd12864Init_f( void )                  //初始化
     
  73. {
     
  74.     v_Lcd12864SendCmd_f( 0x30 ) ;              //基本指令集
     
  75.     v_DelayMs_f( 50 ) ;
     
  76.     v_Lcd12864SendCmd_f( 0x01 ) ;              //清屏
     
  77.     v_DelayMs_f( 50 ) ;
     
  78.     v_Lcd12864SendCmd_f( 0x06 ) ;              //光标右移
     
  79.     v_DelayMs_f( 50 ) ;
     
  80.     v_Lcd12864SendCmd_f( 0x0c ) ;              //开显示
     
  81. }
     
  82. void v_Lcd12864SetAddress_f( unsigned char x, y )  //地址转换
     
  83. {
     
  84.     unsigned char byAddress ;
     
  85.     switch( y )
     
  86.     {
     
  87.         case 0 :    byAddress = 0x80 + x ;
     
  88.             break;
     
  89.         case 1 :    byAddress = 0x90 + x ;
     
  90.             break ;
     
  91.         case 2 :    byAddress = 0x88 + x ;
     
  92.             break ;
     
  93.         case 3 :    byAddress = 0x98 + x ;
     
  94.             break ;
     
  95.         default :
     
  96.             break ;
     
  97.     }
     
  98.     v_Lcd12864SendCmd_f( byAddress ) ;
     
  99. }
     
  100. void v_Lcd12864PutString_f( unsigned char x, unsigned char y, unsigned char *pData )
     
  101. {
     
  102.     v_Lcd12864SetAddress_f( x, y ) ;
     
  103.     while( *pData != '\0' )
     
  104.     {
     
  105.         v_Lcd12864SendData_f( *pData++ ) ;
     
  106.     }            
     

  107.  
  108. }
     
  109. void main( void )
     
  110. {
     
  111.     v_Lcd12864Init_f() ;
     

  112.  
  113.     v_Lcd12864PutString_f( 0,0, "电子工程师之家") ;
     
  114.     v_Lcd12864PutString_f( 2,1, "欢迎光临") ;
     
  115.     v_Lcd12864PutString_f( 0,2, "*LCD12864ST7920*") ;
     
  116.     v_Lcd12864PutString_f( 0,3, "★○◇◆※☆■△") ;
     
  117.     while( 1 ) ;
     
  118. }
复制代码

怎么样,你弄出来了吗,很简单吧~~
下一章节内容将学习如何在LCD12864液晶屏上画图。尽请期待^_^

 
相关主题
回复 链接 收藏
 
我要发帖  | 我要投票  | 我要回复  | 收藏
1