📄 lcd1602drv.c
字号:
/********************************************************************************************************
** 1602字符型液晶显示驱动程序
**
** 版权所有 (c) 2007,罗建
** 保留所有权利
**
** V1.00
**
**
**-------------------------------------------------文件信息----------------------------------------------
**文 件 名: LCD1602Drv.C
**创 建 人: 罗建
**最后修改日期: 2007年07月29日
**描 述: 1602字符型液晶显示驱动程序的源程序。
**其 它:本单元驱动程序以STC12C5408AD作为MCU,外部晶振为11.0592MHz,采用OCM2X16A LCD显示屏显示数据。
** 如果换用其它MCU或其它晶振,则应修改以下两处代码:
** 1)LCD显示屏操作位定义,即LCM_RW等的定义;
** 2)WaitLCD()方法中的代码,系统时钟越快,_nop_()方法调用也应多些。
** 另外,如果上电后LCD不能正常显示,可以增加LCDInit()方法中WriteCmdToLCD(0x38, FALSE);方法的
** 调用次数。
**
**-----------------------------------------------历史版本信息--------------------------------------------
** 创建人: 罗建
** 版 本: V1.00
** 日 期: 2007年07月29日
** 描 述: 原始版本
**
**-----------------------------------------------当前版本修订--------------------------------------------
** 修改人: 罗建
** 版 本: V1.00
** 日 期: 2007年07月29日
** 描 述: 原始版本。
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <Intrins.h>
#include "MiscUnit.h"
#include "LCD1602Drv.h"
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: WaitLCD
** 功能描述: 延时一段时间,以满足LCD的读写时序。
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: 无
** 其它说明:函数中_nop_()方法的调用次数与单片机的时钟周期和LCD的读写时序有关,不同的LCD有不同的读写时间要
** 求,可以查询相关的数据手册。
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void WaitLCD(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: CheckLCDBusy
** 功能描述: 检查并等待LCD显示屏进入空闲状态。
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void CheckLCDBusy(void)
{
LCM_DATA = 0xFF; // 选择命令寄存器
LCM_RS = 0; // 选择命令寄存器
LCM_RW = 1; // 执行读操作
WaitLCD(); // 等待地址设置时间到(>140ns,这里取约1us)
LCM_E = 1; // 开始读操作
WaitLCD(); // 等待数据延迟时间到(<320ns,这里取约1us)
while (LCM_DATA & BUSY); // 检查忙标志
LCM_E = 0; // 停止读操作
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: WriteCmdToLCD
** 功能描述: 向LCD显示屏写入命令。
** 输 入: nCmd>>>>>>>>>>>>>>>要写入LCD的命令,参见OCM2X16A模块支持的命令;
** bCheckBusy>>>>>>>>>指示是否检查LCD要忙标志。
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void WriteCmdToLCD(INT8U nCmd, bit bCheckBusy)
{
if (bCheckBusy) // 判断是否需要检查忙标志
CheckLCDBusy();
LCM_RS = 0; // 选择命令寄存器
LCM_RW = 0; // 执行写操作
LCM_DATA = nCmd; // 准备要写的指令
WaitLCD(); // 等待地址设置时间到(>140ns,这里取约1us)
LCM_E = 1; // 准备写操作
WaitLCD(); // 等待数据设置时间到(<320ns,这里取约1us)
LCM_E = 0; // 开始写操作
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: WriteDataToLCD
** 功能描述: 向LCD显示屏写入数据。
** 输 入: nData>>>>>>>>>>>>>>要写入LCD的数据,参见OCM2X16A模块支持的命令;
** bCheckBusy>>>>>>>>>指示是否检查LCD要忙标志。
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void WriteDataToLCD(INT8U nData, bit bCheckBusy)
{
if (bCheckBusy) // 判断是否需要检查忙标志
CheckLCDBusy();
LCM_RS = 1; // 选择数据寄存器
LCM_RW = 0; // 执行写操作
LCM_DATA = nData; // 准备要写的数据
WaitLCD(); // 等待地址设置时间到(>140ns,这里取约1us)
LCM_E = 1; // 准备写操作
WaitLCD(); // 等待数据设置时间到(<320ns,这里取约1us)
LCM_E = 0; // 开始写操作
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: ReadDataFromLCD
** 功能描述: 从LCD显示屏中读取数据。
** 输 入: 无
** 输 出: nData>>>>>>>>>>>>>>从LCD显示屏中读取的数据,参见OCM2X16A模块支持的命令;
** bCheckBusy>>>>>>>>>指示是否检查LCD要忙标志。
** 全局变量: 无
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/*
void ReadDataFromLCD(INT8U* nData, bit bCheckBusy)
{
if (bCheckBusy) // 判断是否需要检查忙标志
CheckLCDBusy();
LCM_RS = 1; // 选择数据寄存器
LCM_RW = 1; // 执行读操作
WaitLCD();
LCM_E = 1; // 若晶振速度太高可以在这后加小的延时
WaitLCD();
*nData = LCM_DATA; // 返回读取的数据
LCM_E = 0; // 使能液晶模块执行命令
}
*/
void LCDInit(void)
{
WriteCmdToLCD(0x38, FALSE); // 连续3次功能设置(不检查忙标志)
WriteCmdToLCD(0x38, FALSE);
WriteCmdToLCD(0x38, FALSE);
WriteCmdToLCD(0x01, TRUE); // 清显示
WriteCmdToLCD(0x06, TRUE); // 输入方式设置:AC自动加1
WriteCmdToLCD(0x0C, TRUE); // 开显示
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DisplayOneChar
** 功能描述: 在LCD屏的指定位置处显示一个字符。
** 输 入: nX>>>>>>>>>>>>>>>>>LCD屏的列坐标,取值范围为0~15;
** nY>>>>>>>>>>>>>>>>>LCD屏的行坐标,取值范围为0~1;
** nData>>>>>>>>>>>>>>要在LCD屏上显示的字符。
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: WriteCmdToLCM()>>>>向LCD显示屏写入命令;
** WriteDataToLCM()>>>向LCD显示屏写入数据。
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DisplayOneChar(INT8U nX, INT8U nY, INT8U nData)
{
nX = nX & 0x0F; // 一行最多显示16个字符
if (nY) nX |= 0x40; // 当要显示第二行时地址码+0x40;
nX |= 0x80; // 加上0x80以算出指令码
WriteCmdToLCD(nX, TRUE); // 先发送地址码
WriteDataToLCD(nData, TRUE); // 后发送数据
}
//
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DisplayListChar
** 功能描述: 在LCD显示屏的指定位置处显示一串字符。
** 输 入: nX>>>>>>>>>>>>>>>>>LCD屏的列坐标,取值范围为0~15;
** nY>>>>>>>>>>>>>>>>>LCD屏的行坐标,取值范围为0~1;
** nLen>>>>>>>>>>>>>>>要显示的字符串的长度;
** nData[]>>>>>>>>>>>>要在LCD屏上显示的字符串。
** 输 出: 无
** 全局变量: 无
** 全局常量:无
** 调用模块: DisplayOneChar()>>>在LCD屏的指定位置处显示一个字符。
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DisplayListChar(INT8U nX, INT8U nY, INT8U nLen, INT8U *nData)
{
INT8U i;
for (i=0;i<nLen;i++) // 若到达字串尾则退出
{
DisplayOneChar(nX, nY, nData[i]); // 显示单个字符
nX++; // 移向下一个要显示的字符位置
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -