wtiechen1969 发表于 2013-3-9 21:53:22

12864液晶屏(0108驱动)显示错位

都是在LCDMK那里买的,绿色那块显示正常,换上黑底红字的屏显示就会错位,这两块都是0108驱动,请大家帮忙分析一下问题出在哪里。

pengtaoABC 发表于 2013-3-9 21:57:35

能上程序方便大家的吗?应该是2块屏参数有些不同,修改下延时应该可以的吧。

wtiechen1969 发表于 2013-3-9 22:08:41

pengtaoABC 发表于 2013-3-9 21:57 static/image/common/back.gif
能上程序方便大家的吗?应该是2块屏参数有些不同,修改下延时应该可以的吧。 ...

//******查忙****///
void busy()
{
p_di=0;
p_rw=1;
while(1)
{
    p_e=1;
if(Data<0x80)break;
p_e=0;
}
p_e=0;
}

///*****初始化******///
void Init()
{
//开显示;
p_di=0;
p_rw=0;
Data=0x3f;
p_cs1=0;
p_cs2=1;
p_e=1;
p_e=0;
p_cs1=1;
p_cs2=0;
p_e=1;
p_e=0;
//0行开始显示
busy();

p_cs1=0;
p_cs2=1;
Data=0xc0;
p_e=1;
p_e=0;
p_cs1=1;
p_cs2=0;
p_e=1;
p_e=0;
}

void setxy(unsigned char x,unsigned char y)
{
if(y<64)
{
//***写行地址l**//
    busy();
    p_di=p_rw=p_cs1=0;
    p_cs2=1;
    Data=0xb8|x;
    p_e=1;
    p_e=0;
///***写列地址l**//
    busy();
    p_di=p_rw=p_cs1=0;
    p_cs2=1;
    Data=0x40|y;
    p_e=1;
    p_e=0;
}
else
{
//***写行地址r**//
    busy();
p_di=p_rw=p_cs2=0;
p_cs1=1;
Data = 0xb8|x;
p_e=1;
p_e=0;
///***写列地址r**//
    busy();
    p_di=p_rw=p_cs2=0;
    p_cs1=1;
    Data=0x40|y;
    p_e=1;
    p_e=0;
}

}
//****写数据****//
void whitedata(unsigned char x,unsigned char y)
{
busy();
setxy(x,y);//set x,y address address
if(y<64)
{
    p_rw=p_cs1=0;
    p_cs2=1;   
}
else
{
    p_rw=p_cs2=0;
p_cs1=1;
}
p_di=1;
Data=0x00;
p_e=1;
p_e=0;
}



/*---------------------------------------------*/


void LCD_write_ASCII(unsigned char page,unsigned char row, unsigned char c) //row:列 page:页 dd:字符
{
        unsigned char i,j,k;

        k=row*8;
        for(i=0;i<2;i++)
        {
           for(j=0;j<8;j++)
                {
                        busy();

                        setxy(i+page,(j+k));// 页,列

        if(k<64)
   {
   p_rw=p_cs1=0;
   p_di=1;
   p_cs2=1;
   }
   else
   {
   p_rw=p_cs2=0;
p_di=1;
p_cs1=1;
   }

   Data=ASCII;
   p_e=1;
   p_e=0;

        }
}
}



/*----------------------------------------------*/


void LCD_write_shu(unsigned char page,unsigned char row, unsigned char c) //row:列 page:页 dd:字符
{
        unsigned char i,j,k;

        k=row*16;
        for(i=0;i<4;i++)
        {
   for(j=0;j<16;j++)
        {
                busy();

                setxy(i+page,(j+k));// 页,列

if(k<64)
   {
   p_rw=p_cs1=0;
   p_di=1;
   p_cs2=1;
   }
   else
   {
   p_rw=p_cs2=0;
p_di=1;
p_cs1=1;
   }

   Data=shuzi[(c*64)+(i*16+j)];
   p_e=1;
   p_e=0;

        }
}
}


///******* 显示16点阵汉字******///


void white_hanzi_16(unsigned char page,unsigned char row, unsigned char c) //row:列 page:页 dd:字符
{
        unsigned char i,j,k;

        k=row*16;
        for(i=0;i<2;i++)
        {
   for(j=0;j<16;j++)
        {
                busy();

                setxy(i+page,(j+k));// 页,列

if(k<64)
   {
   p_rw=p_cs1=0;
   p_di=1;
   p_cs2=1;
   }
   else
   {
   p_rw=p_cs2=0;
p_di=1;
p_cs1=1;
   }

   Data=HZK_16[(c*32)+(i*16+j)];
   p_e=1;
   p_e=0;

        }
}
}


void LCD_clr_row(unsigned char num)
{
        unsigned char j;
        busy();
    for(j=0;j<128;j++)
       
    whitedata(num,j);       
}

///****清屏***//
void clear()
{        
unsigned char i,j;
busy();
for(i=0;i<8;i++)
    for(j=0;j<128;j++)

    whitedata(i,j);
}


         /****写图像数据****/

