概要
工程文件及取模软件在文末链接领取!
在使用lcd1602的时候,经常会觉得自带的字库不够用。但是使用屏幕自带的字库能在一定程度上解决该问题!
技术细节
一,lcd1602的相关知识
我们这次使用的是普中的51开发板,lcd1602使用并口方式。主要使用到的是8根数据线,4根控制线。LCD1602的基础使用其实很简单,就是D0~D7传输数据,EN、RS、WR控制数据传输,VO调节对比度。
模块和单片机电路图连接如下
LCD1602的使用主要操作的就是他的DDRAM和CGRAM两个储存区域。CGRAM就是存放我们自定义字符的一个存储空间。DDRAM相当于是你屏幕的映射,你要显示什么就放在DDRAM里,屏幕会给你自动显示出来。DDRAM实际上有2行x40个字符的位置,屏幕优先显示前16列的数据。可以通过移屏的命令来看到后面的内容或者做成动画效果!
DDRAM像上图所示,我们只要通过命令把光标位置设置到上图框内所示地址,然后把要显示的数据写入即可显示成功。
光标的设置就是下图指令集的第8条,设置的代码如下所示
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40)); //因为第二行的DDRAM地址是从40开始的
}
}
LCD1602的指令集
要把显示的数据插入进光标指定的DDRAM中,首先要了解到由于数据都是D0~D7八位的,如果要显示一个“A”,肯定要对它进行编码确定一个八位的值。编码的格式即下图中的字模表,可以发现大写的“A”就是ascll码的0x40。大部分的字模都是和ascll一样的,如果我们要传一个A到LCD1602中去,那我们可以直接写'A',编译器会自动转换为ascll码的0x40,当然也可以直接按表上的写0x40进去。
LCD1602的字模表
到目前为止,我们已经知道如何在LCD1602任意位置上显示一个字符了。
流程就是先把光标位置通过写命令,指向我们想显示的DDRAM的位置上。接着再通过写数据,把要显示的字符写入进去。LCD1602就能显示上面字模表里任意的数据了。详细程序编写见下:
二、LCD1602程序详细编写
通过上述说明我们知道LCD1602的简易操作其实就两种形式,一个是写命令一个是写数据。其详细时序如下图所示:
图片看起来比较复杂,这里用文字加代码解释下就很简单了
1,写命令
让单片机的RS和RW引脚为低电平,接着把命令数据放到D0~D7端口上,再让EN引脚置高之后置低产生一个下降沿,就把数据写入lcd1602中了,是不是很简单?
其中延时函数是为了保证电平的建立,代码如下:
void LCD_Delay() //@1ms 11.0592MHz
{
unsigned char i, j;
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
2,写数据
写数据和命令其实是一样的,只是把命令数据替换成你需要的数据即可,代码如下
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
知道了这两个函数我们就已经可以灵活操作LCD1602了,例如我们要在第一行的第一列显示一个大写字母“A”,我们就应该先把光标指向第一行,然后再把'A'的字模相应编码写入即可。程序如下:
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
这个函数就应这样填写LCD_ShowChar(1,1,'A')或LCD_ShowChar(1,1,0x40)
应该注意上面多了个初始化程序,这是因为要想开启显示必须进行相关的设置,不懂得可以参照第一节的指令集进行分析。其他的显示函数在链接里都有,详情查看链接工程。
三、LCD1602自定义字符显示
如果只是会上面的,那也基本够用。但有时候我们想显示除了字模表里的字符,那就要使用到CGRAM来自定义字符了。
那如何进行自定义呢?我们看到指令集的第7条
CGRAM的格式为0 1 x x x x x x x刚好就是0~3F的64个字节,接着看到字模表的CGRAM列
他是只有8个位置可以自定义字符的,64/8的话刚好就是8个字符,每个字符占8个字节
知道这些后,我们要显示一个自定义字符也简单了,首先写命令指向CGRAM的一个位置,然后连续写8次数据,即可把我们的自定义字符写入字模表的0x00~0x08的位置上。显示的话就按其他字模显示的方式一样就可以了。
写自定义字符到字模表函数如下:
/**
* @brief LCD1602自定义字符
* @param Position 位置,范围:1~8
* @param Table 要显示的字符的数组名
* @retval 无
*/
void LCD_SetCustomChar(unsigned char Position,char *Table)
{
unsigned char i;
switch (Position)
{
case 1:
LCD_WriteCommand(0x40);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 2:
LCD_WriteCommand(0x48);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 3:
LCD_WriteCommand(0x50);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 4:
LCD_WriteCommand(0x58);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 5:
LCD_WriteCommand(0x60);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 6:
LCD_WriteCommand(0x68);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 7:
LCD_WriteCommand(0x70);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
case 8:
LCD_WriteCommand(0x78);
for(i=0;i<8;i++)
{
LCD_WriteData(Table[i]);
}
break;
}
}
显示自定义字符的函数如下:
/**
* @brief 在LCD1602指定位置上显示自定义字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Num 要显示的字符编号,范围:1~8
* @retval 无
*/
void LCD_ShowCustomChar(unsigned char Line,unsigned char Column,unsigned char Num)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Num-1);
}
例如:在屏幕任意位置显示我自定义的字符
#include <STC89C5xRC.H>
#include "LCD1602.h"
unsigned char table1[]={0x04,0x1F,0x04,0x1F,0x11,0x1F,0x0A,0x1B};//克
unsigned char table2[]={0x0A,0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x1B};//共
unsigned char table3[]={0x04,0x0A,0x11,0x04,0x04,0x04,0x04,0x04};//个
void main()
{
LCD_Init();
LCD_SetCustomChar(1,table1);//table1字模放CGROM1
LCD_SetCustomChar(2,table2);//table2字模放CGROM2
LCD_SetCustomChar(3,table3);//table3字模放CGROM3
LCD_ShowCustomChar(1,1,1);//在第1行第1列开始显示CGROM1
LCD_ShowCustomChar(2,3,2);//在第2行第3列开始显示CGROM2
LCD_ShowCustomChar(2,5,3);//在第2行第5列开始显示CGROM3
LCD_ShowString(1,4,"Hello World!");
while(1)
{
}
}
实际效果:
四、字模取模相关步骤
上面的字模通过table1[]等的数组进行储存,是因为我直接使用取模软件生成的,链接内自带相关软件,过程如下:
1,新建一个文字
2、点击选项进行相关设置,在格子内画上你想要的字符,(左键点亮,右键清除)最后点击生成字模即可复制到你的table[]数组中
注:严格参照该设置
总结:
相信通过该教程你已经学会了如何使用LCD1602的基础功能了。希望对你有所帮助,欢迎交流指正!
工程文件链接:
链接:https://pan.baidu.com/s/1e89qeOBmqtNZnGRnS1z1MQ
提取码:d1gm