1602单片机控制电路字符型液晶显示器LCD1602显示字符信息

Arduino下LCD1602综合探究(上)——1602的两种驱动方式,如何使LCD的控制编程变得更简单 - 大大维 - 博客园
本文为大大维原创,最早于博客园发表,转载请注明出处!!!
一、前言:
  LCD ( Liquid Crystal Display 的简称)液晶显示器,已经逐渐替代CRT成为主流的显示设备之一,因此也成为了单片机发烧友绕不过的话题之一;而LCD1602更是很多单片机发烧友最早接触的字符型液晶显示器。笔者经过一段时间的深入学习,对其驱动有了些许心得,特地记录于此,以备以后查阅。
  LCD1602,也叫1602液晶,是一种专门用来显示字母、数字、符号等的点阵型液晶模块,工业字符型液晶的一种,能够同时显示16x02即32个字符。主控芯片是HD44780或者其它兼容芯片,而市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理是完全相同的。因此尽管LCD1602可显示的内容十分有限,但在此花点时间是完全值得的。
二、LCD的一些背景知识:
&1&LCD1602基本参数及引脚功能:
1.LCD1602的分类:
  LCD1602分为带背光和不带背光两种,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图10-54所示:
在本文中,笔者选用的是带背光的一种。
2.基本参数:
显示容量:16&2个字符
芯片工作电压:4.5&5.5V
工作电流:2.0mA(5.0V)
模块最佳工作电压:5.0V
字符尺寸:2.95&4.35(W&H)mm
2.引脚功能说明:
  1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如下:
液晶显示偏压
数据/命令选择
背光源正极
背光源负极
各引脚说明:
第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生&鬼影&,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极
&2&LCD1602的指令说明及时序:
1.与HD44780相兼容的芯片时序表如下:
RS=L,R/W=H,E=H
D0&D7=状态字
RS=L,R/W=L,D0&D7=指令码,E=高脉冲
RS=H,R/W=H,E=H
D0&D7=数据
RS=H,R/W=L,D0&D7=数据,E=高脉冲
2.LCD1602的指令说明:
  1602液晶模块内部的控制器共有11条控制指令,如表所示:
置输入模式
显示开/关控制
光标或字符移位
置字符发生存贮器地址
字符发生存贮器地址
置数据存贮器地址
显示数据存贮器地址
读忙标志或地址
计数器地址
写数到CGRAM或DDRAM
要写的数据内容
从CGRAM或DDRAM读数
读出的数据内容
笔者在百度文库中发现一个特别好的介绍1602指令集的文章,给大家分享如下:
&3&LCD1602的RAM地址映射及标准字库表:
1.LCD1602的RAM地址映射
  液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,下图是1602的内部显示地址:
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。每次输入指令前都要判断液晶模块是否处于忙的状态。
2.LCD1602的标准字库表
  1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如下图所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等。
在使用标准字库中的字符图形时,无需自己制作字模即可直接使用,若要显示汉字等标准字库中没有的元素,则需要自己在DDRAM中制作字模。
&4&LCD1602四线驱动的约定流程:
1、& 写入指令:
1) EN = 0 (LCD使能禁止)
3) RS = 0& ,RW = 0&&(准备写入指令)
4) DATA = 指令的高4位(ATA代表D7、D6、D5、D4,下同)
6) EN = 1 (LCD使能允许,指令写入)
8) EN = 0 (LCD使能禁止)
9) DATA = 指令的低4位&
10) 短延时
11) EN = 1 (LCD使能允许,指令写入)
12) 短延时
13) EN = 0 (LCD使能禁止)
14) 短延时
2、& 写入数据:
1) EN = 0 (LCD使能禁止)
3) RS = 1&,RW = 0&(准备写入数据)
4) DATA = 数据的高4位
6) EN = 1 (LCD使能允许,数据写入)
8) EN = 0 (LCD使能禁止)
9) DATA = 数据的低4位
10) 短延时
11) EN = 1 (LCD使能允许,数据写入)
12) 短延时
13) EN = 0 (LCD使能禁止)
14) 短延时
三、关于LCD控制库LiquidCrystal:
  LiquidCrystal是Arduino的官方库之一,他可以控制基于日立公司HD44780(或兼容)芯片集成的字符型LCD。该库可以通过四线或者八线模式控制LCD。