void whitedata_BMP(unsigned char x,unsigned char y)
{
busy();
setxy(x,y);//set x,y address address
if(y<64)
{
    p_rw=p_cs1=0;
    p_cs2=1;   
}
else
{
    p_rw=p_cs2=0;
p_cs1=1;
}
p_di=1;
Data=BMP1;
p_e=1;
p_e=0;
}


/******显示图像******/
void DIS_BMP (void)
{
unsigned char i,j;
for(i=0;i<8;i++)
    for(j=0;j<128;j++)
    whitedata_BMP(i,j);
}

xwkm 发表于 2013-3-9 23:22:52

试试移上去几个像素看看

carefree 发表于 2013-3-9 23:39:05

wtiechen1969 发表于 2013-3-10 11:33:28

问题还没有解决,希望大家帮忙看一下

wtiechen1969 发表于 2013-3-10 11:39:14

请各位高手帮忙看看

StoneSun 发表于 2013-3-11 14:41:25

能显示出文字来应该证明LCD的驱动是没问题的,要看你的黄屏的应用程序地址的设置是否正确?左半屏Y轴向下偏移2个点;右半屏看样子像是向下偏移了4个Byte的样子。你要确保这两个屏的显存RAM地址是一样的。

leirui001 发表于 2013-12-22 21:31:16

也碰到了类似问题,不知LZ找到原因没?

1欧姆 发表于 2013-12-22 22:56:15

leirui001 发表于 2013-12-22 21:31
也碰到了类似问题,不知LZ找到原因没?

一般是锁存数据时需要适当延时。或者初始化时需要E=0。
都什么时代了,还在自己琢磨啊。直接上TreeOS 1.0单片机操作系统,全替你搞定。 www.treeos.com.cn

/******************************************TreeOS Real-Time Operating System****
Function Name:
Description: 往液晶写入1字节指令或数据
Input      : _comd为指令类型,_data为数据
Output       :
Return       :
*******************************************************************************/
void lcd_write_byte(unsigned char _comd,unsigned char _data)
{
   //设定CS1、CS2选择显示区域
   if ((_comd==CS1_COMD)||(_comd==CS1_DATA))          //1区(左半区)   
          {
                  CS1_H;//注意,有些液晶却是低电平有效!
                  CS2_L;
                }   
       else if ((_comd==CS2_COMD)||(_comd==CS2_DATA))   //2区(右半区)            
          {
                  CS1_L;   
                  CS2_H; //注意,有些液晶却是低电平有效!
                }
               
   //设定RS选择写指令或者写入数据
       if ((_comd==CS1_COMD)||(_comd==CS2_COMD)) RS_L;    //RS=0,写指令
       elseRS_H;                //RS=1,写数据
       
       //设定本次操作为写操作
       RW_L;                      //RW=0,写操作   
       OUTPUT_DATA;               //准备指令或数据值
       
       //E上升沿锁存数据
       E_H;                     //E=1
       //E_H;                     //根据晶振频率,要适当插入延时
       E_L;                     //E=0
}


/******************************************TreeOS Real-Time Operating System****
Function Name:
Description: 液晶初始化
Input      :
Output       :
Return       :
*******************************************************************************/
void lcd_init(void)
{
#ifdefUSE_LCD_SOFT_RESET
    lcd_reset(); //reset
#endif

    E_L;                              //E=0
        lcd_write_byte(CS1_COMD,0x3f);    //display on
        lcd_write_byte(CS2_COMD,0x3f);
        lcd_write_byte(CS1_COMD,0xc0);    //begin first line
        lcd_write_byte(CS2_COMD,0xc0);
       
        clear_screen(0x00);
}

xou822 发表于 2013-12-23 08:28:05

求屏幕购买链接

dushanwu522 发表于 2013-12-23 08:32:02

1.读写速度问题;2. 你没有仔细看模块的规格书;3. COM - SEG对应关系你没搞明白 。

bobo89 发表于 2013-12-23 08:40:55

学习学习!

bias 发表于 2013-12-23 11:00:04

如果是这种情况,一般原因是两个屏采用的芯片厂家不同,甚至有可能有个是国产的无锡的驱动,
请在读写和Enable那里加入延时试试看,我看你E信号都是没有加入延时,
下面程序供你参考


void LcdCheckBusyL( void )
{
    unsigned char i,temp;
    CS1 = 0;            //低电平有效
    CS2 = 1;
    RS= 0;
    RW= 1;
    LcdDataBus = 0xFF;//输出0xff以便读取正确
    do
    {
      E = 1;
      for(i=0;i<1;i++);
      temp = LcdDataBus;
      E= 0;
      _nop_();      //E=0后要执行其他程序,所需时序时间足够
    }
    while(temp & 0x80);
}

