前言
本篇文章属于STC89C52单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。
一、LCD1602介绍
二、引脚及应用电路
E,使能,先把其它引脚的数据写好,再给E置1使数据有效,然后再给E置0,就在这个下降沿开始执行命令
三、内部结构框图
字模库相当于数码管的段码表,写入的数据是先放入DDRAM(数据显示区),然后通过字模库的译码,显示在屏幕上,数据显示区比屏幕更长,可以用来实现流动字幕的效果。
四、存储器结构
DDRAM里的地址后的H表示是十六进制,字模库里字符的地址就是对应的十六进制的ASCII码
五、时序结构
先根据需要设置RS,RS是1为数据,是0为指令,R/W是,1为读,0为写,DB0-DB7就是要写入的数据或指令,E最后使能
六、LCD指令集
七、LCD操作流程
其中要注意的是,设置光标位置是发送指令0x80|AC,AC就是DDRAM的地址,但要保证其最高位是1,才能保证发出的指令是DDRAM地址设置
八、LCD功能函数的实现
主要是LCD1602.c文件的撰写
#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() //@11.0592MHz 1ms
{
unsigned char i, j;
i = 2;
j = 199;
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();
}
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();
}
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);
}
}
void LCD_Init(void)
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
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 Lenth)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Lenth;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);
}
}
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Lenth)
{
unsigned char i;
unsigned char Number1;
LCD_SetCursor(Line,Column);
if (Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Lenth;i>0;i--)
{
LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);
}
}
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Lenth)
{
unsigned char i;
unsigned char SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Lenth;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if (SingleNumber<10)
{
LCD_WriteData('0'+SingleNumber);
}
else
{
LCD_WriteData('A'+SingleNumber-10);
}
}
}
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Lenth)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Lenth;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
}
}
首先是两个基本函数,LCD_WriteCommand(写入命令)和LCD_WriteData(写入数据),根据基本的时序结构来操作即可
然后是LCD_SetCursor,这是用来调整光标位置的,来确定写入的位置
然后是LCD_Init,这是LCD的初始化指令,可以通过写入指令来达到清屏的目的
然后是显示函数的基本逻辑就是,先发送指令来设置光标位置,然后再进行写入数据,写入数据前要对数据进行一定的处理。