第七课 控制液晶屏LCD1602《中学生C51单片机易学实战入门教程》
实验准备
课程内容
第七课 控制液晶屏LCD1602
实验准备:
LCD1602 面包板 杜邦线
电阻:10k 8只 或排阻(用于P0上拉)
(或直接使用完整的开发板)
课程内容:
一、 原理图与接线
这里分析下 几个接口信号 V0、RS、RW、EN 表示的意义:
3脚:V0,液晶显示偏压信号,用于调整LCD1602的显示对比度,一般会外接电位器用以调整偏压信号,注意此脚电压为0时可以得到最强的对比度。
4脚:RS,数据/命令选择端,当此脚为高电平时,可以对1602进行数据字节的传输操作,而为低电平时,则是进行命令字节的传输操作。命令字节,即是用来对LCD1602的一些工作方式作设置的字节;数据字节,即使用以在1602上显示的字节。值得一提的是,LCD1602的数据是8位的。
5脚:R/W,读写选择端。当此脚为高电平可对LCD1602进行读数据操作,反之进行写数据操作。
6脚:E,使能信号(LCDE),其实是LCD1602的数据控制时钟信号,利用该信号的上升沿实现对LCD1602的数据传输。
7~14脚:8位并行数据口,使得对LCD1602的数据读写大为方便。
还有就是在单片机开发板上的接线:数据线接P0,控制线用P2中的三个IO
sbit LCD_RS = P2^6;
sbit LCD_RW = P2^5;
sbit LCD_EP = P2^7;
二、 底层操作
写命令 RS=L,RW=L,D0—D7=命令,EN=高脉冲 H
写数据 RS=H,RW=L,D0—D7=数据,EN=高脉冲H
三、 时序图
这节课引入时序图,其他器件类似,只要看懂时序图,就可以通过编程轻松控制这些器件按自己的需求工作,注意时间轴从左往右。
我们先不读出它的数据的状态或者数据本身。所以只需要看两个写时序:
① 当我们要写指令字,设置LCD1602的工作方式时:需要把RS置为低电平,RW置为低电平,然后将数据送到数据口D0~D7,最后E引脚一个高脉冲将数据写入。
② 当我们要写入数据字,在1602上实现显示时:需要把RS置为高电平,RW置为低电平,然后将数据送到数据口D0~D7,最后E引脚一个高脉冲将数据写入。
发现了么,写指令和写数据,差别仅仅在于RS的电平不一样而已。
操作步骤:(要对照时序图)
1) RS 确定 写数据还是命令
2) RW写模式 给0
3) P0 放数据或命令,延时5微秒
4) EN 给 1 延时5微秒 再给0 (即是给了脉冲)
这个表的命令也不需要记,在下面例程中LCD初始化部分就有厂家提供的代码.
还有下表是控制操作需要消耗的时间:ns表示纳秒
四、 按时序图编程
一个 _nop_(); 大约1微秒
void lcd_cmd(BYTE cmd)
{ // 写入指令数据到LCD
LCD_RS = 0;
LCD_RW = 0;
LCD_EP = 0;
P0 = cmd;
_nop_();_nop_();_nop_();_nop_();_nop_();
LCD_EP = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
LCD_EP = 0;
}
void lcd_wdat(BYTE dat)
{ //写入字符显示数据到LCD
LCD_RS = 1;
LCD_RW = 0;
LCD_EP = 0;
P0 = dat;
_nop_();_nop_();_nop_();_nop_();_nop_();
LCD_EP = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
LCD_EP = 0;
}
void lcd_init()
{ //LCD初始化设定
lcd_cmd(0x38); //16*2显示,5*7点阵,8位数据
lcd_cmd(0x0c); //显示开,关光标
lcd_cmd(0x06); //移动光标
lcd_cmd(0x01); //清除LCD的显示内容
}
BYTE code dis1[] = {" WELCOME TO "}; //要放最前面定义
BYTE code dis2[] = {" My C51 "};//要放最前面定义
main()
{
BYTE i;
lcd_init(); // 初始化LCD
delay(10);
while(1)
{
lcd_wcmd(0x06); //向右移动光标
lcd_ wcmd (0x80); //设置显示位置为第一行的第1个字符
i = 0;
while(dis1[ i ] != '\0') // \0 是C语言中字符串最后一个字符
{ //显示字符"WLCOME TO"
lcd_wdat(dis1[ i ]);
i++;
}
lcd_ wcmd (0x80+0x40); //设置显示位置为第二行第1个字符
i = 0;
while(dis2[ i ] != '\0')
{
lcd_wdat(dis2[ i ]); //显示字符" My C51"
i++;
delay(30); //控制两字之间显示速度
}
}
}
可以修改程序 让向左显示 ,或者移出移入
可以在在程序 中 需要的位置加入 延时 让数据稳定
五、增补C语言基础--数组
简单理解:数组是同种类型元素的集合。(特别注意:同种类型)
1. 一维数组定义
int a[10];
这样我们便定义了一个数组a,它分配10个int类型空间。
2.数组的初始化
例程中:
BYTE code dis1[] = {" WELCOME TO "};
定义了一个类型为 BYTE code 的数组,同时做初始化,这数组的各个元素都是一个字符,其中有空格,字母.
3.数组元素的访问
访问数组中的元素可以采用数组名加下标的方式,下标是从0开始,C语言并不检查数组下标是否越界,所以在访问数组中的元素时需要注意,需要对数组下标做判断,防止访问数组越界。
例子:
int a[10];
int i;
for (i = 0; i < 10; i++)
{
a[i] = i + 1;
}
至于二维数组,简单可理解为一个XX行YY列的表格,本教程现时还没有用到,所以暂时不作详解.
51单片机驱动 LCD1602液晶显示 PROTEUS仿真 LCD指令解释
最近后台有小伙伴留言和我说老师给他们留了一个设计作业要用单片机去驱动LCD1602液晶显示任意字符,我利用空闲时间做了一个小实验,希望能帮到他做一个参考,更希望你们看后能有所收获。
51单片机驱动 LCD1602液晶显示系统 PROTEUS仿真及源代码设计
废话不多说先上实物图
LCD1602+51单片机最小系统应用仿真及制作
好了,接下来正式进入制作环节:
第一步:仿真
绘制好原理图,仿真时单片机最小系统只放一个单片机就可以了,但实际电路中需要加上电源模块、复位模块。如下图:
原理图文件请在附件中找。
原理图绘制好后,编写代码并生成hex文件。参考代码如下:
/*************************功能************************/
/*使用外部中断INTO改变LED状态,并且用1602显示出其状态*/
#include<reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=" HELLO 1602 ";
uchar code table0[]="1602 TEST ";
uchar code table1[]="RESULT: "; //空格是写到LCD了,即空格也是内容
uchar code table2[]="OK!";
uchar code table3[]="liang";
uchar code table4[]="mie";
uchar num;
sbit led=P1^7;
sbit lcden=P2^0; //液晶使能端
sbit lcdrs=P2^2; //液晶数据命令选择端选择写数据还是写命令
void delay(uint z) // 延时函数
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com) //写入
{
lcdrs=0; //LCD 选择输入命令
P0=com; //向P0 口输入命令 39-32端口
delay(5); //延时
lcden=1; //打开LCD 使能
delay(5); //一个高脉冲
lcden=0; //关闭LCD 使能
}
void write_data(uchar date)
{
lcdrs=1; //设置为输入数据
P0=date; //将数据赋给P0 口
delay(5); //延时
lcden=1; //置高
delay(5); //高脉冲
lcden=0; //置低完成高脉冲
}
void init() //LED 初始化
{
lcden=0;
write_com(0x38);//设置16x2 显示5x7 点阵,8 位数据接口
write_com(0x0c); //设置开始显示不显示光标 (指令4)
write_com(0x06); //写一个字符后地址指针加1 (指令3)
write_com(0x01); //显示清零数据指针清零 (指令1)
}
void display(unsigned char *p)//按指针 地址写入数据
{
while(*p!='\0')
{
write_data(*p); //写数据
p++;
delay(1);
}
}
void main()
{
TCON=0x01; //设置中断为INTO
IE=0x81;
led=0;
init();
write_com(0x80); //将数据指针第一行第一个字处,
display(table); //调用函数的方式写入数据
delay(800);
write_com(0x80); //将数据指针第一行第一个字处,
display(table0); //调用函数的方式写入数据
write_com(0x80+0x40); //定义指针位置 将数据指针第二行第一个字处
for(num=0;num<7;num++)
{
write_data(table1[num]);
delay(5);
}
write_com(0x80+0x4c); //按1602的地址单个写入数据
write_data(table2[0]);
write_com(0x80+0x4d); //按1602的地址单个写入数据
write_data(table2[1]);
write_com(0x80+0x4e); //按1602的地址单个写入数据
write_data(table2[2]);
while(1);
}
void key_can() interrupt 0
{
delay(20); // 消除按键抖动
if(P3^3==0)
{
if(P3^3==0)
{
led=!led;
}
if(led==1)
{
write_com(0x80+0x4b);
display(table3);
}
else if(led==0)
{
write_com(0x80+0x4b); //按1602的地址单个写入数据
display(table4);
write_com(0x80+0x4f);
write_data(table1[8]); //按1602的地址单个写入数据
write_com(0x80+0x4e);
write_data(table1[8]);
}
}
}
原理图和代码都有了,仿真的准备工作就完了,现在正式进入仿真。
将代码加载进单片机中,仿真结果如下图:
元器件清单
原件布局及效果图如下:
最后按照要求全部焊接好,上电烧程序测试就可以了。
应该写得够详细了吧,最后,如果有什么意见或者建议欢迎直接给我留言,让我们共同学习一起进步,如果需要完整的代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢!
如果喜欢我的文章请评论转发加关注哦。
相关问答
单片机 直接驱动 LCD 液晶屏-ZOL问答普通单片机直接驱动回显得非常吃力因为需要±信号外还需要不同的电压信号,所以...你既然有LCD,应该有说明书才对,里面有介绍怎么接线,用什么接口和IC的。这款密...
怎样用 单片机 I/O口直接驱动 LCD ?LCD耗电少,可以直接用IO口驱动,即直接连接当然,如果单片机的IO口电压与LCD要求的电压不一致时,需要用到电平转换LCD耗电少,可以直接用IO口驱动,即直接连接...
单片机lcd 怎么不断刷新频率?因为lcd屏幕支持啊因为lcd屏幕支持啊
单片机 控制 LCD ,字母上下循环显示的程序把存放字符首地址的寄存器不断加一,再当首地址送出去。
单片机 中的 LCD -ZOL问答单片机中的LCD显示器讨论回答(7)看你的程序,大概猜出应该是在液晶第二行显示时分秒信息Voidwrite_sfm(ucharadd,uchardate),add看程序是指LCD第二...
单片机 上的 lcd 不亮怎么测试?要测试单片机上的LCD是否亮,可以按照以下步骤进行测试。首先,检查LCD的电源是否正常连接,确保电源线没有松动或损坏。然后,检查LCD的背光是否正常工作,可...
C51 单片机 中,如何把一int型形参中的数值显示在1602液晶屏上?在C51单片机中,要将一个int型形参中的数值显示在1602液晶屏上,可以通过以下步骤进行操作:1.首先,连接好C51单片机和1602液晶屏。确保液晶屏的VCC(正电源)...
51 单片机lcd 1602如何显示数字变量?1602是可以显示字符的,如'1','2'等,可以设置一个字符串,如charAA[]={'0123456789'}那么设置一个变量i,AA[i]就行...
LCD 如何用 单片机 程序清屏?有一条指令可以直接清零:0x01,然后等几个毫秒就行。或者直接往屏幕上写0x20(就是空格),把屏幕写满就算ok了。有一条指令可以直接清零:0x01,然后等几个毫秒就...
单片机 控制7寸tft模块液晶屏,具体怎么写程序,大概思路?第一,逻辑上是一样的,如果接的口一样,改动量会很小第二,如果没有gui的话那就需要你进行液晶屏的最底层操作,比如说初始化,画点,画线这些最基本的工作都需...