LCD接口(附8051LCD1602显示:源码+原理图)

LCD接口(附8051LCD1602显示:源码+原理图)

工程源码及原理图:链接:https://pan.baidu.com/s/1KgmiGkFdl_sFE5GTm5MSsQ?pwd=l1gp
提取码:l1gp

LCD(Liquid Crystal Display):又称液晶显示器

LCD引脚

LCD一共有14个引脚,如下图:

LCD接口(附8051LCD1602显示:源码+原理图)_第1张图片

以LCD1602为例:

LCD接口(附8051LCD1602显示:源码+原理图)_第2张图片

以下我们对引脚进行逐个解释:

VSS,VDD,VO

引脚 功能
VSS
VDD 电源正极(4.5~5.5V)
VO 对比度调节电压(一般接在可变电阻上以调节电压)

 

RS(寄存器选择)

数据/指令选择,1为数据,0为指令

若RS=0,选择指令代码寄存器,允许用户发送指令,如清屏,使光标返回初始位置。

若RS=1,选择数据寄存器,允许用户发送数据显示在LCD上

 

RW(read/write)

读/写选择,1为读,0为写

E(使能)

使能,1为数据有效,下降沿执行命令

D0~D7

数据输入/输出

A/K

A:背光灯电源正极

K:背光灯电源负极

 

其内部结构图如下:LCD接口(附8051LCD1602显示:源码+原理图)_第3张图片

数据显示在屏幕上的流程:

数据——>DDRAM——>字模库——>屏幕

DDRAM比屏幕显示内存更多以便实现滚动字符等的效果。

 

LCD1602指令集

LCD接口(附8051LCD1602显示:源码+原理图)_第4张图片

1.清屏指令( 0000 0001 )

1.清除液晶显示器,即将DDRAM的内容全部清除。
2.光标回到液晶屏左上方。
3.地址计数器(AC)的值设置为0。

2.光标归位指令(0000 001x)

1.把光标返回到液晶屏左上方。
2.把地址计数器(AC)的值设置为0。
3.保持DDRAM的内容不变。

3.模式设置指令(0000 01 I/D S)

设定每次写入一位数据后光标的移动方向,并且设定每次写入一个字符是否移动。
I/D:0写入新数据后光标左移,1写入新数据后光标右移。
S :0写入新数据后显示屏不移动,1写入新数据后显示屏整体右移一个字符。

4.显示开关控制指令(0000 1 D C B)

D:0显示关,1显示开。
C:0无光标,1有光标。
B:0光标不闪烁,1光标闪烁。

5.设定显示屏或光标移动方向指令(000 1 S/C R/L x x)

S/C R/L
0 0 光标左移一格,且AC减一。
0 1 光标右移一格,且AC加一。
1 0 显示器字符全部左移一格,光标不动。
1 1 显示器字符全部右移一格,光标不动。

6.功能设定指令(00 1 DL N F x x)

DL:0数据总线为4位,1数据总线为8位。
N: 0显示 1 行,1显示 2 行。
F: 0 58字符点阵,1 510字符点阵。

7.设定CGRAM地址指令(01 aaaaaa)6位地址

8.设定DDRAM地址指令(1 aaaaaaa)7位地址

9.读取忙信号或AC地址指令(BF aaaaaaa)

BF:0空闲,1忙。
aaaaaaa:读取AC地址。

10.数据写入DDRAM或CGRAM指令

11.从DDRAM或CGRAM读出数据指令

 

 

函数功能实现

初始化

发送指令0x38 //八位数据接口,两行显示,5*7点阵

发送指令0x0C //显示开,光标关,闪烁关

发送指令0x06 //数据读写操作后,光标自动加一,画面不动

发送指令0x01 //清屏

void LCD_Init(void)
{
	LCD_WriteCommand(0x38);
	LCD_WriteCommand(0x0C);
	LCD_WriteCommand(0x06);
	LCD_WriteCommand(0x01);
}

 

LCD1602写命令

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();
}

LCD1602写数据

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();
}

LCD1602设置光标位置

void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else
	{
		LCD_WriteCommand(0x80|(Column-1)+0x40);
	}
}

在LCD1602指定位置开始显示所给字符串

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • String 要显示的字符串
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]);
	}
}

在LCD1602指定位置开始显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:0~65535
  • Length 要显示数字的长度,范围:1~5
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);
	}
}

在LCD1602指定位置开始以有符号十进制显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:-32768~32767
  • Length 要显示数字的长度,范围:1~5
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	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);
	}
}

在LCD1602指定位置开始以十六进制显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:0~0xFFFF
  • Length 要显示数字的长度,范围:1~4
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;
		if(SingleNumber<10)
		{
			LCD_WriteData('0'+SingleNumber);
		}
		else
		{
			LCD_WriteData('A'+SingleNumber-10);
		}
	}
}

在LCD1602指定位置开始以二进制显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:0~1111 1111 1111 1111
  • Length 要显示数字的长度,范围:1~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);
	}
}

 

在LCD1602显示姓名学号

#include 

sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_E=P2^2;
#define LCD_DataPort P0

void Delay(unsigned int xms);

void LCD_Init(void);
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_WriteCommand(unsigned char Command);

void main()
{
	LCD_Init();						//LCD初始化

	LCD_ShowString(1,1,"yourname");	//第一行第一列开始显示名字
	LCD_ShowNum(2,1,12138,5);			//第二行第一列显示12138
	LCD_ShowNum(2,6,12138,5);			//第二行第六列开始显示12138
	
	while(1)
	{
	}
}

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

void LCD_Delay()		//@12.000MHz 1ms
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

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_Init(void)
{
	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_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_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);
	}
}

void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	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);
	}
}

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;
		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 Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
	}
}




LCD接口(附8051LCD1602显示:源码+原理图)_第5张图片

你可能感兴趣的:(单片机,51单片机)