标题: 教大家怎么写一个液晶1602的程序(绝对很简单!!) [打印本页]

作者: 51hei社区    时间: 2016-1-11 01:50
标题: 教大家怎么写一个液晶1602的程序(绝对很简单!!)
今天,小编给各位电子爱好者伙伴讲解这么一个程序,也许你看了郭天祥的10天学会单片机后感觉好多代码都不能亲手动手去写对吗?其实自己写代码写模块都是有一定的方法的,掌握了一定的方法,以后不管写什么,你都会如鱼得手,小编总结了一个很多人都头疼的问题,如何写一个液晶显示的程序呢?代码好长!!!!怎么办?害怕了?没有动力干了?小编告诉你,你立马有动力,不再惧怕类似1602的模块!!请往下看。
首先:
要写一个液晶1602的程序,我们需要明白液晶有三个端口是要写入相关的数据的;分别是E、RS、RW。
数据手册内容众多,小编就不一一阐释了;

所以,请看lcd1602数据手册:http://www.51hei.com/mcu/827.html
接着:

看完了数据手册,有木有发现灵感?是不是好多都是可以看着自己就可以敲出来?
好了,我们开始写程序:
写液晶的时候分为以下步骤:
1、写指令(看看数据手册里有的)
void writecmd(uchar com)  
{
E=0;       //为什么要写这一条呢,看看时序图就清楚了
RS=0;
RW=0;
P0=com;   
delay(2);  //延时一下会稳定很多,后面一条也是一样的
E=1;  
delay(2);
E=0;
}
//以上的P0就是液晶送数据的端口,当然你可以是P2口,看你的       电路是怎么样那就怎么改,至于为什么是com,这是个自定义形式参数来的,也可以改成别的,但是不能是关键字,这个参数传的就是你想要写的指令;下面写数据的P0是你想要写的数据。详情看看大程序便知

2、写数据(同样数据手册也有)
void writedata(uchar dat)//写数据,函数名随便你定义看得懂就行
{  
  E=0;     //写数据和写命令的方法差不多,复制过来。照着数据手            //册的写数据要求去写!
  RS=1;
  RW=0;
  P0=dat;
  delay(2);
  E=1;  
  delay(2);
  E=0;

}

3、初始化(一样的,数据手册也有,照写)
void init(void)              
{  delay(15);
writecmd(0x38);
delay(5);
writecmd(0x38);
delay(5);
writecmd(0x38);
writecmd(0x38);
writecmd(0x08);
writecmd(0x01);
writecmd(0x06);
writecmd(0x0c);
}
好了一个液晶的基本操作就是这三部分组成的,不难吧?
接下来来看看我们如何显示如图所示的字符:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

//这三个引脚参考资料
sbit E=P2^7;                //1602使能引脚
sbit RW=P2^6;                //1602读写引脚        
sbit RS=P2^5;                //1602数据/命令选择引脚

uchar tab1[]=" www.51hei.com  ";  //要显示什么就在这儿改
uchar tab2[]="LCD1602 test ok!";  //[size=15.5555562973022px]要显示什么就在这儿改

void delay(uint del)   //延时1ms
{
uint i,j;
for(i=0;i<del;i++)
   for(j=0;j<=168;j++);
}
void writecmd(uchar com)  //写指令
{
E=0;
RS=0;
RW=0;
P0=com;
delay(2);
E=1;  
delay(2);
E=0;
}
void writedata(uchar dat)//写数据
{  
  E=0;
  RS=1;
  RW=0;
  P0=dat;
  delay(2);
  E=1;  
  delay(2);
  E=0;

}
void init(void)               //初始化
{
delay(15);
writecmd(0x38);
delay(5);
writecmd(0x38);
delay(5);
writecmd(0x38);
writecmd(0x38);
writecmd(0x08);
writecmd(0x01);
writecmd(0x06);
writecmd(0x0c);
}
void main()
{  uchar j;
  init();
  writecmd(0x80);    //告诉液晶在哪个地方显示 (设置地址指针)//80H+00
  for(j=0;j<16;j++)  //有16个字符,要循环16次
  {
   writedata(tab1[j]);
        delay(2);
  }
  writecmd(0x80+0x40); //再设置第二行的起始位置80H+40H

  for(j=0;j<16;j++)   //有16个字符,要循环16次
  { writedata(tab2[j]);
         delay(2);
  }
  while(1);         //让液晶显示就一直停在这里。

}


