51单片机驱动LCD1602程序设计C语言.docx
- 文档编号:9552772
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:36
- 大小:1.11MB
51单片机驱动LCD1602程序设计C语言.docx
《51单片机驱动LCD1602程序设计C语言.docx》由会员分享,可在线阅读,更多相关《51单片机驱动LCD1602程序设计C语言.docx(36页珍藏版)》请在冰豆网上搜索。
51单片机驱动LCD1602程序设计C语言
51单片机驱动LCD1602程序设计(C语言)
m/EZ4y字符液晶绝大多数是基于HD44780液晶芯片的,操纵原理是完全相同的,因此HD44780写的操纵程序能够很方便地应用于市面上大部份的字符型液晶。
字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其操纵原理与14脚的LCD完全一样,概念如下表所示:
字符型LCD的引脚概念
HD44780内置了DDRAM、CGROM和CGRAM。
DDRAM确实是显示数据RAM,用来寄放待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:
也确实是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码就好了。
但具体的写入是要按LCD模块的指令格式来进行的。
在1602中咱们用前16个就好了。
第二行也一样用前16个地址。
对应如下:
DDRAM地址与显示位置的对应关系
电子爱好者社区
@-l:
t#Vu(TS
文本文件中每一个字符都是用一个字节的代码记录的。
一个汉字是用两个字节的代码记录。
在PC上咱们只要打开文本文件就能够在屏幕上看到对应的字符是因为在操作系统里和BIOS里都固化有字符字模。
什么是字模?
就代表了是在点阵屏幕上点亮和熄灭的信息数据。
例如“A”字的字模:
01110 ○■■■○ 10001 ■○○○■ 10001 ■○○○■ 10001 ■○○○■ 11111 ■■■■■ 10001 ■○○○■ 10001 ■○○○■上图左侧的数据确实是字模数据,右边确实是将左侧数据用“○”代表0,用“■”代表1。
看出是个“A”字了吗?
在文本文件中“A”字的代码是41H,PC收到41H的代码后就去字模文件中将代表A字的这一组数据送到显卡去点亮屏幕上相应的点,你就看到“A”那个字了。
适才说了想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码41H就好了,可41H这一个字节的代码如何才能让LCD模块在屏幕的阵点上显示“A”字呢?
一样,在LCD模块上也固化了字模存储器,这确实是CGROM和CGRAM。
HD44780内置了192个经常使用字符的字模,存于字符产生器CGROM(CharacterGeneratorROM)中,另外还有8个许诺用户自概念的字符产生RAM,称为CGRAM(CharacterGeneratorRAM)。
以下图说明了CGROM和CGRAM与字符的对应关系。
电子爱好者社区5uC*+gj\/_+a6LIa
从上图能够看出,“A”字的对应上面高位代码为0100,对应左侧低位代码为0001,合起来确实是01000001,也确实是41H。
可见它的代码与咱们PC中的字符代码是大体一致的。
因此咱们在向DDRAM写C51字符代码程序时乃至能够直接用P1='A'如此的方式。
PC在编译时就把“A”先转为41H代码了。
字符代码0x00~0x0F为用户自概念的字符图形RAM(关于5X8点阵的字符,能够寄存8组,5X10点阵的字符,寄存4组),确实是CGRAM了。
后面我会详细说的。
0x20~0x7F为标准的ASCII码,0xA0~0xFF为日文字符和希腊文字符,其余字符码(0x10~0x1F及0x80~0x9F)没有概念。
那么如何对DDRAM的内容和地址进行具体操作呢,下面先说说HD44780的指令集及其设置说明,请阅读该指令集,并找出对DDRAM的内容和地址进行操作的指令。
共11条指令:
功能:
<1>清除液晶显示器,即将DDRAM的内容全数填入"空白"的ASCII码20H; <2>光标归位,即将光标撤回液晶显示屏的左上方; <3>将地址计数器(AC)的值设为0。
2.光标归位指令
功能:
<1>把光标撤回到显示器的左上方; <2>把地址计数器(AC)的值设置为0; <3>维持DDRAM的内容不变。
功能:
设定每次定入1位数据后光标的移位方向,而且设定每次写入的一个字符是不是移动。
参数设定的 情形如下所示:
位名 设置I/D 0=写入新数据后光标左移 1=写入新数据后光标右移S 0=写入新数据后显示屏不移动 1=写入新数据后显示屏整体右移1个字符
功能:
操纵显示器开/关、光标显示/关闭和光标是不是闪烁。
参数设定的情形如下:
位名 设置 D 0=显示功能关 1=显示功能开 C 0=无光标 1=有光标 B 0=光标闪烁 1=光标不闪烁
功能:
使光标移位或使整个显示屏幕移位。
参数设定的情形如下:
S/C R/L 设定情况 0 0 光标左移1格,且AC值减1 0 1 光标右移1格,且AC值加1 1 0 显示器上字符全部左移一格,但光标不动 1 1 显示器上字符全部右移一格,但光标不动
功能:
设定数据总线位数、显示的行数及字型。
参数设定的情形如下:
位名 设置 DL 0=数据总线为4位 1=数据总线为8位 N 0=显示1行 1=显示2行 F 0=5×7点阵/每字符 1=5×10点阵/每字符
功能:
设定下一个要存入数据的CGRAM的地址。
8.设定DDRAM地址指令
功能:
设定下一个要存入数据的CGRAM的地址。
功能:
<1>读取忙碌信号BF的内容,BF=1表示液晶显示器忙,临时无法接收单片机送来的数据或指令;当BF=0时,液晶显示器能够接收单片机送来的数据或指令; <2>读取地址计数器(AC)的内容。
功能:
<1>将字符码写入DDRAM,以使液晶显示屏显示出相对应的字符; <2>将利用者自己设计的图形存入CGRAM。
功能:
读取DDRAM或CGRAM中的内容。
大体操作时序:
读状态 输入:
RS=L,RW=H,E=H 输出:
DB0~DB7=状态字写指令 输入:
RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码 输出:
无读数据 输入:
RS=H,RW=H,E=H 输出:
DB0~DB7=数据写数据 输入:
RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据 输出:
无
显示操作的进程:
电子爱好者社区Tao第一确认显示的位置,即在第几行,第几个字符开始显示。
也确实是要显示的地址,如下表所示的显示地址。
电子爱好者社区A3AV4QP电子爱好者社区+U*d3_vk/dZ
;s{-g6s)Xu%E^g0电子爱好者社区{gIXz3kgJ第一行的显示地址是0x80-0x8F,第二行的显示地址是0xC0-0xCF。
例如想要在第2行,第3个位置显示一个字符,那么地址码确实是0xC2。
在编程进程中,通常编写一个函数确信在某行某个位置显示。
函数需要行(y),和列参数(x)来确信显示位置。
参考如下:
v9r`9Ish+L5k0/***************设置显示位置**************************/3r]`igBZ0voidLCD_set_xy(unsignedcharx,unsignedchary)电子爱好者社区q,vF|%U8A/?
{gZ6nEt3Q0unsignedcharaddress;ZK/Bk;]7l-@]0 if(0==y)x|=0x80;8FBD0第二设置要显示的内容,即上面提到的CGROM内的字符编码。
如显示“A”,将编码41H写入到液晶屏显示即可。
通常设置地址和显示内容用一个函数来完成。
代码参考如下:
电子爱好者社区B8UiW(\-X5s@;eZ0{电子爱好者社区r&z#Q(J4jCf"J:
D if(0==y)x|=0x80;
0c
1f1f1f
0f0f1c
`l7W0子爱好者社区VM/_CnJk子爱好者社区%qF)f,uwBM(s4\Yo Write_dat(p[kk]); P)Y8B
T;_?
_i0 kk++;电子爱好者社区+I/m&YYAJ }电子爱好者社区o{5Dvwqn"C2D tmp+=8;电子爱好者社区T9H@t5A}#S,Py:
LC'^8]0}
上一步中,自概念字符存储到CGRAM的任意一组以后,每一个组(8个字节)也有一个显示编码。
按顺序依次为00H-07H。
显示时,只要挪用每一组的编码,即能够显示相应的字符。
电子爱好者社区BeS]k
电子爱好者社区E4[0l/M?
电子爱好者社区y7^!
Utp注:
内部经常使用字符显示时,显示编码是从0x20开始的。
0x00-0x0f是专门留给自概念字符显示的。
0x00-0x07和0x08-0x0f内容是一样的。
例如:
挪用0x01位置和0x09位置,显示的内容是一样的。
Y"P5sy^1h"\4Nt0 直接依照单个字符的显示方式挪用显示函数,就能够够显示自概念字符了。
代码参考如下:
-YA9Gl0{2vK0
TL1=0xFA;
IE|=0x90;'/',
0x71,'.',
0x70,'0',
0x69,'1',
0x72,'2',
0x7A,'3',
0x6B,'4',
0x73,'5',
0x74,'6',
0x6C,'7',
0x75,'8',
0x7D,'9',
};
unsignedcharcodeShifted[59][2]={
0x1C,'A',
0x32,'B',
0x21,'C',
0x23,'D',
0x24,'E',
0x2B,'F',
0x34,'G',
0x33,'H',
0x43,'I',
0x3B,'J',
0x42,'K',
0x4B,'L',
0x3A,'M',
0x31,'N',
0x44,'O',
0x4D,'P',
0x15,'Q',
0x2D,'R',
0x1B,'S',
0x2C,'T',
0x3C,'U',
0x2A,'V',
0x1D,'W',
0x22,'X',
0x35,'Y',
0x1A,'Z',
0x45,'0',
0x16,'1',
0x1E,'2',
0x26,'3',
0x25,'4',
0x2E,'5',
0x36,'6',
0x3D,'7',
0x3E,'8',
0x46,'9',
0x0E,'~',
0x4E,'_',
0x55,'+',
0x5D,'|',
0x29,'',
0x54,'{',
0x5B,'}',
0x4C,':
',
0x52,'"',
0x41,'<',
0x49,'>',
0x4A,'?
',
0x71,'.',
0x70,'0',
0x69,'1',
0x72,'2',
0x7A,'3',
0x6B,'4',
0x73,'5',
0x74,'6',
0x6C,'7',
0x75,'8',
0x7D,'9',
};
/*********************************************************
//日历时钟
//按AN1,进入设置状态
//按AN2,停止闹钟声音
//按AN3,依次进入闹钟功能是不是启用,闹钟时,分秒,年,月,日及时刻时,分,秒的设置,直到退出设置状态
//按AN4,调整是不是起用闹钟和调剂闹钟时,分,秒,年,月,日,时刻的时,分,秒的数字
//LCD第二排中间显示小喇叭,表示启用闹钟功能,无那么禁止闹钟功能(可在调整状态进行设置)
//正常状态,LCD上排最前面显示自概念字符,LCD下排最前面闪动"willar"
//设置状态,LCD上排最前面显示"P",下排最前面在设置闹钟时刻时显示"alarm:
",其它状态显示"time"
//年代转变2000--2099,礼拜自动转换
//程序中有自概念字符写入
*********************************************************/
#include<>
#include<>
unsignedcharcodedis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};
unsignedcharcodepara_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};//星期月参变数
unsignedchardatadis_buf1[16];//lcd上排显示缓冲区
unsignedchardatadis_buf2[16];//lcd下排显示缓冲区
unsignedchardatayear,month,date,week;//年、月、日、礼拜
unsignedchardataarmhour,armmin,armsec;//闹钟时、分、秒
unsignedchardatahour,min,sec,sec100;//时、分、秒、百分之一秒
unsignedchardataflag,vkey,skey;//设置状态计数标志、按键先前值、按键当前值
bitalarm;//标识是否启用闹钟,1--启用,0--关闭
sbitrs=P2^0;//LCD数据/命令选择端(H/L)
sbitrw=P2^1;//LCD读/写选择端(H/L)
sbitep=P2^2;//LCD使能控制
sbitPRE=P3^4;//调整键(AN3)
sbitSET=P3^5;//调整键(AN4)
sbitSPK=P3^7;
voiddelayms(unsignedcharms);//延时程序
bitlcd_busy();//测试LCD忙碌状态程序
voidlcd_wcmd(charcmd);//写入指令到LCD程序
voidlcd_wdat(chardat);//写入数据到LCD程序
voidlcd_pos(charpos);//LCD数据指针位置程序
voidlcd_init();//LCD初始化设定程序
voidpro_timedate();//时间日期处理程序
voidpro_display();//显示处理程序
voidpro_key();//按键处理程序
voidtime_alarm();//定时报警功能(闹钟)
unsignedcharscan_key();//按键扫描程序
unsignedcharweek_proc();//星期自动计算与显示函数
bitleap_year();//判断是否为闰年
voidlcd_sef_chr();//LCD自定义字符程序
voidupdate_disbuf(unsignedchart1,unsignedchart2[],unsignedchardis_h,unsignedchardis_m,unsignedchardis_s);
//更新显示缓冲区函数
//延时程序
voiddelay(unsignedcharms)
{while(ms--)
{unsignedchari;
for(i=0;i<250;i++)
{
_nop_();//执行一条_nop_()指令为一个机器周期
_nop_();
_nop_();
_nop_();
}
}
}
//测试LCD忙碌状态
bitlcd_busy()
{
bitresult;
rs=0;
rw=1;
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
result=(bit)(P1&0x80);//LCD的D0--D7中,D7=1为忙碌,D7=0为空闲
ep=0;
returnresult;
}
//写入指令到LCD
voidlcd_wcmd(charcmd)
{
while(lcd_busy());//当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写指令
rs=0;
rw=0;
ep=0;
_nop_();
_nop_();
P1=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
ep=0;
}
//写入数据到LCD
voidlcd_wdat(chardat)
{
while(lcd_busy());//当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写数据
rs=1;
rw=0;
ep=0;
P1=dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
ep=0;
}
//LCD数据指针位置程序
voidlcd_pos(charpos)
{
lcd_wcmd(pos|0x80);//数据指针=80+地址码(00H~27H,40H~67H)
}
//设定二个自概念字符,(注意:
LCD1602中自概念字符的地址为0x00--0x07,即可概念8个字符)
//那个地址咱们设定把一个自概念字符放在0x00位置(000),另一个放在0x01位子(001)
voidlcd_sef_chr()
{//第一个自定义字符
lcd_wcmd(0x40);//"01000000"第1行地址(D7D6为地址设定命令形式D5D4D3为字符寄存位置(0--7),D2D1D0为字符行地址(0--7))
lcd_wdat(0x1f);//"XXX11111"第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭)
lcd_wcmd(0x41);//"01000001"第2行地址
lcd_wdat(0x11);//"XXX10001"第2行数据
lcd_wcmd(0x42);//"01000010"第3行地址
lcd_wdat(0x15);//"XXX10101"第3行数据
lcd_wcmd(0x43);//"01000011"第4行地址
lcd_wdat(0x11);//"XXX10001"第4行数据
lcd_wcmd(0x44);//"01000100"第5行地址
lcd_wdat(0x1f);//"XXX11111"第5行数据
lcd_wcmd(0x45);//"01000101"第6行地址
lcd_wdat(0x0a);//"XXX01010"第6行数据
lcd_wcmd(0x46);//"01000110"第7行地址
lcd_wdat(0x1f);//"XXX11111"第7行数据
lcd_wcmd(0x47);//"01000111"第8行地址
lcd_wdat(0x00);//"XXX00000"第8行数据
//第二个自概念字符
lcd_wcmd(0x48);//"01001000"第1行地址
lcd_wdat(0x01);//"XXX00001"第1行数据
lcd_wcmd(0x49);//"01001001"第2行地址
lcd_wdat(0x1b);//"XXX11011"第2行数据
lcd_wcmd(0x4a);//"01001010"第3行地址
lcd_wdat(0x1d);//"XXX11101"第3行数据
lcd_wcmd(0x4b);//"01001011"第4行地址
lcd_wdat(0x19);//"XXX11001"第4行数据
lcd_wcmd(0x4c);//"01001100"第5行地址
lcd_wdat(0x1d);//"XXX11101"第5行数据
lcd_wcmd(0x4d);//"01001101"第6行地址
lcd_wdat(0x1b);//"XXX11011"第6行数据
lcd_wcmd(0x4e);//"01001110"第7行地址
lcd_wdat(0x01);//"XXX00001"第7行数据
lcd_wcmd(0x4f);//"01001111"第8行地址
lcd_wdat(0x00);//"XXX00000"第8行数据
}
//LCD初始化设定
voidlcd_init()
{
lcd_wcmd(0x38);//设置LCD为16X2显示,5X7点阵,八位数据借口
delay
(1);
lcd_wcmd(0x0c);//LCD开显示及光标设置(光标不闪烁,不显示"-")
delay
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 驱动 LCD1602 程序设计 语言