,
/*
LCD Driver Program
LCD Module is DFMC1602-02(COB),the same as EDM1602-B(SMT)
Designed by :LiBaizhan
Date:2003-6-12
Version:1.00.00
*/
#include <reg51.h>
#include <intrins.h>
#define _SYS_DEBUG_P0 0
#define TIME_20MS 0X043B
#define LCD_FLAG_DATA 0X01 /*_________________________________________________*/
#define LCD_FLAG_ADDR 0X00 /*| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |*/
#define LCD_FLAG_INST 0X00 /*| X | X | X | X | X | X | X | W_DI|*/
/*| X | X | X | X | X | X | X | R_DA|*/
#define LCD_DISP_CLR 0X01
#define LCD_DISP_ON 0X0C
#define LCD_DISP_OFF 0X08
#define LCD_DISP_CUR 0X0A
#define LCD_DISP_FLASH 0X09
#define LCD_DATA_WIDTH_8 0X30 /*8 bit Bus width */
#define LCD_DATA_WIDTH_4 0X20 /*4 bit Bus width */
#define LCD_DISP_ROW_2 0X28
#define LCD_DISP_ROW_1 0X20
#define LCD_DISP_NOP_CH 0X20
#define LCD_CHAR_NORMAL 0X00
#define LCD_CHAR_CYCLE 0X0F
/*
LCDRS meaning is as folowing:
LCDRS
WR: 1 : Data Register
0 : Instruction Register
RD: 1 : Data Register
0 : Addr Register
*/
sbit LCD_RS = P2^5;
sbit LCD_RW = P2^7;
sbit LCD_ENB = P2^6;
code unsigned char CGRamCh[][8]={
{0X06,0X0F,0X09,0X09,0X09,0X09,0X0F,0X00}, /*NO Battery*/
{0X06,0X0F,0X09,0X09,0X09,0X0F,0X0F,0X00}, /*1 level Battery*/
{0X06,0X0F,0X09,0X09,0X0F,0X0F,0X0F,0X00}, /*2 level Battery*/
{0X06,0X0F,0X09,0X0F,0X0F,0X0F,0X0F,0X00}, /*3 level Battery*/
{0X06,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X00} /*4 level Battery*/
};
code unsigned char DispChar_1[]="I am a boy!";
code unsigned char DispChar_2[]="Today I feel a little tired!";
code unsigned char DispChar_3[]="Tomorrow will be a new day! ^_^";
void DelayMS(unsigned int DlTime);
void DelayS(unsigned char DlTime);
void InitMCU(void);
unsigned char LCDReadByte(unsigned char Flag); /*read one byte from LCD*/
void LCDWriteByte(unsigned char WData,unsigned char Flag); /*Write one byte to LCD*/
/* Position is: */
/* +(0,0)==========>(X:(15,0))*/
void LCDGotoXY(unsigned char x,unsigned char y); /* || */
/* || */
/* \/(Y:(0,1)) */
void LCDInit(void);
void LCDClr(void);
void LCDLoadCGRam(void);
void LCDClrRegn(unsigned char row,unsigned char start_col,unsigned char end_col);
void LCDDispChar(unsigned char x,unsigned char y,unsigned char *ch_buf,unsigned char ch_len);
void LCDDispCharCycle(unsigned char x,unsigned char y,unsigned char *ch_buf,unsigned char ch_len);
void main(void)
{
InitMCU();
while(1)
{
LCDDispCharCycle(3,0,DispChar_2,10);
LCDClrRegn(0,4,10);
LCDDispCharCycle(3,1,DispChar_3,10);
LCDClrRegn(1,4,10);
}
}
void InitMCU(void)
{
LCDInit();
}
unsigned char LCDReadByte(unsigned char Flag)
{
data unsigned char RData = 0;
LCD_ENB = 0; /*Disable LCD Before Read*/
#if _SYS_DEBUG_P0 == 1
P0 = 0XFF; /*Free P0 Port*/
#endif
LCD_RS = Flag&LCD_FLAG_DATA; /*Select Data Reg or Addr_Counter Reg*/
LCD_RW = 1; /*Read Operation*/
LCD_ENB = 1; /*Read Enable,Data will output to Data Bus when this PIN is 1*/
_nop_();
RData = P0; /*Read data on data bus*/
#if _SYS_DEBUG_P0 == 1
P0 = 0XFF; /*Free P0 Port*/
#endif
return RData; /*Reaturn what MCU has Read*/
}
void LCDWriteByte(unsigned char WData,unsigned char Flag)
{
data unsigned char Busy = 0;
do
{
Busy = LCDReadByte(LCD_FLAG_ADDR);
}while(Busy&0X80); /*wait until LCD is not busy*/
LCD_ENB = 0; /*Disable LCD Before Write*/
#if _SYS_DEBUG_P0 == 1
P0 = 0XFF; /*Free P0 Port*/
#endif
LCD_RS = Flag&LCD_FLAG_DATA; /*Select Data Reg or Inst Reg*/
LCD_RW = 0; /*Write operation*/
LCD_ENB = 1; /*Start Write Operation*/
P0 = WData; /*Output Data to Bus*/
LCD_ENB = 0; /*Latch Data to LCD at falling_edge on this PIN*/
#if _SYS_DEBUG_P0 == 1 /*Free P0 Port*/
P0 = 0XFF;
#endif
}
void LCDInit(void)
{
LCDWriteByte(LCD_DATA_WIDTH_8|LCD_DISP_ROW_2,LCD_FLAG_INST); /*2 ROW AND 8 BIT DATA_WIDTHS*/
LCDWriteByte(LCD_DISP_ON,LCD_FLAG_INST); /*Open LCD Display*/
LCDClr();
DelayMS(TIME_20MS);
LCDLoadCGRam();
}
void LCDClr(void)
{
LCDWriteByte(LCD_DISP_CLR,LCD_FLAG_INST); /*Clr LCD Screen*/
}
void LCDGotoXY(unsigned char x,unsigned char y)
{
data unsigned char DDRamAddr=0X80;
x=x&0X0F; /*adjust x,y to suitable position on the LCD screen*/
y=y&0X01;
DDRamAddr+=x;
if(y) /* if write to row_2 then add row_2 offset:0x40*/
DDRamAddr+=0X40;
LCDWriteByte(DDRamAddr,LCD_FLAG_INST);
}
void LCDLoadCGRam(void)
{
data unsigned char i,j;
LCDWriteByte(0X40,LCD_FLAG_INST); /*Write LCD CGRam Control*/
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
LCDWriteByte(CGRamCh[i][j],LCD_FLAG_DATA); /*load my own character to LCD's CGRam*/
}
}
}
void LCDDispChar(unsigned char x,unsigned char y,unsigned char *ch_buf,unsigned char ch_len)
{
data unsigned char i=0;
LCDGotoXY(x,y);
if(ch_len==0) /*just display char*/
{
while(*ch_buf)
{
LCDWriteByte(*ch_buf,LCD_FLAG_DATA);
ch_buf++;
}
}
else
{
for(i=0;i<ch_len;i++)
{
if(ch_buf[i]=='\0')
{
LCDWriteByte(LCD_DISP_NOP_CH,LCD_FLAG_DATA);
break;
}
LCDWriteByte(ch_buf[i],LCD_FLAG_DATA);
}
}
}
void LCDClrRegn(unsigned char row,unsigned char start_col,unsigned char end_col)
{
data unsigned char i;
LCDGotoXY(start_col,row);
for(i=start_col;i<=end_col;i++)
LCDWriteByte(LCD_DISP_NOP_CH,LCD_FLAG_DATA);
}
void LCDDispCharCycle(unsigned char x,unsigned char y,unsigned char *ch_buf,unsigned char disp_len)
{
data unsigned char CharLength=0;
data unsigned char i,start_x=x+disp_len;
while(ch_buf[CharLength++]!='\0'); /*Calculate string length*/
for(i=1;i<disp_len;i++)
{
start_x=(x+disp_len-i); /*here maybe a bug ,wait to modify*/
LCDDispChar(start_x,y,ch_buf,i);
DelayS(20); /*about 35*20MS*/
}
for(i=0;i<CharLength;i++)
{
LCDDispChar(x,y,&ch_buf[i],disp_len);
DelayS(20); /*about 35*20MS*/
}
}
void DelayMS(unsigned int DlTime)
{
data unsigned int i;
for(i=0;i<DlTime;i++);
}
void DelayS(unsigned char DlTime)
{
data unsigned char i;
for(i=0;i<DlTime;i++)
DelayMS(TIME_20MS);
}