EDN首页   博客首页

日志档案

发表于 2008-8-22 14:24:16

1

标签: LCD1602  51  4位驱动  

LCD1602 4位总线显示问题

这两天想用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电子爱好者家园网站,给咱的宣传积分加点力^_^

系统分类: 单片机   |   用户分类: 51单片机相关   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(166)    回复(1)  

投一票您将和博主都有获奖机会!

  • yanwuxu

    2008-8-24 16:54:11

    4位控制方式复位不显示的问题解决,由于我这个是在8位总线上修改的,后来尝试按照标准的时序把写指令和写数据中的EN信号由上升沿改成正脉冲,也就是说在写延时后EN=1的后面再将EN置为0,写高低4位的两次都这样,现在开机和复位就都显示正常了^_^