好了,你们可以照着我这个程序去修改得到你们想要的显示结果,同样也可以发挥一下你们的想法,如何让液晶进行移屏显示呢?怎么样做出移动的效果呢?有待大家的努力噢!小编最主要的目的是要告诉大家,任何模块拿起来都不要惧怕,把数据手册看一遍,看不懂再看一遍,然后看看别人是怎么写的,自己动手改一遍,再写一遍,转化为自己的东西,这样就可以学到经验了。


作者: 努力山    时间: 2017-12-20 15:11
太好了受益很深;
作者: wugq5    时间: 2017-12-20 19:02
简洁明了,谢谢分享!
作者: qjzyx    时间: 2017-12-24 17:35
谢谢,你说的很易学懂!
作者: only5784    时间: 2017-12-24 18:04
太谢谢了,正在犯愁。多谢大侠
作者: lsc_nj    时间: 2017-12-24 19:47
简洁明了,谢谢分享!
作者: lsc_nj    时间: 2017-12-25 10:46
谢谢,你说的很易学懂!
作者: huang0762    时间: 2017-12-25 14:36
真的非常感谢成功点亮

作者: maoanlai    时间: 2018-1-1 14:56
请问怎么显示单片机里的数据啊,就是不是从程序里定义的,而是由单片机从别的地方都出来的数据
作者: 迈特拉布    时间: 2018-5-5 23:45
谢谢你
作者: carolineee    时间: 2018-5-22 15:46
学习了、谢谢
作者: 流年521    时间: 2018-5-22 18:12
简单明了,有收获,谢谢楼主

作者: 一杯树同学    时间: 2018-5-22 20:56
谢谢分享
作者: feiji666    时间: 2018-5-22 21:08
学习了,值得收藏
作者: 康德    时间: 2018-7-23 14:47
感谢分享。有些困惑解开了,谢谢
作者: FQ967    时间: 2018-7-24 09:35
记号一下!慢慢消化!
作者: 轰爆机    时间: 2018-7-24 11:25
感谢大神
作者: 单片机萌新21    时间: 2018-7-24 11:36
感谢解决了这一块的疑惑
作者: lwf1978l    时间: 2018-7-24 14:13
写的很简洁,思路很清楚。
作者: kapoc7    时间: 2018-7-24 16:27
支持技术贴,对我们初学者来说真是及时雨。
作者: xhkk    时间: 2018-7-24 17:12
其实就是这么回事
作者: Azure645    时间: 2018-7-31 17:52
学习了、谢谢
作者: jie1997    时间: 2018-8-1 11:25
谢谢楼主,适合小白学习。
作者: 281770683    时间: 2018-8-4 12:09
简单明了
作者: 泰瑞尔的羽翼    时间: 2018-8-4 13:59
前来学习了
作者: rz1976    时间: 2018-9-7 08:26
路过学习学习。
作者: FDGFDG    时间: 2018-10-3 17:52
楼主,为什么我显示的字母是黑点
作者: 快乐眼泪    时间: 2018-10-3 19:33
正在学习,谢谢!
作者: wangzihao233    时间: 2018-12-3 13:43
最后没有while(1)咋办

