HD44780是应用最广泛的一种字符型LCD控制器,以它为基础开发出了许多字符显示LCD。
51单片机与外设的接口一般分为两种:总线接口方式和GPIO接口方式。这两种方式各有所长。总结接口方式操作方便,操作频率高,但当单片机的频率很高时,由于HD44780的接口频率跟不上而不能使用。此时我们要采用第二种接口方式——GPIO接口,此时的每一个接口信号都可以进行单独操作,因此可以控制信号的频率,从而更好实现信号接口。下面是HD44780与51单片机接口电路图
下面是总线接口电路图:
C语言讲解
GPIO接口方式C程序
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//文件名: LCD.h
//功能: 全局宏定义
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 硬件信号设置
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sbit LCD_EN= P3^5; //LCD使能
sbit LCD_WR= P1^4; //LCD读写
sbit LCD_RS= P1^5; //LCD命令选择
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 显存数组
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char Data[32]; //显存数组
● 写命令子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: WriteLcdCmd
// 功能说明: 向LCD写命令
// 入口参数: 命令值
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WriteLcdCmd( unsigned char lcdcommand )
{
unsigned char temp = 0x80 ;
LCD_WR = 1 ; //读
LCD_RS = 0 ; //指令
while( temp )
{
DelayS() ;
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
temp &= 0x80 ;
}
LCD_WR = 0 ; //写
LCD_RS = 0 ; //指令
P0 = lcdcommand ;
DelayS() ;
LCD_EN = 1 ; //使能
DelayS() ;
LCD_EN = 0 ; //禁能
}
● 读命令子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: ReadLcdCmd
// 功能说明: 从LCD读命令
// 入口参数: 无
// 返回参数: 命令值
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char ReadLcdCmd( void )
{
unsigned char temp = 0x80 ;
LCD_WR = 1 ; //读
LCD_RS = 0 ; //指令
while( temp )
{
DelayS() ;
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
temp &= 0x80 ;
}
LCD_WR = 1 ; //读
LCD_RS = 0 ; /指令
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
return temp ;
}
● 写数据子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: WriteLcdData
// 功能说明: 向LCD写数据
// 入口参数: 数据值
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WriteLcdData( unsigned char lcddata )
{
unsigned char temp = 0x80 ;
LCD_WR = 1 ; //读
LCD_RS = 0 ; //指令
while( temp )
{
DelayS() ;
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
temp &= 0x80 ;
}
LCD_WR = 0 ; //写
LCD_RS = 1 ; //数据
P0 = lcddata ;
DelayS() ;
LCD_EN = 1 ; //使能
DelayS() ;
LCD_EN = 0 ; //禁能
}
● 读数据子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: ReadLcdData
// 功能说明: 从LCD读数据
// 入口参数: 无
// 返回参数: 数据值
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char ReadLcdData( void )
{
unsigned char temp = 0x80 ;
LCD_WR = 1 ; //读
LCD_RS = 0 ; //指令
while( temp )
{
DelayS() ;
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
temp &= 0x80 ;
}
LCD_WR = 1 ; //读
LCD_RS = 1 ; //数据
P0 = 0xFF ;
LCD_EN = 1 ; //使能
DelayS() ;
temp = P0 ;
DelayS() ;
LCD_EN = 0 ; //禁能
return temp ;
}
● 初始化LCD子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: InitialLCD
// 功能说明: 初始化LCd
// 入口参数: 无
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void InitialLCD( void )
{
WriteLcdCmd( 0x38 ) ; //功能设置
WriteLcdCmd( 0x06 ) ; //显示方式
WriteLcdCmd( 0x0c ) ; //显示和光标
WriteLcdCmd( 0x01 ) ; //清屏
}
● 设置LCD显示数据子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: SetLcdData
// 功能说明: 将字符填充到显存中
// 入口参数: 字符数组
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SetLcdData( unsigned char *lcddata )
{
unsigned char i = 0x00 ;
for( i = 0x00 ; i < 0x20 ; i ++ )
{
if( lcddata == '\0' )
break ;
Data = lcddata ; //循环将字符数组写到显存中
}
for( ; i < 0x20 ; i ++ )
Data = ' ' ; //多余的填充空白
}
● 设置LCD显示数据第二行子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: SetLcdDatah
// 功能说明: 将字符填充到显存第二行中
// 入口参数: 字符数组
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SetLcdDatah( unsigned char *lcddata )
{
unsigned char i = 0x00 ;
for( i = 0x00 ; i < 0x10 ; i ++ )
{
if( lcddata == '\0' )
break ;
Data[i + 0x10] = lcddata ; //循环将字符数组写到显存中
}
for( ; i < 0x10 ; i ++ )
Data[i + 0x10] = ' ' ; //多余的填充空白
}
● LCD显示子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: LcdDisplay
// 功能说明: 显示一屏LCd
// 入口参数: 无
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void LcdDisplay( void )
{
unsigned char i ;
ClearWDT() ; //清看门狗
WriteLcdCmd( 0x80 ) ; //第一行
for( i = 0 ; i < 0x10 ; i ++ )
WriteLcdData( Data );
WriteLcdCmd( 0xc0 ) ; //第二行
for( ; i < 0x20 ; i ++ )
WriteLcdData( Data ) ;
}
6.1.5.2 总线接口方式C程序
全局宏定义:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//文件名: LCD.h
//功能: 全局宏定义
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 硬件信号设置
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sfr LCD_CMD_RD = 0x8000;
sfr LCD_CMD_WR = 0x8001;
sfr LCD_DAT_RD = 0x8002;
sfr LCD_DAT_WR = 0x8003;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 显存数组
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char Data[32];
● 写命令子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: WriteLcdCmd
// 功能说明: 向LCD写命令
// 入口参数: 命令值
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WriteoCmmandLCD( unsigned char lcdcommand )
{
unsigned char temp = 0x80 ;
while( temp )
{
DelayS() ;
temp = LCD_CMD_RD ;
temp &= 0x80 ;
}
LCD_CMD_WR = lcdcommand ;
}
● 读命令子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: ReadLcdCmd
// 功能说明: 从LCD读命令
// 入口参数: 无
// 返回参数: 命令值
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char ReadCommandLCD( void )
{
unsigned char temp = 0x80 ;
//temp = LCD_CMD_RD ;
return ( LCD_CMD_RD );
}
● 写数据子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: WriteLcdData
// 功能说明: 向LCD写数据
// 入口参数: 数据值
// 返回参数: 无
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WriteDataLCD( unsigned char lcddata )
{
unsigned char temp = 0x80 ;
while( temp )
{
DelayS() ;
temp = LCD_CMD_RD ;
temp &= 0x80 ;
}
LCD_DAT_WR = lcddata ;
}
● 读数据子程序:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数名: ReadLcdData
// 功能说明: 从LCD读数据
// 入口参数: 无
// 返回参数: 数据值
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned char ReadDataLCD( void )
{
unsigned char temp = 0x80 ;
while( temp )
{
DelayS() ;
temp = LCD_CMD_RD ;
temp &= 0x80 ;
}
return ( LCD_DAT_WR ) ;
} |