超强的51+LCD1602控制四位八位控制1602函数全集+写入字库.docx
《超强的51+LCD1602控制四位八位控制1602函数全集+写入字库.docx》由会员分享,可在线阅读,更多相关《超强的51+LCD1602控制四位八位控制1602函数全集+写入字库.docx(16页珍藏版)》请在冰豆网上搜索。
超强的51+LCD1602控制四位八位控制1602函数全集+写入字库
风骚的51+LCD1602控制(四位,八位控制),1602函数全集+写入字库
LCD1602写字库在文档后面。
LCD1602演示程序(很多函数哦)控制芯片为HD44780
函数都是经过测试的,实物显示都通过了,呵呵,请大家放心使用^_^
呵呵,支持四线数据接口模式,可以任意切换编程,只须改模式选择Port_Type_Select就可以咯!
很方便的。
并且我说一下我的个人体会,希望大家在写程序的时候,最好考虑一下程序的可移植性,而且要方便更改参数和硬件资源的选择,最好使用条件编译,任意切换硬件资源,可以方便以后更改参数,就会省去以后不少的不必要的麻烦和错误以及宝贵的时间
里面有标准测试,如果您觉得好的话,请您帮忙顶一下,希望有更多的朋友能知道的更多,更好,学习得更快^_^一起努力加油,写出更好的功能函数。
先简单介绍一下功能函数吧:
/*--------------------------------------------------------------*/
//模式选择(条件编译)
#definePort_Type_Select 1 //=1,选择八位数据模式
//=0,选择四位数据模式,LCD高四位接MCU端口高四位
/*--------------------------------------------------------------*/
//函数声明
voidLCD_busy (void); //检测LCD是否忙
voidLCD_init (void); //LCD初始化
voidLCD_cmd (unsignedcharcmd); //写入指令
voidLCD_dat (unsignedchardat); //写入数据
voidLCD_pos (unsignedcharx,unsignedchary); //显示定位
voidLCD_printc(unsignedcharx,unsignedchary,unsignedcharc); //定位输出字符
voidLCD_prints(unsignedcharx,unsignedchary,unsignedchar*s); //定位输出字符串
voidLCD_printn(unsignedcharx,unsignedchary,unsignedintnum); //定位输出16位二进制数字
unsignedcharLCD_current_addr(void); //读出AC当前地址(DB6~DB0)或忙标志位DB7
unsignedcharLCD_current_addr_dat(void); //读出AC当前地址的数据
unsignedcharLCD_addr_dat(unsignedcharx,unsignedchary); //读出AC指定地址的数据
voidLCD_pos_CG(unsignedcharx,unsignedchar*CGRAM_dat); //指定地址(x:
0-7)写入8bytes数据CGRAM
/*-------------------------------------------------------------*/
//光标、画面移动,不影响DDRAM
#defineLCD_LEFT_MOVE LCD_cmd(0x18); //LCD显示左移一位
#defineLCD_RIGHT_MOVE LCD_cmd(0x1c); //LCD显示右移一位
#defineLCD_CURSOR_LEFT_MOVE LCD_cmd(0x10); //光标左移一位
#defineLCD_CURSOR_RIGHT_MOVE LCD_cmd(0x14); //光标右移一位
/*--------------------------------------------------------------*/
//设置显示、光标及闪烁开、关
#defineLCD_DISPLAY_ON LCD_cmd(0x0c); //LCD开显示
#defineLCD_DISPLAY_OFF LCD_cmd(0x08); //LCD关显示
#defineLCD_CURSOR_ON LCD_cmd(0x0e); //光标显示
#defineLCD_CURSOR_OFF LCD_cmd(0x0c); //光标不显示
#defineLCD_CURSOR_BLINK_ON LCD_cmd(0x0f); //光标闪烁
#defineLCD_CURSOR_BLINK_OFF LCD_cmd(0x0e); //光标不闪烁
#defineLCD_GO_HOME LCD_cmd(0x02); //AC=0,光标、画面回HOME位,DDRAM内容不变
#defineLCD_CLR LCD_cmd(0x01); //LCD清屏,清除DDRAM,清除屏幕,置AC为0,光标回位?
/*--------------------------------------------------------------*/
//工作方式设置
#defineLCD_DISPLAY8_DOUBLE_LINE LCD_cmd(0x38); //两行显示8-bits
#defineLCD_DISPLAY8_SINGLE_LINE LCD_cmd(0x30); //单行显示8-bits
#defineLCD_DISPLAY4_DOUBLE_LINE LCD_cmd(0x28); //两行显示4-bits
#defineLCD_DISPLAY4_SINGLE_LINE LCD_cmd(0x20); //单行显示4-bits
/*--------------------------------------------------------------*/
//输入方式设置
#defineLCD_AC_AUTO_INCREMENT LCD_cmd(0x06); //数据读、写操作后,AC自动加1
#defineLCD_AC_AUTO_DECREASE LCD_cmd(0x04); //数据读、写操作后,AC自动减1
#defineLCD_MOVE_ENABLE LCD_cmd(0x07); //数据读、写操作,画面平移
#defineLCD_MOVE_DISENABLE LCD_cmd(0x06); //数据读、写操作,画面不动
以下是液晶驱动头文件:
/*--------------------------------------------------------------*/
//File:
LCD1602_8A.H
//Time:
20:
10
//Modi:
09-5-17
/*--------------------------------------------------------------*/
//防止被重复定义
#ifndef__LCD1602_8A_H__
#define__LCD1602_8A_H__
/*--------------------------------------------------------------*/
//模式选择(条件编译)
#definePort_Type_Select 1 //=1,选择八位数据模式
//=0,选择四位数据模式,LCD高四位接MCU端口高四位
#defineInt_Transfer 1 //=1, 允许中断服务函数调用
//=0,不允许中断服务函数调用
/*--------------------------------------------------------------*/
//LCD1602与单片机接口定义
sfr LCD_IO=0x80; //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit LCD_RS=P2^0; //LCD数据/命令选择端(H/L)
sbit LCD_RW=P2^1; //LCD 读/写 选择端(H/L)
sbit LCD_EN=P2^2; //LCD使能控制端
/*--------------------------------------------------------------*/
//工作方式设置
#defineLCD_DISPLAY8_DOUBLE_LINE LCD_cmd(0x38); //两行显示8-bits
#defineLCD_DISPLAY8_SINGLE_LINE LCD_cmd(0x30); //单行显示8-bits
#defineLCD_DISPLAY4_DOUBLE_LINE LCD_cmd(0x28); //两行显示4-bits
#defineLCD_DISPLAY4_SINGLE_LINE LCD_cmd(0x20); //单行显示4-bits
/*--------------------------------------------------------------*/
//输入方式设置
#defineLCD_AC_AUTO_INCREMENT LCD_cmd(0x06); //数据读、写操作后,AC自动加1
#defineLCD_AC_AUTO_DECREASE LCD_cmd(0x04); //数据读、写操作后,AC自动减1
#defineLCD_MOVE_ENABLE LCD_cmd(0x07); //数据读、写操作,画面平移
#defineLCD_MOVE_DISENABLE LCD_cmd(0x06); //数据读、写操作,画面不动
/*--------------------------------------------------------------*/
//设置显示、光标及闪烁开、关
#defineLCD_DISPLAY_ON LCD_cmd(0x0c); //LCD开显示
#defineLCD_DISPLAY_OFF LCD_cmd(0x08); //LCD关显示
#defineLCD_CURSOR_ON LCD_cmd(0x0e); //光标显示
#defineLCD_CURSOR_OFF LCD_cmd(0x0c); //光标不显示
#defineLCD_CURSOR_BLINK_ON LCD_cmd(0x0f); //光标闪烁
#defineLCD_CURSOR_BLINK_OFF LCD_cmd(0x0e); //光标不闪烁
#defineLCD_GO_HOME LCD_cmd(0x02); //AC=0,光标、画面回HOME位,DDRAM内容不变
#defineLCD_CLR LCD_cmd(0x01); //LCD清屏,清除DDRAM,清除屏幕,置AC为0,光标回位?
/*--------------------------------------------------------------*/
//光标、画面移动,不影响DDRAM
#defineLCD_LEFT_MOVE LCD_cmd(0x18); //LCD显示左移一位
#defineLCD_RIGHT_MOVE LCD_cmd(0x1c); //LCD显示右移一位
#defineLCD_CURSOR_LEFT_MOVE LCD_cmd(0x10); //光标左移一位
#defineLCD_CURSOR_RIGHT_MOVE LCD_cmd(0x14); //光标右移一位
/*--------------------------------------------------------------*/
//LCD1602地址相关
/*
#defineLINE1_HEAD 0x80 //第一行DDRAM起始地址
#defineLINE2_HEAD 0xc0 //第二行DDRAM起始地址
#defineLINE1 0 //第一行
#defineLINE2 1 //第二行
#defineLINE_LENGTH 16 //每行的最大字符长度(40-DDRAM)
/*--------------------------------------------------------------*/
//函数声明
voidLCD_busy (void); //检测LCD是否忙
voidLCD_init (void); //LCD初始化
voidLCD_cmd (unsignedcharcmd); //写入指令
voidLCD_dat (unsignedchardat); //写入数据
voidLCD_pos (unsignedcharx,unsignedchary); //显示定位
voidLCD_printc(unsignedcharx,unsignedchary,unsignedcharc); //定位输出字符
voidLCD_prints(unsignedcharx,unsignedchary,unsignedchar*s); //定位输出字符串
voidLCD_printn(unsignedcharx,unsignedchary,unsignedintnum); //定位输出16位二进制数字
unsignedcharLCD_current_addr(void); //读出AC当前地址(DB6~DB0)或忙标志位DB7
unsignedcharLCD_current_addr_dat(void); //读出AC当前地址的数据
unsignedcharLCD_addr_dat(unsignedcharx,unsignedchary); //读出AC指定地址的数据
voidLCD_pos_CG(unsignedcharx,unsignedchar*CGRAM_dat); //指定地址(x:
0-7)写入8bytes数据CGRAM
/*--------------------------------------------------------------*/
//读出AC当前地址(DB6~DB0)或忙标志位DB7
#ifPort_Type_Select //选择八位数据模式
unsignedcharLCD_current_addr(void)
{
unsignedcharac_addr;
LCD_EN=0;
LCD_RS=0; //指令
LCD_RW=1; //读出
LCD_IO=0xff; //端口置为输入方式(P0)
LCD_EN=1;
ac_addr=LCD_IO;
LCD_EN=0;
return(ac_addr);
}
#else //选择四位数据模式
unsignedcharLCD_current_addr(void)
{
unsignedcharac_addr;
LCD_EN=0;
LCD_RS=0; //指令
LCD_RW=1; //读出
LCD_IO|=0xf0; //端口置为输入方式(P0)
LCD_EN=1;
ac_addr=LCD_IO&0xf0; //高四位
LCD_EN=0;
LCD_EN=1;
ac_addr|=LCD_IO>>4; //低四位
LCD_EN=0;
return(ac_addr);
}
#endif
/*--------------------------------------------------------------*/
//检测LCD忙状态
#ifInt_Transfer //允许中断服务函数调用
voidLCD_busy(void)
{
unsignedcharac_dat;
unsignedcharbusy_flag;
do
{
ac_dat=LCD_current_addr();
busy_flag=ac_dat&0x80;
}while(busy_flag); //=1表示忙,=0表示空闲
}
#else //不允许中断服务函数调用
voidLCD_busy(void)
{
unsignedcharac_dat;
bitbusy_flag;
do
{
ac_dat=LCD_current_addr();
busy_flag=(bit)(ac_dat&0x80);
}while(busy_flag); //=1表示忙,=0表示空闲
}
#endif
/*--------------------------------------------------------------*/
//读出AC当前地址的数据
#ifPort_Type_Select //选择八位数据模式
unsignedcharLCD_current_addr_dat(void)
{
unsignedcharaddr_dat;
// unsignedchari;
LCD_busy(); //或者检查忙最可靠
// for(i=0;i<3;i++) //要连续读出三次才会有效
{
LCD_EN=0;
LCD_RS=1; //数据
LCD_RW=1; //读出
LCD_IO=0xff; //端口置为输入方式(P0)
LCD_EN=1;
addr_dat=LCD_IO;
LCD_EN=0;
}
return(addr_dat);
}
#else //选择四位数据模式
unsignedcharLCD_current_addr_dat(void)
{
unsignedcharaddr_dat;
// unsignedchari;
LCD_busy(); //或者检查忙最可靠
// for(i=0;i<3;i++) //要连续读出三次才会有效
{
LCD_EN=0;
LCD_RS=1; //数据
LCD_RW=1; //读出
LCD_IO|=0xf0; //端口置为输入方式(P0)
LCD_EN=1;
addr_dat=LCD_IO&0xf0; //高四位
LCD_EN=0;
LCD_EN=1;
addr_dat|=LCD_IO>>4; //低四位
LCD_EN=0;
}
return(addr_dat);
}
#endif
/*--------------------------------------------------------------*/
//写入指令
#ifPort_Type_Select //选择八位数据模式
voidLCD_cmd(unsignedcharcmd)
{
LCD_busy(); //检测忙
LCD_RS=0; //指令
LCD_RW=0; //写入
LCD_EN=1;
LCD_IO=cmd; //传指令
LCD_EN=0; //下降沿有效
}
#else //选择四位数据模式
voidLCD_cmd(unsignedcharcmd)
{
LCD_busy(); //检测忙
LCD_IO&=0x0f; //清高四位
LCD_RS=0; //指令
LCD_RW=0; //写入
LCD_EN=1;
LCD_IO|=cmd&0xf0; //写高四位
LCD_EN=0; //下降沿有效
cmd<<=4; //低四位移到高四位
LCD_IO&=0x0f; //清高四位
LCD_EN=1;
LCD_IO|=cmd&0xf0; //写高四位
LCD_EN=0; //下降沿有效
}
#endif
/*--------------------------------------------------------------*/
//写入数据
#ifPort_Type_Select //选择八位数据模式
voidLCD_dat(unsignedchardat)
{
LCD_busy(); //检测忙
LCD_RS=1; //数据
LCD_RW=0; //写入
LCD_EN=1;
LCD_IO=dat; //传数据
LCD_EN=0; //下降沿有效
}
#else //选择四位数据模式
voidLCD_dat(unsignedchardat)
{
LCD_busy(); //检测忙
LCD_IO&=0x0f; //清高四位
LCD_RS=1; //数据
LCD_RW=0; //写入
LCD_EN=1;
LCD_IO|=dat&0xf0; //写高四位
LCD_EN=0; //下降沿有效
dat<<=4; //低四位移到高四位
LCD_IO&=0x0f; //清高四位
LCD_EN=1;
LCD_IO|=dat&0xf0; //写高四位
LCD_EN=0; //下降沿有效
}
#endif
/*--------------------------------------------------------------*/
//显示定位DDRAM
voidLCD_pos(unsignedcharx,unsignedchary)
{
if(y) LCD_cmd(x|0xc0);//y=1第二行显示,y=0第一行显示 0<=x<16(40-DD