作者: gnez    时间: 2018-12-5 22:45
感谢分享!!!!
作者: cb474265474265    时间: 2018-12-6 07:42
多谢楼主分享,学习了。
作者: yiwen_005    时间: 2018-12-6 10:54
感谢。自己琢磨了老半天,终于会了。
作者: yzhbyyy    时间: 2019-5-20 14:45
感谢分享!!!!!!!
作者: LiYouhong263    时间: 2019-5-20 19:32
太收益了,简单明了。
作者: 辰宿列张    时间: 2019-6-13 10:16
感谢,但不知道我哪里出错了,显示出来是错误的,代码直接照抄的
作者: nsush    时间: 2019-6-14 19:15
看了之后,忍无可忍了,一定要回复下,很有用,楼主多谢!辛苦了!
作者: nsush    时间: 2019-6-19 03:05
另外,为啥初始化里,0x38,就是定义显示两行,5*8字符的。要刷3次?
作者: cphnkj188    时间: 2019-6-19 18:29
经典,以前看不懂的这样一讲就容易理解了,谢谢!
作者: 囚心久爱不腻    时间: 2019-7-11 10:48
楼主,再分享一个12864的呗,最近被他难住了

作者: azi197417    时间: 2019-7-11 14:03
简单明了,学习中
作者: 7320527    时间: 2019-7-11 15:26
不错的程序,谢谢啦
作者: 化蝶    时间: 2019-7-14 11:35
谢谢分享,赞一个

作者: Amber815    时间: 2019-7-19 11:15
思路清晰,学习方法很赞哦!
作者: Amber815    时间: 2019-7-19 14:41
但是LCD不现实怎么办
作者: wangxing123456    时间: 2019-7-22 14:42
谢谢分享!
作者: 12345678..    时间: 2019-7-22 22:37
感谢分享
作者: 下一秒-    时间: 2019-7-23 09:10
赞得很,刚好在学这个1602!
作者: 谢建业    时间: 2019-7-31 09:02
谢谢,简直太优秀了,感谢分享,

作者: 夏宇闪擎    时间: 2019-8-1 09:20
感谢楼主,收货颇多
作者: 123LI    时间: 2019-8-1 10:10
不错,很有心
作者: 作业终结者    时间: 2020-4-17 15:09
支持,已经收藏
作者: LUREN1    时间: 2020-4-19 20:46
浅显易懂,受益匪浅
作者: 王伟全    时间: 2020-4-19 21:10
很给力,比较简单易懂
作者: shyboy133    时间: 2020-5-3 19:21
谢谢楼主分享,很有用。
作者: 412903510    时间: 2020-5-4 22:24
很棒!
作者: lsg0280    时间: 2021-7-7 16:03
这篇文章指明了成长的道路。
作者: man1234567    时间: 2021-7-7 17:38
对照时序图讲解就更好了
作者: pq1972    时间: 2021-7-7 18:08
谢谢分享这么好的经验,新手最需要。也最缺少这样的经验。
作者: 方禾    时间: 2021-7-9 21:03
简洁

作者: 没啥好名    时间: 2021-10-30 21:46
都不用判忙的吗?

作者: 没啥好名    时间: 2021-10-31 09:00
nsush 发表于 2019-6-19 03:05
另外,为啥初始化里,0x38,就是定义显示两行,5*8字符的。要刷3次?

只用一次就可以了

作者: 没啥好名    时间: 2021-10-31 09:01
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

sbit rs=P2^6;
sbit rw=P2^5;
sbit en=P2^7;

uchar tab1[]=" www.51hei.com  ";

void busy()
{
uchar sta;
P0=0xff;
rs=0;
rw=1;
do{
en=1;
sta=P0;
en=0;
}while(sta&0x80);
}
void wr_lcd(uchar a,uchar b)
{
busy();
rs=a;
rw=0;
P0=b;
en=1;
en=0;
}

void init(void)
{
wr_lcd(0,0x38);
wr_lcd(0,0x08);
wr_lcd(0,0x0c);
wr_lcd(0,0x06);
wr_lcd(0,0x01);
}

void main()
{
uchar a;
init();
wr_lcd(0,0x80);
for(a=0;a<8;a++)
{
wr_lcd(1,tab1[a]);
}
while(1);
}
这样不简单一点?





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1