12864液晶屏(0108驱动)显示错位
都是在LCDMK那里买的,绿色那块显示正常,换上黑底红字的屏显示就会错位,这两块都是0108驱动,请大家帮忙分析一下问题出在哪里。 能上程序方便大家的吗?应该是2块屏参数有些不同,修改下延时应该可以的吧。 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);
}
试试移上去几个像素看看 问题还没有解决,希望大家帮忙看一下 请各位高手帮忙看看 能显示出文字来应该证明LCD的驱动是没问题的,要看你的黄屏的应用程序地址的设置是否正确?左半屏Y轴向下偏移2个点;右半屏看样子像是向下偏移了4个Byte的样子。你要确保这两个屏的显存RAM地址是一样的。 也碰到了类似问题,不知LZ找到原因没? 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);
}
求屏幕购买链接 1.读写速度问题;2. 你没有仔细看模块的规格书;3. COM - SEG对应关系你没搞明白 。 学习学习! 如果是这种情况,一般原因是两个屏采用的芯片厂家不同,甚至有可能有个是国产的无锡的驱动,
请在读写和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;
} 好久没有玩过12864屏幕了,来学习一下!谢谢~ 也有遇到过错位的情况,我是用USB烧写的,后来无意中把USB拔掉,单片机复位了下,然后就好了好了。。。。。
页:
[1]