📄 lcd_hd44780.c
字号:
/**************************************************************************************************
* 文件信息 : LCD驱动
* 文 件 名 : HD44780_LCD.C
* 创 建 人 : 谢志俊
* 创建日期 : 2006-4-8
* 原始版本 : V 1.0.0
* 说 明 :
* 修改版本 :
* 修改日期 :
* 说 明 :
* 描 述 : 源代码
* (c) Copyright 2004-2006, HNCSXZJ
* All Rights Reserved
**************************************************************************************************/
/**************************************************************************************************
* 简介
*
* 本模块仅使用于字符显示液晶模块
*
* 当前版本的驱动仅支持以下类型LCD模块驱动:
* Hitachi HD44780 或与之兼容的芯片.
*
* LCD显示函数支持以下格式:
* 1 line x 16 characters 2 lines x 16 characters 4 lines x 16 characters
* 1 line x 20 characters 2 lines x 20 characters 4 lines x 20 characters
* 1 line x 24 characters 2 lines x 24 characters
* 1 line x 40 characters 2 lines x 40 characters
*说明:
* 1 line x 16 characters 需要定义为2*8的液晶模块
*
* 不支持外部内存模式
**************************************************************************************************/
/**************************************************************************************************
* INCLUDE FILES
**************************************************************************************************/
#define LCD_HD44780_GLOBALS
#include "..\includes.h"
/**************************************************************************************************
* 局部常数
**************************************************************************************************/
/**************************************************************************************************
* 局部变量
**************************************************************************************************/
static INT8U D_lcd_x; // 实时X座标
static INT8U D_lcd_y; // 实时Y座标
static INT8U D_base_y[4] = {
HD44780_DISP_SET_ADDR_DDRAM,
HD44780_DISP_SET_ADDR_DDRAM + 0x40,//第二行首地址为0x40
_lcd_MaxRows+ HD44780_DISP_SET_ADDR_DDRAM,
_lcd_MaxRows+ HD44780_DISP_SET_ADDR_DDRAM + 0x40
};
/**************************************************************************************************
* 局部函数
**************************************************************************************************/
static void HD44780_Data_PORT_Wr (INT8U Data);
static INT8U HD44780_Data_PORT_Rd (void);
void LCD_init(void)
{
INT8U i=3;
CLRBIT(HD44780_RS_PORT, HD44780_RS); // 初始控制端口
CLRBIT(HD44780_RW_PORT, HD44780_RW);
CLRBIT(HD44780_E_PORT, HD44780_E);
SETBIT(HD44780_RS_DDR, HD44780_RS);
SETBIT(HD44780_RW_DDR, HD44780_RW);
SETBIT(HD44780_E_DDR, HD44780_E);
Tdelay_nms(15);
do{
#if (HD44780_COMM_PORT == HD44780_8_Bits_SRAM)
//HD44780_Cmd_W_Add = HD44780_DISP_MODE_BIT_8; // 显示模式设置(不检测忙信号)
#else
HD44780_Data_PORT_Wr(HD44780_DISP_MODE_BIT_8); // 显示模式设置(不检测忙信号)
#endif
Tdelay_nms(5);
}while(--i);
HD44780_Write_Cmd(HD44780_DISP_MODE_BIT); // 显示模式设置
Tdelay_nms(5);
HD44780_Write_Cmd(HD44780_MODE_SET); // 显示模式设置
HD44780_Write_Cmd(HD44780_DISP_CURSOR_INC); // 显示光标移动设置
LCD_clear(); // 显示清屏
}
/**************************************************************************************************
* 功 能 : LCD 清屏
* 入 口 :
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_clear(void)
{
HD44780_Write_Cmd(HD44780_DISP_ON); // 显示开
HD44780_Write_Cmd(HD44780_DISP_CMD_CLS); // LCD 清屏,光标返回(0,0)位置。
D_lcd_x=D_lcd_y=0;
}
/**************************************************************************************************
* 功 能 : 显示、光标回原位
* 入 口 :
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_home(void)
{
HD44780_Write_Cmd(HD44780_DISP_CMD_HOME); //
D_lcd_x=D_lcd_y=0;
}
/**************************************************************************************************
* 功 能 : 把 LCD 当前显示位置调整到 x 列 y 行。x, y 值由 0 开始。
* 入 口 : '显示字符串的位置,X:0-15,Y:0-1
* LCD第一行显示寄存器地址:0X80-0X8F
* LCD第一行显示寄存器地址:0XC0-0XCF
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_gotoxy(INT8U x, INT8U y)
{
if(y>=_lcd_MaxCols)
{
y = 0;
}
if(x>=_lcd_MaxRows)
{
x = 0;
}
HD44780_Write_Cmd( D_base_y[y]+x);
D_lcd_x=x;
D_lcd_y=y;
}
/**************************************************************************************************
* 功 能 : 向 LCD 输出一个字符,并在当前显示位置显示该字符
* 入 口 :
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_putchar(char c)
{
if (D_lcd_x >= _lcd_MaxRows)
{
++D_lcd_y;
LCD_gotoxy(0,D_lcd_y);
}
HD44780_Write_Data(c);
++D_lcd_x;
}
/**************************************************************************************************
* 功 能 : 向 LCD 输出一个字符串,并在当前显示位置显示该字符串。str 位于 RAM 空间。
* 入 口 :
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_puts(INT8U *str)
{
while (*str){
LCD_putchar( *str );
str ++;
}
}
/**************************************************************************************************
* 功 能 : 向 LCD 输出一个字符串,并在当前显示位置显示该字符串。
* progmem_s 位于 程序存储区FLASH 空间。
* 入 口 :
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
void LCD_puts_p(const prog_char *progmem_s)
{
register char c;
while ((c = pgm_read_byte(progmem_s++))) {
LCD_putchar(c);
}
}
/**************************************************************************************************
* 功 能 : 从 LCD 字符发生器读取一个字符
* 入 口 : addr LCD 字符发生器地址
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
#if (EN_LCD_CGRAM_read_byte > 0)
INT8U LCD_CGRAM_read_byte(INT8U addr)
{
HD44780_Write_Cmd( HD44780_DISP_SET_ADDR_CGRAM + addr); // 设置CGRAM地址
return (HD44780_Read_Data());
}
#endif
/**************************************************************************************************
* 功 能 : 向 LCD 字符发生器写入一个字节。
* 入 口 : addr LCD 字符发生器地址
* Data 要写入的一个字节
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
#if (EN_LCD_CGRAM_write_byte > 0)
void LCD_CGRAM_write_byte(INT8U addr, INT8U Data)
{
HD44780_Write_Cmd( HD44780_DISP_SET_ADDR_CGRAM + addr); // 设置CGRAM地址
HD44780_Write_Data(Data);
}
#endif
/**************************************************************************************************
* 功 能 : 把自定义字型图样数据 cchr 写入 CGRAM 中第 index 个自定义字符
* 入 口 : index CGRAM 中自定义字符序号, 0..7
* cchr 自定义字型图样数据的结构变量 LCC 的指针。
* 返 回 : 无
* 说 明 :
**************************************************************************************************/
#if (EN_LCD_set_custom_char > 0)
void LCD_set_custom_char(INT8U index, LCC *cchr)
{
INT8U i;
HD44780_Write_Cmd( HD44780_DISP_SET_ADDR_CGRAM | (index * 8)); // 设置CGRAM地址
for(i = 0;i < 8 ;i++){
HD44780_Write_Data(cchr->cgram[i]);
}
HD44780_Write_Cmd( D_base_y[D_lcd_y]+D_lcd_x);
}
#endif
/**************************************************************************************************
* 硬件相关驱动函数集
**************************************************************************************************/
/**************************************************************************************************
* 功 能 : 向LCD命令寄存器写命令
* 入 口 : 'Cmd' 是当前要写入的命令数据
* 返 回 : 无
* 说 明 :1> 如果送到数据端口的数据跟实际需要送出的数据不一样 表示LCM可能出问题或着有共享的I/O被利
* 用了,则需要等待其他的释放共享的I/O 来保证数据的正确性
**************************************************************************************************/
void HD44780_Write_Cmd (INT8U Cmd)
{
HD44780_Read_Cmd(); // 等待LCD空闲
#if (HD44780_COMM_PORT == HD44780_8_Bits_SRAM)
// HD44780_Cmd_W_Add = Cmd;
#else
HD44780_Cmd_Mode(); // 选择命令寄存器
HD44780_Wr_Mode (); // 选择写状态
HD44780_Data_PORT_Wr(Cmd); // 向LCD数据端口写数据
#endif
}
/**************************************************************************************************
* 功 能 : 向LCM数据寄存器写一字节数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -