原创 51单片机1602液晶驱动程序(三)四线驱动(4bit)

2009-4-10 22:08 9248 7 10 分类: MCU/ 嵌入式

51单片机1602液晶驱动程序(三)四线驱动(4bit<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


   LCM1602可以用四线驱动,也就是说数据线只连D4~D7,这样的好处是节省了单片机的I/O口。


 


/*=========================================================


SMC<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1602A(16*2)模拟口线接线方式 连接线图:


---------------------------------------------------


|LCM-----51 | LCM-----51 | LCM------51 |


---------------------------------------------|


DB4-----P1.4 | RW-------P2.0 |


DB5-----P1.5 | RS -------P2.1 |


DB6-----P1.6 | E --------P2.2 |


DB7-----P1.7 | VLCD 1K 电阻到 GND|


---------------------------------------------------


[:AT89S51 使用 12M晶体震荡器]


=========================================================*/


#include <reg51.h>


 


sbit LCM_RW=P2^0; //定义引脚


sbit LCM_RS=P2^1;


sbit LCM_E =P2^2;


 


#define LCM_Data  P1


 


#define Busy 0x80 //用于检测 LCM 状态字中的 Busy 标识


 


void WriteDataLCM(unsigned char Data);


void WriteCommandLCM(unsigned char Command);


 


void LCMInit(void);


void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);


void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);


 


void Delayms(unsigned int n);


void dellay(unsigned int  h);


 


unsigned char code blog_adr[] = {"EDNchina"};


unsigned char code email[] = {"tengjingshu@126.com"};


 


void main(void)


 


{


        //Delay400Ms();    //启动等待,等 LCM 讲入工作状


        LCMInit();         //LCM 初始化


        DisplayListChar(3, 0, blog_adr);


               DisplayListChar(0, 1, email);


        while(1);


}


 


//写数据 RS="H",RW=L,D0~D7=数据,E=高脉冲


void WriteDataLCM(unsigned char Data) 


{     


       LCM_RS = 1;


       LCM_RW = 0;


          LCM_E  = 0;


          LCM_Data =(Data & 0xF0);


          LCM_E  = 1;


       dellay(100);     //短暂延时,代替检测忙状态


          LCM_E  = 0;


       LCM_Data =(Data & 0x0F)<<4;


       LCM_E  = 1;


          dellay(100);


          LCM_E  = 0;


}


 


//写指令 RS="L",RW=L,D0~D7=指令码,E=高脉冲


void WriteCommandLCM(unsigned char Command)


{


dellay(100);       //短暂延时,代替检测忙状态


      LCM_RS = 0;


         LCM_RW = 0;


         LCM_E  = 0;


         LCM_Data =( Command & 0xF0);


         LCM_E  = 1;


      dellay(100);


         LCM_E  = 0;


      LCM_Data =( Command & 0x0F )<<4;


      LCM_E  = 1;


         dellay(100);


      LCM_E  = 0;


}


 


//读数据 RS="H",RW=H,E=H


//读状态 RS="L",RW=H,E=H


//由于不要检测忙,所以读数据和读状态两个函数省略


 


void LCMInit(void)     //LCM 初始化


{


      LCM_Data = 0;


      Delayms(15);


      WriteCommandLCM(0x03); //三次显示模式设置不检测忙信号


      Delayms(5);


      WriteCommandLCM(0x03);


      Delayms(5);


      WriteCommandLCM(0x03);


      Delayms(5);


      WriteCommandLCM(0x02);


         Delayms(5);


      WriteCommandLCM(0x28); //显示模式设置,开始要求每次检测忙信号


      WriteCommandLCM(0x06); // 显示光标移动设置


         WriteCommandLCM(0x0C);


      WriteCommandLCM(0x01);


        Delayms(5);


}


 


//按指定位置显示一个字符


void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)