无疑,LiquidCrystal库可以使LCD的控制编程变得十分简单!!!
笔者在学习中,发现了一个比较完整的LiquidCrystal库的中文资料,链接如下:
下面,就一些常用的LiquidCrystal库函数做一个简单介绍:
1.LiquidCrystal()构造函数
2.begin()指定显示方式
3.clear()清屏,光标置于左上角
4.home()接下来的字符从左上角显示
5.setCursor(col,row)设置光标位置
6.print()LCD显示字符
四、Arduino下的LCD1602的8线驱动模式:
&1&优缺点:
 八线模式的优点是每位数据均从单独的数据线传输,因此数据传输速度快。但缺点也是显然的,需要占掉大量的端口。
&2&接线方式:
VL为液晶显示器对比度调整端,有条件的话,最好使用一个10K的电位器来调整对比度。限于条件,笔者通过反复调试,最后选择了4k电阻,效果也还可以。
&3&试验代码:
1.不使用LiquidCrystal库
1 /*Arduino在8位接法下不使用LiquidCrystal库
2 * 输出欢迎界面和Hello World!
3 * 作者:大大维
7 int RS = 12;
//数据/命令选择器引脚(RS)
8 int RW = 11;
//读/写选择器引脚(R/W)
9 int DB[] = {3, 4, 5, 6, 7, 8, 9, 10};
//使用数组来定义总线需要的管脚(D0-D7)
10 int Enable = 2;
12 void LcdCommandWrite(int value) {
// 定义所有引脚
int i = 0;
digitalWrite(RS, LOW);
digitalWrite(RW, LOW);
for (i=DB[0]; i &= RS; i++) //总线赋值
//这里的&是二进制的&与&运算。取指令码的最低位。
digitalWrite(i,value & 0x01);
value &&= 1;
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
31 void LcdDataWrite(int value) {
// 定义所有引脚
int i = 0;
digitalWrite(RS, HIGH);
digitalWrite(RW, LOW);
for (i=DB[0]; i &= DB[7]; i++) {
digitalWrite(i,value & 0x01);
value &&= 1;
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
48 void setup (void) {
int i = 0;
for (i=E i &= RS; i++) {
pinMode(i,OUTPUT);
delay(100);
// 短暂的停顿后初始化LCD
// 用于LCD控制需要
LcdCommandWrite(0x38);
// 设置为8-bit接口,2行显示,5x7文字大小
delay(20);
LcdCommandWrite(0x06);
  // 输入方式设定,自动增量,画面没有移位
delay(20);
LcdCommandWrite(0x0C);
  // 显示设置,开启显示屏,光标关,无闪烁
delay(20);
64 void loop (void) {
LcdCommandWrite(0x01);
  // 屏幕清空,光标位置归零
delay(10);
LcdCommandWrite(0x80+5);
  // 定义光标位置为第一行第五个位置
delay(10);
// 写入欢迎信息
LcdDataWrite('W');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('c');
LcdDataWrite('o');
LcdDataWrite('m');
LcdDataWrite('e');
delay(10);
LcdCommandWrite(0xc0+2);
  // 定义光标位置为第二行第二个位置
delay(10);
LcdDataWrite('I');
LcdDataWrite(' ');
LcdDataWrite('a');
LcdDataWrite('m');
LcdDataWrite(' ');
LcdDataWrite('D');
LcdDataWrite('a');
LcdDataWrite('D');
LcdDataWrite('a');
LcdDataWrite('W');
LcdDataWrite('e');
LcdDataWrite('i');
delay(3000);
LcdCommandWrite(0x01);
   // 屏幕清空,光标位置归零
delay(10);
LcdCommandWrite(0x80+2);
  //定义光标位置为第一行第二个位置
delay(10);
LcdDataWrite('H');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('l');
LcdDataWrite('o');
LcdDataWrite(' ');
LcdDataWrite('W');
LcdDataWrite('o');
LcdDataWrite('r');
LcdDataWrite('l');
LcdDataWrite('d');
LcdDataWrite('!');
delay(5000);
&看到上面的代码,是否觉得略显复杂?但要是使用了LiquidCrystal库,一切将变得十分简单!!!
2.使用LiquidCrystal库
1 /*Arduino在8位接法下使用LiquidCrystal库
2 * 输出欢迎界面和Hello World!
3 * 作者:大大维
6 #include&LiquidCrystal.h&
7 LiquidCrystal lcd(12,11,3,4,5,6,7,8,9,10);
   //初始化LCD
8 void setup(){
lcd.begin(16,2);
   //设置LCD为16列*2行
11 void loop(){
lcd.clear();
    //清屏操作
lcd.setCursor(5,0);
//设置光标位置为第一行,第六列
lcd.print("Welcome");
    //在LCD上输出信息
delay(10);
//延时程序
lcd.setCursor(2,1);
lcd.print("I am DaDaWei");
delay(3000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Hello World!");
delay(5000);
&4&试验展示:
五、Arduino下的LCD1602的四线驱动模式:
&1&优缺点:
 四线模式相对于八线模式的优点是占用的端口更少,减少了四条数据线,也就是说八位的数据需要通过四条线来发送,那么会导致四线模式比八线模式数据速度慢些。
&2&接线方式:
&3&试验代码:
&1.不使用LiquidCrystal库
1 /*Arduino在4位接法下不使用LiquidCrystal库
2 * 输出欢迎界面和Hello World!
3 * 作者:大大维
7 int RS = 12;
//数据/命令选择器引脚(RS)
8 int RW = 11;
//读/写选择器引脚(R/W)
9 int DB[] = {6, 7, 8, 9};
//使用数组来定义总线需要的管脚(D0-D7)
10 int Enable = 10;
12 void LcdCommandWrite(int value) {
// 定义所有引脚
int i = 0;
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
digitalWrite(RS, LOW);
digitalWrite(RW, LOW);
DB[0] DB[1] DB[2] DB[3]
int temp=value & 0xf0;//取指令高4位
for (i=DB[0]; i &= 9; i++)
if((temp & 0x80)!=0)//取指令最高位
digitalWrite(i,HIGH);
digitalWrite(i,LOW );
temp &&= 1;
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
temp=(value & 0x0f)&&4;
for (i=DB[0]; i &= 9; i++)
if((temp & 0x80)!=0)//取指令最高位
digitalWrite(i,HIGH);
digitalWrite(i,LOW );
temp &&= 1;
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
54 void LcdDataWrite(int value) {
// 定义所有引脚
int i = 0;
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
digitalWrite(RS, HIGH);
digitalWrite(RW, LOW);
int temp=value& 0xf0;
for (i=DB[0]; i &= 9; i++)
if((temp & 0x80)!=0)//取指令最高位
digitalWrite(i,HIGH);
digitalWrite(i,LOW );
temp &&= 1;
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
temp=(value & 0x0f)&&4;
for (i=DB[0]; i &= 9; i++)
if((temp & 0x80)!=0)//取指令最高位
digitalWrite(i,HIGH);
digitalWrite(i,LOW );
temp &&= 1;
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
// 延时1us
digitalWrite(Enable,LOW);
delayMicroseconds(1);
// 延时1us
90 void setup (void) {
int i = 0;
for (i=E i &= RS; i++) {
pinMode(i,OUTPUT);
delay(100);
// 短暂的停顿后初始化LCD
// 用于LCD控制需要
LcdCommandWrite(0x38);
// 设置为8-bit接口,2行显示,5x7文字大小
delay(20);
LcdCommandWrite(0x06);
// 输入方式设定,自动增量,画面没有移位
delay(20);
LcdCommandWrite(0x0C);
// 显示设置,开启显示屏,光标关,无闪烁
delay(20);
106 void loop (void) {
LcdCommandWrite(0x01);
// 屏幕清空,光标位置归零
delay(10);
LcdCommandWrite(0x80+5);
// 定义光标位置为第一行第五个位置
delay(10);
// 写入欢迎信息
LcdDataWrite('W');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('c');
LcdDataWrite('o');
LcdDataWrite('m');
LcdDataWrite('e');
delay(10);
LcdCommandWrite(0xc0+2);
// 定义光标位置为第二行第二个位置
delay(10);
LcdDataWrite('I');
LcdDataWrite(' ');
LcdDataWrite('a');
LcdDataWrite('m');
LcdDataWrite(' ');
LcdDataWrite('D');
LcdDataWrite('a');
LcdDataWrite('D');
LcdDataWrite('a');
LcdDataWrite('W');
LcdDataWrite('e');
LcdDataWrite('i');
delay(3000);
LcdCommandWrite(0x01);
// 屏幕清空,光标位置归零
delay(10);
LcdCommandWrite(0x80+2);
//定义光标位置为第一行第二个位置
delay(10);
LcdDataWrite('H');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('l');
LcdDataWrite('o');
LcdDataWrite(' ');
LcdDataWrite('W');
LcdDataWrite('o');
LcdDataWrite('r');
LcdDataWrite('l');
LcdDataWrite('d');
LcdDataWrite('!');
LcdCommandWrite(0xc0);
// 定义光标位置为第二行起始位置
delay(10);
LcdDataWrite('4');
LcdDataWrite('-');
LcdDataWrite('B');
LcdDataWrite('i');
LcdDataWrite('t');
LcdDataWrite('-');
LcdDataWrite('I');
LcdDataWrite('n');
LcdDataWrite('t');
LcdDataWrite('e');
LcdDataWrite('r');
LcdDataWrite('f');
LcdDataWrite('a');
LcdDataWrite('c');
LcdDataWrite('e');
delay(10);
delay(5000);
2.使用LiquidCrystal库
1 /*Arduino在4位接法下使用LiquidCrystal库
2 * 输出欢迎界面和Hello World!
3 * 作者:大大维
6 #include&LiquidCrystal.h&
7 LiquidCrystal lcd(13,12,11,10,9,8,7);
//初始化LCD
8 void setup(){
lcd.begin(16,2);
//设置LCD为16列*2行
11 void loop(){
lcd.clear();
//清屏操作
lcd.setCursor(5,0);
//设置光标位置为第一行,第六列
lcd.print("Welcome");
//在LCD上输出信息
delay(10);
//延时程序
lcd.setCursor(2,1);
lcd.print("I am DaDaWei");
delay(3000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Hello World!");
lcd.setCursor(0,1);
lcd.print("4-Bit-Interface");
delay(5000);
&4&试验展示:51单片机驱动1602液晶显示器的小例子
10:06:01来源: eefocus
首先附上的相关资料:
引脚功能:
1602采用标准的16脚接口,其中:
第1脚:VSS为地
第2脚:VCC接5V电源正极
第3脚:V0为对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会 产生&鬼影&,使用时可以通过一个10K的电位器调整对比度)。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。
第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极。
将DDRAM填满"20H",并且设定DDRAM的地址计数器(AC)到"00H"
设定DDRAM的地址计数器(AC)到"00H",并且将游标移到开头原点位置;这个指令不改变DDRAM 的内容
显示状态开/关
[D=1: 整体显示 ON][C=1: 游标ON]
[B=1:游标位置反白允许]
进入点设定
指定在数据的读取与写入时,设定游标的移动方向及指定显示的移位
游标或显示移位控制
设定游标的移动与显示的移位控制位;这个指令不改变DDRAM 的内容
[DL=0/1:4/8位数据]
[RE=0/1: 基本指令操作 / 扩充指令操作]
设定CGRAM地址
设定CGRAM 地址
设定DDRAM地址
设定DDRAM 地址(显示位址)
[第一行:80H-A7H]
[第二行:C0H-E7H]
读取忙标志和地址
读取忙标志(BF)可以确认内部动作是否完成,同时可以读出地址计数器(AC)的值
写数据到RAM
将数据D7&&D0写入到内部的RAM (DDRAM/CGRAM/IRAM/GRAM)
读出RAM的值
从内部RAM读取数据D7&&D0(DDRAM/CGRAM/IRAM/GRAM)
3.3V或5V工作电压,对比度可调
内含复位电路
提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能
有80字节显示数据存储器DDRAM
内建有192个5X7点阵的字型的字符发生器CGROM
8个可由用户自定义的5X7的字符发生器CGRAM
测试代码:
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^2;
sbit lcdrs=P3^0;
//数据命令选择端
sbit rw=P3^1;
uchar code table[]="xian shi 1";
//输入的字符
uchar code table1[]="xian shi 2";
//输入的字符
uchar num=0;
void delay(uint z)
for(x=z;x>0;x--)
for(y=110;y>0;y--);
void write_com(uchar com)//根据写时序图写出指令程序
void write_data(uchar date)//根据写时序图写出数据程序
void init()
lcden=0; //使能端为低电平
write_com(0x38);
/*显示模式设置
设置16*2显示
8位数据接口*/
write_com(0x0f);
/*显示开关及光标设置
D=1,开显示
D=0, 关显示
C=1,显示光标
C=0,不显示光标
B=1,光标闪烁
B=0,光标不闪烁*/
write_com(0x06);//地址指针自动+1且光标+1,写字符屏幕不会移动
write_com(0X01);
write_com(0X80);
void main()
for(num=0;num<10;num++)
//输入的字符数量,修改
write_data(table[num]);
delay(50);
write_com(0X80+0x40);
for(num=0;num<10;num++) //输入的字符数量,修改
write_data(table1[num]);
delay(50);
测试效果:
关键字:&&&&
编辑:什么鱼
引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
微信扫一扫加关注 论坛活动 E手掌握
微信扫一扫加关注
芯片资讯 锐利解读
大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。单片机控制LCD1602显示字符(测试通过)
> 单片机控制LCD1602显示字符(测试通过)
单片机控制LCD1602显示字符(测试通过)
本次测试的是常用LCD1602显示屏,操作流程很简单,但有些小问题要注意,如该LCD处理速度有些慢,单片机在发送控制指令时需要适当延时,否则可能操作失败。一、硬件简介本文引用地址:1>引脚介绍具体引脚如下:单片机需要操作的引脚有:RS、RW、E及DB0~72>指令介绍在这里,仅仅介绍下什么是CGRAM、什么是DDRAM?CGRAM:是用户自定义字符存放存储器,可以自己在指定地址定义字符DDRAM:是对应屏幕位置的存储器,设定了该地址,就确定了从屏幕什么位置开始显示字符二、软件部分#include#include#define DATA P0sbit RS=P2^6;sbit RW=P2^5;sbit EN=P2^7;unsigned char zifu[]={"Hello,World!0"};unsigned char wangzhi[]={"/"};void delayms(unsigned char m) //适当延时{while(m--){for(i=0;i<=250;i++){_nop_();}}}void WRITE_BYTE(unsigned char canshu) //写1个字节{RW=0;_nop_();_nop_();EN=1;_nop_();DATA=EN=0;_nop_();_nop_();}void main(){unsigned char *RS=0;WRITE_BYTE(1);//清屏delayms(10);//约延时23msWRITE_BYTE(2);//光标归位delayms(10);WRITE_BYTE(6);// AC自动增1,屏幕不动delayms(10);WRITE_BYTE(0x0F);//光标显示闪烁delayms(10);WRITE_BYTE(0x14);//光标右移delayms(10);WRITE_BYTE(0x38);//两行显示,5X7字符delayms(10);WRITE_BYTE(0x80);//设定DDRAM地址delayms(10);_nop_();point=while(*point!=)//Hello,world!,{RS=1;_nop_();WRITE_BYTE(*point);point=point+1;delayms(10);if(point==wangzhi+16){RS=0;WRITE_BYTE(0xC0);//设定DDRAM地址为下行第一个字符处delayms(10);}}while(1);}三、测试中问题1>在每条指令之后注意适当延时,不然操作出错2>本次测试中就不读忙标志位了,直接延时再操作基本能通过四、测试结果
分享给小伙伴们:
我来说两句……
最新技术贴
微信公众号二
微信公众号一}

我要回帖

更多关于 lcd1602液晶显示器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信