搜索
bottom↓
回复: 11

请问一下液晶EL1602第2行不能显示的问题

[复制链接]

出0入0汤圆

发表于 2010-11-3 10:39:42 | 显示全部楼层 |阅读模式
主要想看一下第二行的地址是多少

现在试了0xc0,0x40,0x90等都没有第2行显示

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2010-11-3 16:47:24 | 显示全部楼层
现在只显示1行

而且通电后第2行没有背景黑框

出0入0汤圆

 楼主| 发表于 2010-11-4 08:37:38 | 显示全部楼层
up

出0入0汤圆

发表于 2010-11-4 14:05:16 | 显示全部楼层
你是不是没有设置成两行的工作模式?

8bit 总线要写指令 0x38, 4bit 总线要写指令 0x2, 0x8

出0入0汤圆

 楼主| 发表于 2010-11-4 17:00:25 | 显示全部楼层
thanks

出0入0汤圆

 楼主| 发表于 2010-11-4 18:17:08 | 显示全部楼层
第2行好像还是没有显示

相关初始化如下:

void LCD_Init(void)
{

   LCD_WriteCmd(0x01);    // LCD清屏
   LCD_WriteCmd(0x06);    //数据读、写操作后,光标右移动,AC自动增一
   LCD_WriteCmd(0x0C);    //开显示;关光标;关闪烁
   LCD_WriteCmd(0x38);    //8位数据接口;两行显示;5x8点阵字符
}

出0入0汤圆

 楼主| 发表于 2010-11-4 18:42:26 | 显示全部楼层
还是只显示一行16个字符"12345abcde12345a"

完整的程序如下

//******** EL1602 test *********

#include <iom16v.h>
#include <macros.h>

//LCD数据端口PC0-PC7
#define LCD_DATA_PORT  PORTC
#define LCD_DATA_DDR   DDRC
#define LCD_DATA_PIN   PINC

//LCD控制端口PA5,PA7
#define LCD_CONTROL_PORT    PORTA
#define LCD_CONTROL_DDR     DDRA
#define        RS         5
#define        E         7

#define LINEWIDTH 16  //行宽   
#define LINES 2       //行数

//--------------------------------------------------------------------------------------------------
//Public function prototypes
//--------------------------------------------------------------------------------------------------
void Delay_1us(void);
void Delay_1ms(void);
void Delay_nus(unsigned int n);
void Delay_nms(unsigned int n);

#define        SETBIT(x,y) (x|=(1<<y))      //set bit y in byte x
#define        CLRBIT(x,y) (x&=(~(1<<y)))   //clear bit y in byte x
#define        CHKBIT(x,y) (x&(1<<y))       //check bit y in byte x

#define uchar unsigned char // 0~255
#define uint unsigned int   // 0~65535

void LCD_Init(void);     //LCD初始化
void LCD_Clear(void);    //LCD清屏
void LCD_CheckState(void);   //--保留
void LCD_WriteCmd(unsigned char scmd);    //写一个命令到LCD
void LCD_WriteData(unsigned char DData);  //写一个数据到LCD
void LCD_Set_xy(unsigned char Y, unsigned char X); //设置光标位置
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c1);   //写一个字符到LCD
void LCD_WriteStr(unsigned char Y,unsigned char X,unsigned char *pstr); //写字符串到LCD显示
void LCD_WriteStrAuto(unsigned char *pstr);   //从显示屏的初始位置写入数据,自动换行


void LCD_Init(void)
{
   Delay_nms(100);
       
   LCD_WriteCmd(0x01);    // LCD清屏
   LCD_WriteCmd(0x06);    //数据读、写操作后,鼠标右移动,AC自动增一
   LCD_WriteCmd(0x0C);    //开显示;关光标;关闪烁
   LCD_WriteCmd(0x38);    //8位数据接口;两行显示;5x8点阵字符
}


//LCD清屏
void  LCD_Clear(void)
{
   LCD_WriteCmd(0x01);
   Delay_nms(1);        
}


void LCD_WriteCmd(unsigned char scmd)   //send command
{
        CLRBIT(LCD_CONTROL_PORT,E);
        CLRBIT(LCD_CONTROL_PORT,RS);

        LCD_DATA_DDR=0xFF;
        LCD_DATA_PORT=scmd;
               
        NOP();
        SETBIT(LCD_CONTROL_PORT,E);
        NOP();
        CLRBIT(LCD_CONTROL_PORT,E);

        Delay_nus(20);       
}

void LCD_WriteData(unsigned char DData)
{
        CLRBIT(LCD_CONTROL_PORT,E);
        SETBIT(LCD_CONTROL_PORT,RS);
       
        LCD_DATA_DDR=0xFF;
        LCD_DATA_PORT=DData;
       
        NOP();
        SETBIT(LCD_CONTROL_PORT,E);
        NOP();
        CLRBIT(LCD_CONTROL_PORT,E);

        Delay_nus(20);       
}

//设置光标位置,先Y坐标后X坐标
void LCD_Set_xy(unsigned char Y, unsigned char X)
{
    unsigned char i=0x00;
    switch(Y & 0x0f)   //确定行号
    {
        case 0x00:
                i=0x80;  //0x80
                break;
        case 0x01:
                i=0xC0; //0x90;
                break;

        default :
                break;
    }
    i = (X & 0x0f)|i; //确定列号
   LCD_WriteCmd(i);
       
}

//从显示屏指定的行(Y),列(X)的位置写入字符
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c1)
{
   LCD_WriteCmd(0x38);        // 8bit I/F, basic command, graphic off
   
   LCD_Set_xy(X,Y);   
   LCD_WriteData(c1);
   
   Delay_nms(1); //2006.11.19
}

