/*------------------------------------------------------------------
CharLCD.C (v1.00) 16x2 字符液晶屏驱动程序
------------------------------------------------------------------*/
#include "CharLCD.h"
//Change the following section accroding to you hardware
#ifdef _LCDXADDR
#define Lcd1602WCmdPort (*(volatile uchar *)0x2000) //E=1 RS=0 RW=0
#define Lcd1602RStatusPort (*(volatile uchar *)0x2001) //E=1 RS=0 RW=1
#define Lcd1602WdataPort (*(volatile uchar *)0x2002) //E =1 RS=1 RW=0
#define Lcd1602RDataPort (*(volatile uchar *)0x2003) //E=1 RS=1 RW=1
#else
#ifdef _51
sbit lcd_cs = P2^0; //控制位
sbit lcd_rw = P2^1;
sbit lcd_rs = P2^2;
#define DataPort P0
#define DataDirPort P0
#define StatePort P0
#endif
#ifdef _AVR
#define lcd_cs PORTC.0 //控制位以及其方向控制位
#define lcd_cs_dir_bit DDRC.0
#define lcd_rw PORTC.1
#define lcd_rw_dir_bit DDRC.1
#define lcd_rs PORTC.2
#define lcd_rs_dir_bit DDRC.2
#define DataPort PORTA
#define StatePort PINA
#define DataDirPort DDRA
#endif
#endif
// ------ Private constants ----------------------------------------
#define Busy 0x80 // 忙判别位
// ------ Private variables-----------------------------------------
#ifdef _51
code uchar* WrtieLcdErr = "Display char outof range.";
#endif
#ifdef _AVR
flash uchar* WrtieLcdErr = "Display char outof range.";
#endif
// ------ Private function prototypes ------------------------------
static BOOL WaitTillNotBusy();
static BOOL LocateXY(uchar posx,uchar posy);
static BOOL LcdWData(uchar dataW);
static BOOL LcdWCMD(uchar CMD);
/*------------------------------------------------------------------
WaitTillNotBusy()
检测忙
------------------------------------------------------------------*/
BOOL WaitTillNotBusy()
{
uint delay = 0xffff;
#ifdef _LCDXADDR
while( (Lcd1602RStatusPort & Busy) && delay )
delay--;
if (!delay)
return FALSE;
#else
#ifdef _AVR
DataDirPort = 0x00;
#endif
#ifdef _51
DataDirPort = 0xff;
#endif
lcd_cs = 1;
lcd_rs = 0;
lcd_rw = 1;
while( (StatePort & Busy) && delay)
delay--;
lcd_cs = 0;
if (!delay)
return FALSE ;
#endif
return TRUE;
}
/*------------------------------------------------------------------
LocateXY()
显示光标定位
------------------------------------------------------------------*/
BOOL LocateXY( uchar posx,uchar posy)
{
posy &= 0x01;
if (posy == 1)
posx |= 0x40;
posx |= 0x80;
return LcdWCMD(posx);
}
/*------------------------------------------------------------------
LcdWCMD()
写控制字符子程序: E=1 RS=0 RW=0
------------------------------------------------------------------*/
BOOL LcdWCMD(uchar CMD)
{
#ifdef _LCDXADDR
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
Lcd1602WCmdPort = CMD;
#else
uchar i=1;
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
#ifdef _AVR
DataDirPort = 0xff;
#endif
DataPort = CMD;
lcd_rs = 0;
lcd_rw = 0;
lcd_cs = 1;
while(i++);
lcd_cs = 0;
#endif
return TRUE;
}
/*------------------------------------------------------------------
LcdWData()
当前位置写字符子程序: E =1 RS=1 RW=0
------------------------------------------------------------------*/
BOOL LcdWData( uchar dataW )
{
#ifdef _LCDXADDR
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
Lcd1602WdataPort = dataW;
#else
uchar i = 1;
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
#ifdef _AVR
DataDirPort = 0xff;
#endif
DataPort = dataW;
lcd_rs = 1;
lcd_rw = 0;
lcd_cs = 1;
while(i++);
lcd_cs = 0;
#endif
return TRUE;
}
/*------------------------------------------------------------------
LCDInit()
初始化程序, 必须按照产品资料介绍的初始化过程进行
------------------------------------------------------------------*/
BOOL LCDInit()
{
#ifdef _AVR
#ifndef _LCDXADDR
lcd_cs_dir_bit = 1;
lcd_rw_dir_bit = 1;
lcd_rs_dir_bit = 1;
#endif
#endif
// 显示模式设置,光标移动设置,显示开及光标设置,显示清屏
return (LcdWCMD( 0x38) && LcdWCMD( 0x06) && LcdWCMD( 0x0c) && LcdWCMD( 0x01));
}
/*------------------------------------------------------------------
DisplayOneChar()
按指定位置显示数出一个字符
------------------------------------------------------------------*/
BOOL DisplayOneChar(uchar x ,uchar y ,uchar Wdata)
{
if( (x >= 0 && x < 16) && (y >= 0 && y < 2) )
return (LocateXY( x, y ) && LcdWData( Wdata )) ;// 定位显示地址,写字符
else
return ( LCDInit() && DisplayString(0, 0, WrtieLcdErr)); //显示越界消息
}
/*------------------------------------------------------------------
DisplayString()
从指定位置开始显示一串字符
------------------------------------------------------------------*/
BOOL DisplayString(uchar posx, uchar posy, flash uchar* str)
{
while ( (*str) != '\0' )
{
if (!DisplayOneChar(posx, posy, (*str)))
return FALSE;
str++;
posx++;
if( posx == 16 )
{
posx = 0;
posy++;
}
}
return TRUE;
}
/*------------------------------------------------------------------
---- END OF FILE -------------------------------------------------
------------------------------------------------------------------*/