{


Y &= 0x1;


X &= 0xF;   //限制 X 不能大于 15Y 不能大于 1


if (Y) X |= 0x40;   //当要显示第二行时地址码+0x40;


X |= 0x80;       //算出指令码


WriteCommandLCM(X);    //这里不检测忙信号,发送地址码


WriteDataLCM(DData);


}


 


//按指定位置显示一串字符


void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)


{


unsigned char ListLength;


ListLength = 0;


Y &= 0x1;


X &= 0xF; //限制 X 不能大于 15Y 不能大于 1


while (DData[ListLength]>0x1f) //若到达字串尾则退出


  {


        if (X <= 0xF) //X 坐标应小于 0xF


           {


                 DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符


                 ListLength++; X++;


           }


}


}


 


void Delayms(unsigned int n)


{


       unsigned int i,j;


       for(j=n;j>0;j--)


       for(i=112;i>0;i--);


}


 


/**************************************************


** 函数名称: dellay


** 入口参数:hunsigned int型)


** 出口参数:无


** 功能描述: 短暂延时,约0.01MS


****************************************************/


void dellay(unsigned int  h)


{


  while(h--);    //0.01MS


}


 


   


本文程序下载:https://static.assets-stash.eet-china.com/album/old-resources/2009/4/10/bd51c2f7-e4e2-4858-beb3-d361bc6500cf.rar


 


LCM16028bit驱动和4bit驱动的电路图差别是4bit只用到数据线D4~D7,而D0~D3没有用到。


1602系列液晶显示模块常用的驱动芯片有HD44780(日立公司),兼容芯片有KS0066(韩国三星)sEDl278(seikoEpson)NJu6408(NewJapanRadioC0Ld)等。


其实不知道LCM1602用的是什么芯片,因为看到的是一大块黑色的集成封装。下面以HD44780为例介绍。(我下过KS0066DataSHeet,和HD44780芯片的初始化命令代码是不一样的,如果按照KS0066的初始化,LCM1602没有显示)


HD44780 LCD控制器的命令和位的定义:


 


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />



a0aaf986-3e45-4ef7-9a4e-fb11574170bf.JPG


点击看大图


 


HD44780 LCD初始化



 


263fd950-b5b3-4924-b505-e6f78899727c.JPG


 


void LCMInit(void)     //LCM 初始化


{


      LCM_Data = 0;


      //上电初始化


Delayms(15);             //等待15ms或更长


      WriteCommandLCM(0x03);


      Delayms(5);              //等待4.1ms或更长


      WriteCommandLCM(0x03);


      Delayms(5);              //等待100us或更长


      WriteCommandLCM(0x03);


      Delayms(5);              //等待40us或更长


      WriteCommandLCM(0x02);


         Delayms(5);               //等待40us或更长


       //显示器配置


      WriteCommandLCM(0x28); //配置显示屏


      WriteCommandLCM(0x06); //设置显示屏自动增地址指针


         WriteCommandLCM(0x0C); //开显示屏并失能指针和光标


      WriteCommandLCM(0x01);//发清屏命令


        Delayms(5);              //此后等待至少1.64ms(必不可少)


}


 


参考Spartan-3E使用手册中文版


 


其实好像初始化没有这么严格,参考网上其它程序,有的程序采用下面的初始化。


/********************************************************************/
void LCD_init(void)
{
   
WriteCommandLCM (0x01);
   
Delayms (5);
   
WriteCommandLCM (0x01);
   
Delayms (5);    
   
WriteCommandLCM (0x28);
   
Delayms (5);
    
WriteCommandLCM (0x28);
   
Delayms (5);
   
WriteCommandLCM (0x28);
   
Delayms (5);    
   
WriteCommandLCM (0x0C);
   
Delayms (5);    
   
WriteCommandLCM (0x80);
   
Delayms (5);    
   
WriteCommandLCM (0x01);
   
Delayms (5);
}
/********************************* *********************************/


 


由于该显示屏是4位操作,每8位命令被送到24位(2个半位)。高半位先送,低半位后送。



 

点击看大图


 