void LcdCheckBusyR( void )
{
    unsigned char i,temp;
    CS1 = 1;            //低电平有效
    CS2 = 0;
    RS= 0;
    RW= 1;
    LcdDataBus = 0xFF;//输出0xff以便读取正确
    do
    {
      E = 1;
      for(i=0;i<1;i++);
      temp = LcdDataBus;
      E= 0;
      _nop_();      //E=0后要执行其他程序,所需时序时间足够
    }
    while(temp & 0x80);
}

void LcdWrCmdL( unsigned char Cmd )
{
    LcdCheckBusyL();
    RS= 0;
    RW= 0;
    E = 1;
    _nop_();
    LcdDataBus = Cmd;
    _nop_();
    E= 0;
    _nop_();
}

void LcdWrCmdR( unsigned char Cmd )
{
    LcdCheckBusyR();
    RS= 0;
    RW= 0;
    E = 1;
    _nop_();
    LcdDataBus = Cmd;
    _nop_();
    E= 0;
    _nop_();
}

void LcdWrDat( unsigned char Dat )
{
    unsigned char x,y;
    switch (Col&0xC0)         //col.and.0xC0
    {                           //条件分支执行
      case 0:
      {
            x = Col&0x3F|0x40;// col.and.0x3f.or.Set Y Address
            y = Page&0x07|0xB8; // row.and.0x07.or.set Page
            LcdWrCmdL(y);   //设置页面地址
            LcdWrCmdL(x);   //设置列地址
            LcdCheckBusyL();
            RS= 1;
            RW= 0;
            E = 1;
            _nop_();
            LcdDataBus = Dat;
            _nop_();
            E= 0;
            _nop_();
            break;          //完成case分支
      }
      case 0x40:
      {
            x = Col&0x3F|0x40;/* col.and.0x3f.or.Set Y Address*/
            y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */
            LcdWrCmdR(y);       //设置页面地址
            LcdWrCmdR(x);       //设置列地址
            LcdCheckBusyR();
            RS= 1;
            RW= 0;
            E = 1;
            _nop_();
            LcdDataBus = Dat;
            _nop_();
            E= 0;
            _nop_();
            break;          //完成case分支
      }
    }
}

unsigned char LcdRdDat( void )
{
    unsigned char i;
    unsigned char x,y;
    unsigned char DataByte;
    switch (Col&0xC0)         //col.and.0xC0
    {                           //条件分支执行
      case 0:
      {
            x = Col&0x3F|0x40;// col.and.0x3f.or.Set Y Address
            y = Page&0x07|0xB8; // row.and.0x07.or.set Page
            LcdWrCmdL(y);       //设置页面地址
            LcdWrCmdL(x);       //设置列地址
            LcdCheckBusyL();
            RS= 1;
            RW= 1;
            LcdDataBus = 0xFF;
            E = 1;
            for(i=0;i<1;i++);
            DataByte = LcdDataBus;//dummy read
            E= 0;
            for(i=0;i<1;i++);

            LcdCheckBusyL();
            RS= 1;
            RW= 1;
            LcdDataBus = 0xFF;
            E = 1;
            for(i=0;i<1;i++);
            DataByte = LcdDataBus;
            E= 0;
            for(i=0;i<1;i++);
            break;          //完成case分支
      }
      case 0x40:
      {
            x = Col&0x3F|0x40;/* col.and.0x3f.or.Set Y Address*/
            y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */
            LcdWrCmdR(y);       //设置页面地址
            LcdWrCmdR(x);       //设置列地址
            LcdCheckBusyR();
            RS= 1;
            RW= 1;
            LcdDataBus = 0xFF;
            E = 1;
            for(i=0;i<1;i++);
            DataByte = LcdDataBus;//dummy read
            E= 0;
            for(i=0;i<1;i++);

            LcdCheckBusyR();
            RS= 1;
            RW= 1;
            LcdDataBus = 0xFF;
            E = 1;
            for(i=0;i<1;i++);
            DataByte = LcdDataBus;
            E= 0;
            for(i=0;i<1;i++);
            break;          //完成case分支
      }
    }
    return DataByte;
}

void LcdFill( unsigned char FillData )
{
    Page = 0;
    Col= 0;
    for(Page=0;Page<(LcdYPixel/8);Page++)
      for(Col=0;Col<LcdXPixel;Col++)
            LcdWrDat(FillData);
}

void LcdInit( void )
{
    LcdWrCmdL(0x3f);    //开显示
    LcdWrCmdR(0x3f);

    LcdWrCmdL(0xc0);    //设置起始地址=0
    LcdWrCmdR(0xc0);

    LcdWrCmdL(0x3f);    //开显示
    LcdWrCmdR(0x3f);

    LcdFill(0);
    Col = 0;
    Page= 0;
}

pnsyzx20088hlq 发表于 2013-12-23 11:21:19

好久没有玩过12864屏幕了,来学习一下!谢谢~

iversonY 发表于 2014-3-17 09:59:46

也有遇到过错位的情况,我是用USB烧写的,后来无意中把USB拔掉,单片机复位了下,然后就好了好了。。。。。
页: [1]
查看完整版本: 12864液晶屏(0108驱动)显示错位