网上有很多关于玩转12864液晶屏(ST7920)的相关页面,我看了之后,调试了很久。结果发现我的学习板上由于LCD的数据库程序上与实际连接上相反,就会有一个Convert函数,使实际和程序相符合。正是由于这个,使我调试了老久,结果我换了一个学习板就可以了。不过,有弊有利,看了老久,就对程序有了一些理解。在他的程序上加了一点注释。
void v_Lcd12864CheckBusy_f( void ) //忙检测函数
{
unsigned int nTimeOut = 0;
io_LCD12864_DATAPORT = Convert(0x80) ;//P0=0x80
SET_READ //io_LCD12864_RW= 1,读
SET_INC //io_LCD12864_RS=0,指令
CLR_EN //io_LCD12864_EN=0,
SET_EN //io_LCD12864_EN=1,使能
while((io_LCD12864_DATAPORT==0x80)&&(++nTimeOut!=0));
//在P0==0x80时,等待
CLR_EN //io_LCD12864_EN=0,
}
unsigned char u8_Lcd12864ReadByte_f( void )
{
unsigned char byReturnValue ;
v_Lcd12864CheckBusy_f();
io_LCD12864_DATAPORT = Convert(0xff) ;//P0=0xff
SET_DATA //RS=1,指令
SET_READ //RW=1,读
CLR_EN //EN=0
SET_EN //EN=1
byReturnValue = io_LCD12864_DATAPORT ;//byReturnValue=P0
CLR_EN //EN=0;
return byReturnValue;
}
void v_Lcd12864DrawPoint_f( unsigned char X,
unsigned char Y, unsigned char Color )
{
unsigned char Row,Tier,Tier_bit;
//Tier_bit的作用:确定该位置是低八位,还是高八位
unsigned char ReadOldH, ReadOldL ;
v_Lcd12864SendCmd_f( 0x34 ) ; //使用扩充指令集
v_Lcd12864SendCmd_f( 0x36 ) ; //使用扩充指令集,图像显示开。
Tier = X >> 4 ;
//X的范围是0-127,即0x7f.Tier 除以16,获取它的字。
//12864LCD只能定位地址时,只能定位到字。
//63,即00111111B,Tier:0011B,3
Tier_bit = X & 0x0f;
//Tier_bit:1111B,15
//Tier_bit,取它的低四位。
if( Y < 32 )
{
Row = Y ;
}
else
{
Row = Y - 32 ; //Row:0
Tier += 8 ; //Tier:处于下半屏幕
}
v_Lcd12864SendCmd_f( Row + 0x80 ) ;
v_Lcd12864SendCmd_f( Tier + 0x80 ) ;
u8_Lcd12864ReadByte_f() ;
ReadOldH = u8_Lcd12864ReadByte_f() ;
//获取以前这个位置(16*16的显示屏)上的数据
ReadOldL = u8_Lcd12864ReadByte_f() ;
v_Lcd12864SendCmd_f(Row+0x80);
v_Lcd12864SendCmd_f(Tier+0x80);
if(Tier_bit<8) //Tier_bit=15
{
switch( Color)
{
case 0 : ReadOldH &=( ~( 0x01 << ( 7 - Tier_bit ))) ; break ;
case 1 :
ReadOldH |= ( 0x01 << ( 7 - Tier_bit )) ;
break ;
case 2 : ReadOldH ^= ( 0x01 << ( 7 - Tier_bit )) ; break ;
default : break ;
}
v_Lcd12864SendData_f( ReadOldH ) ;
v_Lcd12864SendData_f( ReadOldL ) ;
}
else
{
switch(Color)
{
case 0 :
ReadOldL&=(~(0x01<< ( 15 - Tier_bit ))) ;
//ReadOldL&=0xfe;最低位置0,其余位不变。
break ;
case 1 :
ReadOldL|=( 0x01 << ( 15 - Tier_bit ));
//ReadOldL|=0x01;=>最低位置1,其余位不变
//若ReadOldL&=0x01;=>最低位置1,其余位置0
break ;
case 2 : ReadOldL ^= ( 0x01 << ( 15 - Tier_bit )) ; break ;
default : break ;
}
v_Lcd12864SendData_f( ReadOldH ) ;
v_Lcd12864SendData_f( ReadOldL ) ;
}
v_Lcd12864SendCmd_f( 0x30 ) ;
}