原创 LCD1602 4位总线显示问题

2008-8-22 14:24 4530 9 10 分类: MCU/ 嵌入式

这两天想用AT89C2051+LCD1602做点东西,本着节省管脚的原则,想用4位控制,按照LCD1602的手册上说的把在自己的Cepark51实验板(以下简称51实验板)上8位正常的程序的初始化部分和写指令和数据部分改了一下,结果在51实验板无显示,原程序如下:


 


//Cepark51实验板LCD1602显示程序
//日期:2008年8月20日 四位控制
//文件名:lcd1602_c.c
//作者:yanwuxu



#include "at89x51.h"
#define uchar unsigned char
#define uint unsigned int
#define lcd_bus P0  //lcd1602 数据总线
sbit lcd_rs=P1^0; //lcd1602 数据/命令选择端,1数据,0指令
sbit lcd_rw=P1^1; //lcd1602 读写控制端,1读,0写
sbit lcd_en=P1^2; //lcd1602 使能端,高脉冲有效



void Delay1ms(uint mDelay1) //1ms延时
{
 uint mDelay2;
 for(;mDelay1>0;mDelay1--)
 { for(mDelay2=0;mDelay2<114;mDelay2++)
   {;}
 }
}



void lcd_wdata(uchar lcd_data) //lcd1602写数据
{
 lcd_bus=lcd_data;  //先送高4位
 lcd_rs=1;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
// Delay1ms(1);
 lcd_bus=(lcd_data<<=4); //再送低4位
 lcd_rs=1;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;



}


void lcd_wcmd(uchar lcd_cmd)  //lcd写指令
{
 lcd_bus=lcd_cmd;
 lcd_rs=0;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
// Delay1ms(1);
 lcd_bus=(lcd_cmd<<=4);
 lcd_rs=0;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
}


void lcd_disp_byte(uchar x,uchar y,uchar lcd_dat)  //lcd写字符,x横位置1-16,y行,y为1为显示在第一行,其它的为显示在第2行
{
 uchar lcd_address;


 if(y==1)
  lcd_address=0x80+x-1;  //从1-16
 else
  lcd_address=0xc0+x-1;  //从1-16
 
 lcd_wcmd(lcd_address);
 lcd_wdata(lcd_dat);


}


void lcd_disp_str(uchar x,uchar y,uchar code *s)  //lcd写字符串,x横位置1-16,y行,y为1为显示在第一行,其它的为显示在第2行
{
 uchar lcd_address;


 if(y==1)
  lcd_address=0x80+x-1;  //从1-16
 else
  lcd_address=0xc0+x-1;  //从1-16
 lcd_wcmd(lcd_address);


 while(*s>0)
 {
  lcd_wdata(*s);
  s++;    
 };
}



void lcd_init()  //lcd初始化
{
  Delay1ms(15);  //延时15ms
 lcd_wcmd(0x28);    //4位是0x28,8位是0x38
 Delay1ms(15);
 lcd_wcmd(0x28);
 Delay1ms(15);
 lcd_wcmd(0x28);


 lcd_wcmd(0x0c);
 lcd_wcmd(0x06);
 lcd_wcmd(0x01);
}



void main()
{
  lcd_init();
  while(1)
  {
   lcd_disp_byte(3,1,'K');    //测试
   lcd_disp_str(4,2,"123456");  


  }


}


 


后来在网上查阅了别人的一些关于4位驱动的文章,在LCD初始化部分0x28之前再加入0x02这条这条指令(LCD1602的归位指令),编译下载后开机显示正常了,但奇怪的是按复位键后显示不对,显示的现象就像是初始化没好一样,上面一行显示一排黑块,搞了一下午没明白为什么,问了几个兄弟都存在这个情况,很不解,手册里也没提到太多关于4位驱动注意事项...


Delay1ms(15);
 lcd_wcmd(0x02);

这是LCD初始化部分加了02指令后的完整部分:


//Cepark51实验板LCD1602显示程序
//日期:2008年8月20日 四位控制版本
//文件名:lcd1602_c.c
//作者:yanwuxu



#include "at89x51.h"
#define uchar unsigned char
#define uint unsigned int
#define lcd_bus P0  //lcd1602 数据总线
sbit lcd_rs=P1^0; //lcd1602 数据/命令选择端,1数据,0指令
sbit lcd_rw=P1^1; //lcd1602 读写控制端,1读,0写
sbit lcd_en=P1^2; //lcd1602 使能端,高脉冲有效



