LCD1602
介绍
LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符,其显示容量:16×2个字符,每个字符为5*7点阵(实际为5*8的点阵,只是字符占据5*7)1602是由其能显示的字符数命名的数字。
LCD1602是有自己单独的芯片,自带扫描功能。
引脚及应用电路
内部结构
CGRAM+CGROM(Character Generator,字模生成):字模库,其中RAM是可写入的区域,相当于自己创造一个字符,比如创造一个右上角是句号的字符等。ROM为不可写入区域,
DDRAM(Data Display RAM,数据显示RAM)为数据显示区,写入的数据都存储进该存储单元中,并且通过在字模库中查找,最终显示在屏幕上。但是需要用十六进制进行转换。
数据显示区为40*2,而屏幕区为16*2,这说明在DDRAM中的数据不一定能够在屏幕中全部显示出来,如果想全部显示,就需要一些指令。
控制器部分的AC:光标位置,相当于在数据显示区的特定区域写入内容。(可以通过指令确定AC位置)
时序结构
读时序与写时序类似,但是这里不需要读,只需要写入数据即可。上图中的交叉部分表示要进行填写数据
首先将RS设置(1为数据,0为指令),接着将RW置0(为写选择),然后将DB0~DB7填入字节数据,之后将E拉高,传输数据,最后再将E拉低,完成数据传输。
LCD1602指令集以及操作流程
LCD1602代码
#include <REGX52.H>
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DataPort P0
void LCD_Delay() //@12.000MHz 1ms
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_E=1;
LCD_Delay(); //因为时间间隔过短可能导致数据传输未完成
LCD_E=0;
LCD_Delay(); //因为时间间隔过短可能导致LCD没处理完成程序
}
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_E=1;
LCD_Delay(); //因为时间间隔过短可能导致数据传输未完成
LCD_E=0;
LCD_Delay(); //因为时间间隔过短可能导致LCD没处理完成程序
}
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else
{
LCD_WriteCommand(0x80|(Column-1)+0x40);
}
}
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10); //这里用字符0加进去,是为了将数字转换为字符数字
}
}
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1; //利用存储位更大的变量,使得对负数转正的时候,不会出现-32768转换正数出现越界情况
LCD_SetCursor(Line,Column);
if(Number>=0) //字符显示
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10); //这里用字符0加进去,是为了将数字转换为字符数字
}
}
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
unsigned char SingleNumber; //使用中间变量,使得十六进制的字母能够显示出来
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16; //原理与十进制数相同,每隔16进一
if(SingleNumber<10)
{
LCD_WriteData('0'+SingleNumber); //这里用字符0加进去,是为了将数字转换为字符数字
}
else
{
LCD_WriteData('A'+SingleNumber-10); //这里用字符A加进去,是为了将数字转换为十六进制字母,且减去10,取出到16前的字母数字
}
}
}
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
}
}
主函数代码
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
void main()
{
LCD_Init();
LCD_ShowChar(1,1,'A');
LCD_ShowString(1,3,"Hello");
LCD_ShowNum(1,9,66,2);
LCD_ShowSignedNum(1,12,-88,2);
LCD_ShowHexNum(2,1,0xA5,2);
LCD_ShowBinNum(2,4,0xA5,8);
LCD_ShowChar(2,13,0xDF); //显示摄氏度符号的一个句号
LCD_ShowChar(2,14,'C');
LCD_ShowString(1,16,"Welcome to China!");
while(1)
{
LCD_WriteCommand(0x18);
Delay(500);
}
}