//从显示屏指定的行(Y),列(X)的位置写入字符串
void LCD_WriteStr(unsigned char X,unsigned char Y,unsigned char *pstr1)   //英文LCD
{
   unsigned char j;
   unsigned char *pstr = pstr1;

   LCD_WriteCmd(0x38);        // 8bit I/F, basic command, graphic off

   LCD_Set_xy(Y,X);
         
   j=Y * LINEWIDTH + X;
   while (*pstr && j< (LINEWIDTH * LINES))
   {
      if (j%LINEWIDTH==0)         //判断是否换行
      {
         LCD_Set_xy(j/LINEWIDTH,0);   //如换行, 则光标移动到行首
                 Delay_nms(1);
      }
                 
      LCD_WriteData(*pstr++);
      j++;
          Delay_nms(1);

   }
         
   Delay_nms(1); //2006.11.19
}

//从显示屏的初始位置写入字符串,自动换行
void LCD_WriteStrAuto(unsigned char *pstr1)  //英文LCD
{
   unsigned char i;
   unsigned char j;
   unsigned char *pstr = pstr1;

   LCD_WriteCmd(0x38);        // 8bit I/F, basic command, graphic off
   
   LCD_Clear();
   LCD_Set_xy(0,0);
   Delay_nms(1);
               
   j=0;
   while (*pstr && j<LINEWIDTH*LINES)
   {
      if (j%LINEWIDTH==0)         //判断是否换行
      {
         LCD_Set_xy(j/LINEWIDTH,0);   //如换行, 则光标移动到行首
                 Delay_nms(1);
      }          

      LCD_WriteData(*pstr++);
      j++;
          Delay_nms(1);
   }
         
   Delay_nms(1);
}



void main(void)
{
   CLI();                 // disable interrupts

   Delay_nms(1000);

   //LCD端口初始化
   LCD_DATA_DDR=0xFF;
   LCD_CONTROL_DDR|=(1<<RS|1<<E); //置位RS,E等
   CLRBIT(LCD_CONTROL_PORT,E);
   CLRBIT(LCD_CONTROL_PORT,RS);
   LCD_DATA_PORT|=0xFF;

   //LCD功能初始化
   LCD_Init();       
   Delay_nms(10);
       
   while(1)
   {
       
      LCD_WriteStrAuto("12345abcde12345abcde");
      Delay_nms(2000);
       
   }
       
}

/*-----------------------------------------------------------------------
延时函数
系统时钟:8M
-----------------------------------------------------------------------*/
void Delay_1us(void)                 //1us延时函数
  {
   asm("nop");
  }

void Delay_nus(unsigned int n)       //N us延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   Delay_1us();
  }
  
void Delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
  
void Delay_nms(unsigned int n)       //N ms延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   Delay_1ms();
  }

出0入0汤圆

发表于 2010-11-4 21:15:32 | 显示全部楼层
C51 我也只是初学,也没有 AVR 的编译环境。所以你 AVR C 的程序我也没法帮你试,但是有几点建议:

1,初始化的指令序列,和控制 IC 手册上要求的不一样,如果你是 8bit 接法,要按时序写 3 次 0x38。然后才开始设置。当然,我也有不完全按照手册要求进行初始化成功的。应该是 LCM 内部初始化 OK,不需要外部指令做初始化了。

2,建议你先用一套简单的指令来试验。直接用一个循环写两行的内容。下面是我程序里的做法。避免因为其他逻辑出错,导致误认为 LCM 工作不正常。这样可以快速地缩小问题的范围。下面的循环在我的系统上,是可以正常显示一行大写 "ABCD...." ,第二行小写"abcd..."的。当然,其他的程序段我省略了。

        for (i; i < 16; i++) {
                        w_CMD_LCM1602(0x80 + i);        //定位第一行左一位置,并逐个向右
                        delay_ms_0(1);
                        w_DAT_LCM1602(0x41 + i);        //从 'A' 开始写大写字符
                        delay_ms_0(1);
                        w_CMD_LCM1602(0xC0 + i);        //定位第二行左一位置,并逐个向右
                        delay_ms_0(1);
                        w_DAT_LCM1602(0x61 + i);        //从 'a' 开始写小写字符
                        delay_ms_0(1);
        }

3,建议你对你设置光标位置的 LCD_Set_xy(Y,X) 当中 LCD_WriteCmd(i);  这行下个中断,看看写进去的命令值是多少,第一行应该是从 0x80 开始。第二行应该是从 0xC0 开始。

(修改错字)

出0入0汤圆

发表于 2010-11-4 21:19:41 | 显示全部楼层
还有可以看一下论坛里其他的帖子,1602 讨论还挺多的。8bit 的例子也很多。我之前也有发一个帖子,其中有关于初始化的文档。你可以参考一下。

http://ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4344053&bbs_page_no=3&bbs_id=1006

出0入0汤圆

 楼主| 发表于 2010-11-4 22:22:48 | 显示全部楼层
谢谢,明天连写3次初始化,并直接写第2行试试; 以前用其他液晶好像很容易调通的

出0入0汤圆

 楼主| 发表于 2010-11-5 08:53:30 | 显示全部楼层
已解决,感谢【3楼】 easywater 的提示

LCD_WriteChar,LCD_WriteStr,LCD_WriteStrAuto 中也修改成0x38就ok了

出0入0汤圆

发表于 2013-4-8 15:32:51 | 显示全部楼层
我也遇到这个问题了.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 13:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表