|
/*************************************************
* File: Lcd.C
* Function: Lcd1602驱动
**************************************************/
#i nclude <p18f452.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define LCD_EN PORTAbits.RA1
#define LCD_RW PORTAbits.RA2
#define LCD_CD PORTAbits.RA3
#define LCD_DATA_BUS PORTD // 数据总线,只用到RD0~RD3
#define ON 1
#define OFF 0
#define W 0
#define R 1
#define C 0
#define D 1
void Ini_Lcd( void); // Lcd初使化
void ChkBusy( void); // 忙检测
uint8 Rcmd( void ); // 读指令寄存器
void Wcmd( uint8 command ); // 写指令寄存器
void Wdata( uint8 lcddata); // 写数据寄存器
void SetXY( uint8 X ,uint8 Y ); // 设置显示坐标
void Wchar( uint8 x ,uint8 y ,uint8 data ); // 显示一个字符
void Wstring( uint8 x ,uint8 y ,uint8 *data ); // 显示一串字符
/***************** 写指令寄存器*******************/
void Wcmd( uint8 command )
{
LCD_RW = W; // 写
LCD_CD = C; // 指令
LCD_EN = ON;
LCD_DATA_BUS = ( command & 0xf0 )>> 4; // 传送高4位
Nop();
Nop();
LCD_EN = OFF; // 产生下降沿,写时序
LCD_EN = ON;
LCD_DATA_BUS = ( command & 0x0f ); // 传送低4位
Nop();
Nop();
LCD_EN = OFF; // 产生下降沿,写时序
}
/***************** 写数据寄存器********************/
void Wdata( uint8 lcddata)
{
LCD_RW = W; // 写
LCD_CD = D; // 数据
LCD_EN = ON;
LCD_DATA_BUS = ( lcddata & 0xf0 )>> 4; // 传送高4位
Nop();
Nop();
LCD_EN = OFF; // 产生下降沿,写时序
LCD_EN = ON;
LCD_DATA_BUS = ( lcddata & 0x0f ); // 传送低4位
Nop();
Nop();
LCD_EN = OFF; // 产生下降沿,写时序
}
/**************** 读指令寄存器 *******************/
uint8 Rcmd( void )
{
uint8 tempH , tempL;
LCD_EN = OFF;
TRISD |= 0x0f; // RD口设为输入口
LCD_RW = R; // 读
LCD_CD = C; // 指令寄存器
LCD_EN = ON;
tempH = LCD_DATA_BUS; // 读数据总线
LCD_EN = OFF;
Nop();
Nop();
LCD_EN = ON;
tempL = LCD_DATA_BUS; // 读AC值
LCD_EN = OFF;
tempH = ( tempH << 4 )|( tempL & 0x0f );
TRISD &= 0xf0; // RD口设为输出口
return (tempH); // 返回读到的8位值
}
/**************** 忙状态检测***********************/
void ChkBusy( void)
{
while( ( Rcmd() & 0x80 ) == 1);
}
/*****************************************************
* NAME: SetXY( uint8 X ,uint8 Y )
* 功能: 设置显示坐标
******************************************************/
void SetXY( uint8 X ,uint8 Y )
{
uint8 temp;
if ( Y == 0 )temp = X + 0x80;
else
temp = X + 0xc0;
Wcmd( temp);
ChkBusy();
}
/******************************************************
* NAME:Wstring( uint8 x ,uint8 y ,uint8 *data )
* 功能:在指定位置起显示字符串
*******************************************************/
void Wstring( uint8 x ,uint8 y ,uint8 *data )
{
SetXY(x,y); // 设置显示坐标
while(*data)
{
Wdata( *data);
data++;
delay5ms();
}
}
/*******************************************************
* NAME:Wchar( uint8 x ,uint8 y ,uint8 data )
* 功能:在指定位置显示一个字符
********************************************************/
void Wchar( uint8 x ,uint8 y ,uint8 data )
{
SetXY(x,y); // 显示定位
Wdata( data); // 写数据
delay5ms();
}
/*******************************************************
* NAME: Ini_Lcd( void)
* 功能:LCD初使化
********************************************************/
void Ini_Lcd( void)
{
TRISA &= 0xf1; // RA3~RA1设为输出
TRISD &= 0xf0; // RD3~RD0设为输出
ADCON1 = 0b00001110;// 除RA0外,关闭RA口引脚模拟功能
Wcmd(0x30) ; // 前三次写 0x30 不检测忙状态
delay5ms() ;
delay5ms() ;
delay5ms() ; // 延时15ms,切记否则会初使化不成功
Wcmd(0x30) ;
delay5ms() ;
Wcmd(0x30) ;
delay5ms() ;
Wcmd(0x20) ; // 显示模式设置:4位总线,2行显示,5*10点阵
ChkBusy();
Wcmd(0x28) ;
Wcmd(0x01) ; // 显示清屏
Wcmd(0x06) ; // 显示光标移动设置:光标右移
Wcmd(0x0d) ; // 开显示:开显示,开光标,光标闪烁
Wcmd(0x80) ; // 清DDRAM
} |
|