void Delay1ms(uint mDelay1) //1ms延时
{
 uint mDelay2;
 for(;mDelay1>0;mDelay1--)
 { for(mDelay2=0;mDelay2<114;mDelay2++)
   {;}
 }
}



void lcd_wdata(uchar lcd_data) //lcd1602写数据
{
 lcd_bus=lcd_data;  //先送高4位
 lcd_rs=1;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
// Delay1ms(1);
 lcd_bus=(lcd_data<<=4); //再送低四位
 lcd_rs=1;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;



}


void lcd_wcmd(uchar lcd_cmd)  //lcd写指令
{
 lcd_bus=lcd_cmd;
 lcd_rs=0;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
// Delay1ms(1);
 lcd_bus=(lcd_cmd<<=4);
 lcd_rs=0;
 lcd_rw=0;
 lcd_en=0;
 Delay1ms(3);
 lcd_en=1;
}


void lcd_disp_byte(uchar x,uchar y,uchar lcd_dat)  //lcd写字符,x横位置1-16,y行,y为1为显示在第一行,其它的为显示在第2行
{
 uchar lcd_address;


 if(y==1)
  lcd_address=0x80+x-1;  //从1-16
 else
  lcd_address=0xc0+x-1;  //从1-16
 
 lcd_wcmd(lcd_address);
 lcd_wdata(lcd_dat);


}


void lcd_disp_str(uchar x,uchar y,uchar code *s)  //lcd写字符串,x横位置1-16,y行,y为1为显示在第一行,其它的为显示在第2行
{
 uchar lcd_address;


 if(y==1)
  lcd_address=0x80+x-1;  //从1-16
 else
  lcd_address=0xc0+x-1;  //从1-16
 lcd_wcmd(lcd_address);


 while(*s>0)
 {
  lcd_wdata(*s);
  s++;    
 };
}



void lcd_init()  //lcd初始化
{
 Delay1ms(20);
 lcd_wcmd(0x02);


 Delay1ms(15);  //延时15ms
 lcd_wcmd(0x28);    //
 Delay1ms(15);
 lcd_wcmd(0x28);
 Delay1ms(15);
 lcd_wcmd(0x28);


 lcd_wcmd(0x0c);
 lcd_wcmd(0x06);
 lcd_wcmd(0x01);
}



void main()
{
  lcd_init();
  while(1)
  {
   lcd_disp_byte(3,1,'K');    //测试
   lcd_disp_str(4,2,"123456");  


  }


}



举手之劳,希望热心的兄弟姐妹帮忙点击宣传一下CEPark电子爱好者家园网站,给咱的宣传积分加点力^_^
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1400793 2008-8-24 16:54

4位控制方式复位不显示的问题解决,由于我这个是在8位总线上修改的,后来尝试按照标准的时序把写指令和写数据中的EN信号由上升沿改成正脉冲,也就是说在写延时后EN=1的后面再将EN置为0,写高低4位的两次都这样,现在开机和复位就都显示正常了^_^
相关推荐阅读
用户1400793 2016-03-18 10:31
汗!被转烂了的555单电源变双电源电路竟然是错的?
昨天老王在论坛发了个帖子,让大家分析一下下面的电路能否正常工作,附图1电路中,时基电路555接成无稳态电路,3脚输出频率为20KHz、占空比为1:1的方波。3脚为高电平时,C4被充电;低电平时,C3被...
用户1400793 2011-07-26 11:30
国巨和TDK贴片电容规格表
国巨Y5V_10V-to-50V_5.pdfTDK贴片电容规格书.pdf国巨X7R_16V-to-100V_6.pdf...
用户1400793 2011-07-06 15:09
部分DC-DC芯片存档
tps5420-5.5V 至 36V 输入、2A、500kHz 降压转换器.pdfAX3007 输入4.5V-40V SOP8 输出2A.pdfLM2574-国半.pdfLM2575_NCV2575....
用户1400793 2011-07-06 09:25
华为模拟技术讲义上下册
华为模拟技术讲义-下册.pdf华为模拟技术讲义-上册.pdf...
用户1400793 2011-07-06 09:09
IC常用封装尺寸
IC常用封装尺寸.pdf...
用户1400793 2011-07-06 08:50
工字电感规格
工字电感规格.pdf...
我要评论
1
9
关闭 站长推荐上一条 /3 下一条