|
RD_LCD1602b.c
/***********************************************************
* 函数库说明:LCD1602B基本驱动函数库 *
* 版本: v2.11 *
* 作者: 傻孩子 *
* 创建日期: 2005年9月6日 *
* -------------------------------------------------------- *
* [支 持 库] *
* -------------------------------------------------------- *
* [版本更新] *
* 修改: 傻孩子 *
* 修改日期: 2006年6月8日 *
* 版本: v2.11 *
* -------------------------------------------------------- *
* [版本历史] *
* -------------------------------------------------------- *
* [使用说明] *
* 1、需要底层硬件驱动函数支持 *
* 基本的宏定义: *
* LCD_RS LCD_RW LCD_E *
* LCD_SET_WRITE_DATA LCD_SET_READ_DATA *
* LCD_SEND_HALF_CHAR_HIGH(a) *
* LCD_SEND_HALF_CHAR_LOW(a) *
* 当处于串行状态下时,只定义LCD_RS *
* LCD_E LCD_SEND_HALF_CHAR_HIGH(a) *
* LCD_SEND_HALF_CHAR_LOW(a) *
* 2、如果采用8数据位连接,则需要定义数据端口 *
* LCD_DATA_PORT,同时需要定义宏来开启该功 *
* 能:_LCD1602_FULL_DATA_MODEL *
* 3、需要修改引用宏定义来指定底层硬件驱动 *
* 函数库。 *
* 4、本库驱动下的LCD显示支持1602的各种连 *
* 接方法。当使用只写模式是请在引用该头 *
* 文件之前加上宏定义: *
* # define _USE_LCD_ONLY_WRITE *
* 5、在调用本库之前,定义RunStringSpeed可 *
* 以设置滚屏的速度。通过在引用前定义 *
* FlashTimeOut 和 FlashGIFTimeOut 可以 *
* 改变字符闪烁的频率。 *
* 6、增加一个GIF字幕特效函数。 *
* 7、确定没有LCD复位问题。 *
* 8、增加对595串行转并行连接的支持。 *
* 需要头文件SerialToCollateral.h *
***********************************************************/
/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"
# include "LIB_Config.h"
# include "RD_LCD1602B.h"
/********************
* 系 统 宏 定 义 *
********************/
/*------------------*
* 常 数 宏 定 义 *
*------------------*/
# define LCD_CMD_DISP_CTR 0x0c
# define LCD_CMD_CLS 0x01
# define LCD_CMD_ENTER_SET 0x02
# define LCD_CMD_ICON_SHOW 0x0f
# define LCD_CMD_ICON_HIDE 0x0c
# define LCD_CMD_NOT_MOVE 0x14
# define LCD_WRITE 0x00
# define LCD_READ 0x01
# define LCD_COMMAND 0x00
# define LCD_DATA 0x01
#ifndef LCD_RUN_STRING_SPEED
# define LCD_RUN_STRING_SPEED 100
#endif
#ifndef LCD_FLASH_TIME_OUT
# define LCD_FLASH_TIME_OUT 0x03ff
#endif
#ifndef LCD_FLASH_STRING_GROUP_TIME_OUT
# define LCD_FLASH_STRING_GROUP_TIME_OUT 0x03ff
#endif
/*------------------*
* 动 作 宏 定 义 *
*------------------*/
#if defined(_USE_LCD_ONLY_WRITE) || defined(_Use_LCD1602B_Serial)
#ifndef LCD_SET_WRITE_DATA
# define LCD_SET_WRITE_DATA
#endif
#ifndef LCD_SET_READ_DATA
# define LCD_SET_READ_DATA
#endif
#ifndef LCD_RW
# define LCD_RW LCD_Temp
#endif
#ifndef LCD_BF
# define LCD_BF LCD_Temp
#endif
#else
#ifndef LCD_SET_WRITE_DATA
# error No define LCD_SET_WRITE_DATA
#endif
#ifndef LCD_SET_READ_DATA
# error No define LCD_SET_READ_DATA
#endif
#ifndef LCD_RW
# error No define LCD_RW
#endif
#ifndef LCD_BF
# error No define LCD_BF
#endif
#endif
#ifndef LCD_RS
# error Need define LCD_RS
#endif
#ifndef _Use_LCD1602B_Serial
# define SetReadState LCD_SET_READ_DATA;LCD_RS = LCD_COMMAND;LCD_RW = LCD_READ;
# define SetRead LCD_SET_READ_DATA;LCD_RW = LCD_READ;
# define SetWrite LCD_SET_WRITE_DATA;LCD_RW = LCD_WRITE;
# define SetCommand LCD_RS = LCD_COMMAND;
# define SetData LCD_RS = LCD_DATA;
#else
# define _USE_LCD_ONLY_WRITE
# define SetReadState
# define SetRead
# define SetWrite
# define SetCommand LCD_RS = LCD_COMMAND;refreshVirtualPORT();
# define SetData LCD_RS = LCD_DATA;refreshVirtualPORT();
# define SetEnable LCD_E = High;refreshVirtualPORT();
# define SetDisable LCD_E = Low;refreshVirtualPORT();
#endif
#ifdef _LCD1602_FULL_DATA_MODEL
#ifndef LCD_DATA_PORT
#error Need for macro: LCD_DATA_PORT
#endif
#endif
/********************
* 用户变量类型定义 *
********************/
/********************
* 模块结构体定义区 *
********************/
/********************
* 模块函数声明区 *
********************/
static void LCDDelay(UINT16 Time);
static void LCDDelayUs(UINT16 Time);
/********************
* 全局函数声明区 *
********************/
void LCDInit(void);
void LCDSetXY(UINT8 X,UINT8 Y);
void LCDDisplayString(UINT8 *String);
void LCDDisplayNum(unsigned long Num,UINT8 BitCount);
void RunString(UINT8 *String,UINT8 Y,UINT8 StartX,UINT8 EndX);
UINT8 StringLength(UINT8 *String);
void Flash(UINT8 *String,UINT8 Icon,UINT8 X,UINT8 Y);
void FlashStringGroup(UINT8 String[][17],UINT8 StringCounter,UINT8 X,UINT8 Y);
void LCDWaitForReady(void);
void LCDSendCommand(UINT8 Command);
void LCDSendData(UINT8 Data);
void PrintD(INT32 nNumber,UINT8 chCounter);
/********************
* 全局函数引用区 *
********************/
#ifdef _Use_LCD1602B_Serial
extern void refreshVirtualPORT(void);
#endif
/********************
* 模块变量声明区 *
********************/
const static UINT8 CHR[16] = {'0','1','2','3','4','5','6','7','8'
,'9','a','b','c','d','e','f'};
/********************
* 全局变量声明区 *
********************/
static UINT8 LCD_Temp = 0;
/********************
* 全局变量引用区 *
********************/
#ifndef SYS_TIMER_MS_ADD_UNTILL_OVF
extern UINT16 g_wSystemTimer;
#define SYS_TIMER_MS_ADD_UNTILL_OVF g_wSystemTimer
#else
extern UINT16 SYS_TIMER_MS_ADD_UNTILL_OVF;
#endif
/***********************************************************
* 函数说明:LCD驱动类毫秒延时函数 *
* 输入: 需要延时的大体毫秒数 *
* 输出: 无 *
* 调用函数:LCDDelayUs() *
***********************************************************/
static void LCDDelay(UINT16 Time)
{
UINT16 TimeCounter = 0;
for (TimeCounter = 0;TimeCounter < Time;TimeCounter ++)
{
LCDDelayUs(255);
}
}
/***********************************************************
* 函数说明:LCD驱动指令周期延时函数 *
* 输入: 需要大体延时Us数 *
* 输出: 无 *
* 调用函数:无 *
***********************************************************/
static void LCDDelayUs(UINT16 Time)
{
UINT16 TimeCounter = 0;
for (TimeCounter = 0;TimeCounter < Time;TimeCounter ++)
{
asm("nop");
}
}
/***********************************************************
* 函数说明:LCD初始化函数 *
* 输入: 无 *
* 输出: 无 *
* 调用函数:LCDDelay() LCDWaitForReady() *
* LCDSendCommand() *
***********************************************************/
void LCDInit(void)
{
LCDDelay(15);
#ifndef _LCD1602_FULL_DATA_MODEL
LCDSendCommand(0x28);
#else
LCDSendCommand(0x38);
#endif
//LCDWaitForReady();
LCDDelay(100);
LCDSendCommand(LCD_CMD_DISP_CTR);
LCDDelay(100);
LCDSendCommand(LCD_CMD_CLS);
LCDDelay(100);
LCDSendCommand(LCD_CMD_ENTER_SET);
LCDDelay(100);
LCDSendCommand(LCD_CMD_NOT_MOVE);
}
#ifndef _Use_LCD1602B_Serial
/***********************************************************
* 函数说明:向LCD发送指令函数 *
* 输入: 需要发送的指令 *
* 输出: 无 *
* 调用函数:LCD_SEND_HALF_CHAR_HIGH() LCD_SEND_HALF_CHAR_LOW() *
***********************************************************/
void LCDSendCommand(UINT8 Command)
{
SetWrite;
SetCommand;
#ifndef _LCD1602_FULL_DATA_MODEL
{
LCD_SEND_HALF_CHAR_HIGH(Command);
LCD_E = HIGH;
LCD_E = LOW;
}
{
LCD_SEND_HALF_CHAR_LOW(Command);
LCD_E = HIGH;
LCD_E = LOW;
}
#else
LCD_DATA_PORT = Command;
LCD_E = HIGH;
LCD_E = LOW;
#endif
SetRead;
SetCommand;
}
/***********************************************************
* 函数说明:向LCD发送数据函数 *
* 输入: 需要发送的数据 *
* 输出: 无 *
* 调用函数:LCD_SEND_HALF_CHAR_HIGH() LCD_SEND_HALF_CHAR_LOW() *
***********************************************************/
void LCDSendData(UINT8 Data)
{
SetWrite;
SetData;
#ifndef _LCD1602_FULL_DATA_MODEL
{
LCD_SEND_HALF_CHAR_HIGH(Data);
LCD_E = HIGH;
LCD_E = LOW;
}
{
LCD_SEND_HALF_CHAR_LOW(Data);
LCD_E = HIGH;
LCD_E = LOW;
}
#else
LCD_DATA_PORT = Data;
LCD_E = HIGH;
LCD_E = LOW;
#endif
SetRead;
SetCommand;
}
/***********************************************************
* 函数说明:等待LCD空闲状态函数 *
* 输入: 无 *
* 输出: 无 *
* 调用函数:LCDDelayUs() *
***********************************************************/
void LCDWaitForReady(void)
{
#ifdef _USE_LCD_ONLY_WRITE
LCDDelayUs(500);
#else
SetRead;
SetCommand;
LCD_E = HIGH;
while (LCD_BF == 1); //RW=1,读PD7,为0表示空闲;
LCD_E = LOW;
#endif
}
#else
/***********************************************************
* 函数说明:向LCD发送指令函数 *
* 输入: 需要发送的指令 *
* 输出: 无 *
* 调用函数:LCD_SEND_HALF_CHAR_HIGH() *
* LCD_SEND_HALF_CHAR_LOW() *
***********************************************************/
void LCDSendCommand(UINT8 Command)
{
SetCommand;
{
SetEnable;
LCD_SEND_HALF_CHAR_HIGH(Command);
SetDisable;
}
{
SetEnable;
LCD_SEND_HALF_CHAR_LOW(Command);
SetDisable;
}
SetCommand;
}
/***********************************************************
* 函数说明:向LCD发送数据函数 *
* 输入: 需要发送的数据 *
* 输出: 无 *
* 调用函数:LCD_SEND_HALF_CHAR_HIGH() *
* LCD_SEND_HALF_CHAR_LOW() *
***********************************************************/
void LCDSendData(UINT8 Data)
{
SetData;
{
SetEnable;
LCD_SEND_HALF_CHAR_HIGH(Data);
SetDisable;
}
{
SetEnable;
LCD_SEND_HALF_CHAR_LOW(Data);
SetDisable;
}
SetCommand;
}
/***********************************************************
* 函数说明:等待LCD空闲状态函数 *
* 输入: 无 *
* 输出: 无 *
* 调用函数:LCDDelayUs() *
***********************************************************/
void LCDWaitForReady(void)
{
LCDDelayUs(30);
}
#endif
/***********************************************************
* 函数说明:设置显示坐标函数 *
* 输入: x,y坐标值 *
* 输出: 无 *
* 调用函数:LCDWaitForReady() LCDSendCommand() *
***********************************************************/
void LCDSetXY(UINT8 X,UINT8 Y)
{
UINT8 Address;
if (Y == 0)
{
Address = 0x80 + X;
}
else
{
Address = 0xc0 + X;
}
LCDWaitForReady();
LCDSendCommand(Address);
}
/***********************************************************
* 函数说明:LCD字符串显示函数 *
* 输入: 要显示的字符串指针 *
* 输出: 无 *
* 调用函数:LCDWaitForReady() LCDSendData() *
***********************************************************/
void LCDDisplayString(UINT8 *String)
{
while(*String)
{
LCDWaitForReady();
LCDSendData(*String);
String++;
}
}
/***********************************************************
* 函数说明:数值显示函数(HEX) *
* 输入: 需要显示的数字(无符号长整形) *
* 输出: 无 *
* 调用函数:LCDSendData() *
***********************************************************/
void LCDDisplayNum(unsigned long Num,UINT8 BitCount)
{
UINT8 a = 0;
for (a = 8-BitCount ;a<8;a++)
{
LCDWaitForReady();
LCDSendData(CHR[(Num<<(a<<2))>>28]);
}
}
/***********************************************************
* 函数说明:滚屏字幕效果 *
* 输入: 需要滚屏的字符串 长度 位置 *
* 输出: 无 *
* 调用函数:LOCATE() PRINT() *
***********************************************************/
void RunString(UINT8 *String,UINT8 Y,UINT8 StartX,UINT8 EndX)
{
static UINT8 StringHead = 0;
UINT8 SCREEN[17];
UINT8 a = 0;
UINT8 Point = StringHead;
UINT8 StringLong = StringLength(String);
static UINT16 RunTimeCounter = 0;
for (a = 0;a<EndX - StartX + 1;a++)
{
SCREEN[a] = String[Point];
Point ++;
if (Point == StringLong)
{
Point = 0;
}
}
for (;a < 17;a++)
{
SCREEN[a] = 0;
}
RunTimeCounter ++;
if (RunTimeCounter > LCD_RUN_STRING_SPEED)
{
StringHead ++;
RunTimeCounter = 0;
if (StringHead == StringLong)
{
StringHead = 0;
}
}
LOCATE(StartX,Y)
PRINT(SCREEN)
}
/***********************************************************
* 函数说明:字符串长度测试函数 *
* 输入: 字符串指针 *
* 输出: 字符串的长度 *
* 调用函数:无 *
***********************************************************/
UINT8 StringLength(UINT8 *String)
{
UINT8 n = 0;
while (*String)
{
n++;
String ++;
}
return n;
}
/***********************************************************
* 函数说明:闪烁显示函数 *
* 输入: 要显示的字符串、显示的光标、x,y坐标位置 *
* 输出: 无 *
* 调用函数:LOCATE() LCDWaitForReady() LCDSendData() *
***********************************************************/
void Flash(UINT8 *String,UINT8 Icon,UINT8 X,UINT8 Y)
{
UINT8 a = 0;
UINT8 StringLong = StringLength(String);
if ((SYS_TIMER_MS_ADD_UNTILL_OVF & LCD_FLASH_TIME_OUT)
> (LCD_FLASH_TIME_OUT >> 1))
{
LOCATE(X,Y)
PRINT(String)
}
else
{
for (a = X;a < (X+StringLong);a++)
{
LOCATE(a,Y)
LCDWaitForReady();
LCDSendData(Icon);
}
}
}
/***********************************************************
* 函数说明:字幕GIF函数 *
* 输入: 要显示的字符串集合指针,字符串数目,位置 *
* 输出: 无 *
* 调用函数:LOCATE() PRINT() *
***********************************************************/
void FlashStringGroup(UINT8 String[][17],UINT8 StringCounter,UINT8 X,UINT8 Y)
{
static UINT8 Pictures = 0;
static UINT8 DispState = 0;
if ((SYS_TIMER_MS_ADD_UNTILL_OVF & LCD_FLASH_STRING_GROUP_TIME_OUT)
> (LCD_FLASH_STRING_GROUP_TIME_OUT >> 1))
{
if (DispState == 0)
{
Pictures ++;
if (Pictures == StringCounter)
{
Pictures = 0;
}
DispState = 1;
}
}
else
{
if (DispState == 1)
{
Pictures ++;
if (Pictures == StringCounter)
{
Pictures = 0;
}
DispState = 0;
}
}
LOCATE(X,Y);
PRINT(String[Pictures]);
}
/***********************************************************
* 函数说明:数值显示函数 *
* 输入: 要显示的整数 *
* 输出: 无 *
* 调用函数:无 *
***********************************************************/
void PrintD(INT32 nNumber,UINT8 chCounter)
{
uint8 cTempBuff[10] = {0};
uint8 n = 0;
uint32 wTempNumber = ABS(nNumber);
BOOL bIfFindFirstNoneZeroNumber = FALSE;
if (nNumber < 0)
{
PRINT("-")
}
else
{
PRINT(" ")
}
for (n = 9;n > 0;n--)
{
cTempBuff[n] = (wTempNumber % 10);
wTempNumber /= 10;
}
if (chCounter)
{
bIfFindFirstNoneZeroNumber = TRUE;
}
else
{
chCounter = UBOUND(cTempBuff);
bIfFindFirstNoneZeroNumber = FALSE;
}
chCounter = MIN(chCounter,UBOUND(cTempBuff));
for (n = UBOUND(cTempBuff) - chCounter;n < UBOUND(cTempBuff);n++)
{
if (cTempBuff[n])
{
PRINTN(cTempBuff[n],1);
bIfFindFirstNoneZeroNumber = TRUE;
}
else if (bIfFindFirstNoneZeroNumber)
{
PRINTN(cTempBuff[n],1);
}
}
if (!bIfFindFirstNoneZeroNumber)
{
PRINTN(0,chCounter);
}
}
RD_LCD1602b.h
#ifndef _Use_LCD1602B
#define _Use_LCD1602B
/***********************************************************
* 声明库说明:LCD1602B基本驱动函数声明库 *
* 版本: v2.11 *
* 作者: 傻孩子 *
* 创建日期: 2005年9月6日 *
* -------------------------------------------------------- *
* [支 持 库] *
* -------------------------------------------------------- *
* [版本更新] *
* 修改: 傻孩子 *
* 修改日期: 2006年6月8日 *
* 版本: v2.11 *
* -------------------------------------------------------- *
* [版本历史] *
* -------------------------------------------------------- *
* [使用说明] *
* 1、需要底层硬件驱动函数支持 *
* 基本的宏定义: *
* LCD_RS LCD_RW LCD_E *
* LCD_SET_WRITE_DATA LCD_SET_READ_DATA *
* LCD_SEND_HALF_CHAR_HIGH(a) *
* LCD_SEND_HALF_CHAR_LOW(a) *
* 当处于串行状态下时,只定义LCD_RS *
* LCD_E LCD_SEND_HALF_CHAR_HIGH(a) *
* LCD_SEND_HALF_CHAR_LOW(a) *
* 2、如果采用8数据位连接,则需要定义数据端口 *
* LCD_DATA_PORT,同时需要定义宏来开启该功 *
* 能:_LCD1602_FULL_DATA_MODEL *
* 3、需要修改引用宏定义来指定底层硬件驱动 *
* 函数库。 *
* 4、本库驱动下的LCD显示支持1602的各种连 *
* 接方法。当使用只写模式是请在引用该头 *
* 文件之前加上宏定义: *
* # define _USE_LCD_ONLY_WRITE *
* 5、在调用本库之前,定义RunStringSpeed可 *
* 以设置滚屏的速度。通过在引用前定义 *
* FlashTimeOut 和 FlashGIFTimeOut 可以 *
* 改变字符闪烁的频率。 *
* 6、增加一个GIF字幕特效函数。 *
* 7、确定没有LCD复位问题。 *
* 8、增加对595串行转并行连接的支持。 *
* 需要头文件SerialToCollateral.h *
***********************************************************/
/********************
* 头 文 件 配 置 区 *
********************/
/********************
* 系 统 宏 定 义 *
********************/
/*------------------*
* 常 数 宏 定 义 *
*------------------*/
/*------------------*
* 动 作 宏 定 义 *
*------------------*/
# define PRINT(a) LCDDisplayString(a);
# define LOCATE(x,y) LCDSetXY(x-1,y-1);
# define CLS LCDWaitForReady();LCDSendCommand(0x01);LCDWaitForReady();LCDSendCommand(0x02);
# define PRINTN(a,b) LCDDisplayNum((unsigned long)a,b);
# define SHOW_ICON LCDWaitForReady();LCDSendCommand(0x0f);
# define HIDE_ICON LCDWaitForReady();LCDSendCommand(0x0c);
# define PRINTD(a,b) PrintD(a,b);
/********************
* 结构体定义区 *
********************/
/********************
* 函 数 引 用 区 *
********************/
extern void LCDInit(void);
extern void LCDSetXY(UINT8 X,UINT8 Y);
extern void LCDDisplayString(UINT8 *String);
extern void LCDDisplayNum(UINT32 Num,UINT8 BitCount);
extern void RunString(UINT8 *String,UINT8 Y,UINT8 StartX,UINT8 EndX);
extern UINT8 StringLength(UINT8 *String);
extern void Flash(UINT8 *String,UINT8 Icon,UINT8 X,UINT8 Y);
extern void FlashStringGroup(UINT8 String[][17],UINT8 StringCounter,UINT8 X,UINT8 Y);
extern void LCDWaitForReady(void);
extern void LCDSendCommand(UINT8 Command);
extern void LCDSendData(UINT8 Data);
extern void PrintD(INT32 nNumber,UINT8 chCounter);
/********************
* 全局变量引用区 *
********************/
#endif |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|