//写指令 RS="L",RW=L,D0~D7=指令码,E=高脉冲


void WriteCommandLCM(unsigned char Command)


{


dellay(100);       //短暂延时,代替检测忙状态


      LCM_RS = 0;


         LCM_RW = 0;


         LCM_E  = 0;


         LCM_Data =( Command & 0xF0);    //屏蔽低4


         LCM_E  = 1;      //送高4


      dellay(100);


         LCM_E  = 0;


      LCM_Data =( Command & 0x0F )<<4;  //屏蔽高四位,把低四位移到高四位


      LCM_E  = 1;      //送低4


         dellay(100);


      LCM_E  = 0;


}


 


 


    CGROMCGRAM中字符代码与字符图形对应关系



 

点击看大图 


 


参考资料:
1
HD44780 DtatSheet


2LCD1602 4线并口通信源程序


http://www.laogu.com/wz_1770.htm 


31602系列液晶显示模块的驱动程序设计及设计中需要注意的问题


 http://papers.jdzj.com/showart.asp?art_id=3861


41602的四线驱动


http://www.edacn.net/html/18/187218-51332.html 


51602AVRC驱动(4线方式)


http://blog.ednchina.com/chuanhuibh/106299/message.aspx 


61602字符型LCD介绍及使用


http://www.mcudriver.cn/mod2/show_article.asp?id=212991


7LCD1602-MC9SDG128的程序


http://www.eefocus.com/myspace/blog/show_144777.html

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户377235 2012-9-23 15:53

谢谢

coyoo 2012-5-3 11:13

如果要打开一个存在的文件并在原有的文件后面写入时,使用a选项。r和w选项会将原有内容清零。

用户518079 2009-4-30 15:04

楼主记录的很细致呀!

用户184981 2009-4-18 13:27

51就是麻烦,我以前用51写液晶驱动,太长,后来用AVR来作,有自带的驱动函数。直接调用就可以了。
相关推荐阅读
藤井树 2015-10-12 14:43
印制电路板的抗干扰设计 zz
印制电路板的抗干扰设计     作者:中船重工集团第707所 肖麟芬   摘   要:本文以印制电路板的电磁兼容性为核心,分析了电磁干扰的产生机理...
藤井树 2013-10-22 15:32
2010.5.30 黄草梁上包饺子一日登山活动——摘韭菜篇
        上次桃花节的时候也有野韭菜,那时候的我连草和韭菜叶分不清,才回去的韭菜也不敢吃,哈哈,这次可算真正见识了韭菜,黄草梁也叫韭菜梁,因为满山遍野都是野韭菜而闻名,比较圆比较粗的就是野韭...
藤井树 2013-10-22 15:28
2010.5.30 黄草梁上包饺子一日登山活动——包饺子篇
摘韭菜回来,大家已经忙开了 我也装模作样地“工作着” 哈哈,还不让我包,包饺子是技术活,一定要皮薄馅厚才有资格包,像我这样的只能旁观了 摘的韭菜应该足够了,旁边那个袋子是我摘来带回学校的 ...
藤井树 2013-08-09 15:19
datasheet下载网站整理(查IC芯片手册)【原创】
*************************************************************************         作为电子工程师,芯片的dat...
藤井树 2010-06-04 00:21
陈伟宁王辉一家捐助渠道(北京菲亚特—英菲尼迪)
       王辉的最新消息请关注 http://chenweining.org/       目前事故责任认定已经出来了——陈家全责。        发信人: program (程序), 信区: D...
藤井树 2010-06-01 13:43
2010.5.30 黄草梁上包饺子一日登山活动——美景篇
这天不得不说的是天空,蓝蓝的天空,白白的云    绿油油的山脊  我、洪涛哥哥、huangna妹妹还有她同事小艾走在黄草梁上    在蓝天白云下合影       阳光照过来,景色真美 象鼻山,走不...
EE直播间
更多
我要评论
3
7
关闭 站长推荐上一条 /3 下一条