LCD1602的介绍
LCD1602是一种字符型液晶显示模块,通常用于嵌入式系统、单片机等领域。它由LCD(液晶显示屏)、HD44780控制驱动主电路及其扩展驱动电路、少量电阻、电容元件等组成。
LCD1602具有以下特点和功能:
- 显示能力:LCD1602可以同时显示两行,每行16个字符,共32个字符。
- 控制接口:通常使用8位数据总线D0-D7、RS、R/W、EN三个控制端口进行控制。
- 工作电压:一般工作电压为5V。
- 显示原理:利用液晶的物理特性,通过电压对其显示区域进行控制,从而显示出字符和简单图形。
- 硬件参数:LCD1602主要参数包括工作温度范围、显示区域尺寸、像素尺寸、视角等。
- 引脚功能:LCD1602的引脚包括VCC(电源正极)、GND(电源负极)、V0(液晶对比度调节)、RS(寄存器选择)、R/W(读/写选择)、EN(使能)、D0-D7(数据总线)、A(背光正极)、K(背光负极)等。
工作原理
LCD1602使用HD44780芯片作为控制器,通过与主控芯片(如单片机或微处理器)进行通信来控制液晶显示屏。
工作时,主控芯片向LCD1602发送命令和数据。在发送之前,需要设置RS引脚的电平来区分是发送命令还是发送数据。当RS为高电平时,表示发送的是数据;当RS为低电平时,表示发送的是命令。通过设置RW引脚的电平来区分是写入操作还是读取操作,当RW为高电平时,表示读取操作;当RW为低电平时,表示写入操作;
这里的数据输入是并行输入,操作就是直接将数据传入P0寄存器即可;
在发送命令或数据后,需要通过控制引脚中的E引脚来触发LCD1602对命令或数据进行处理。通过设置E引脚的上升沿或下降沿触发,将数据写入液晶单元并显示相应的内容。
此外,LCD1602通常还包含背光引脚,用于控制显示屏背光的开关。通过控制背光引脚的电平,可以使LCD1602的显示内容在不同的光照条件下更好地被观察到。
上图是内部的大致存储结构;上面说过这是一块字符型的LCD模块;我们输入的数字或者字符,都将通过ASCII码值的转换在字模库中找出对应的码值然后在屏幕进行显示;
时序结构
在时序结构中,我们要做有写数据和写指令的操作;
写指令:RS引脚置于高电平,表示要选择指令;RW置于低电平,表示选择写入;然后将对应的数据给到P0寄存器;最后将使能置高电平,置完需要进行延迟1ms;
输入的数据由控制器芯片将信号传递给液晶模块的每个像素点。延迟操作可以确保驱动信号在传递过程中达到稳定状态;当然LCD1602的也需要一定的响应时间。
写数据:将RS引脚置于低电平,其他操作与写指令一致;
代码:
//引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DATAPORT P0//延迟1ms函数
void Delay1ms() //@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}//LCD1602写入指令
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DATAPORT=Command;LCD_E=1;Delay1ms();LCD_E=0;Delay1ms();
}//LCD1602写入数据
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DATAPORT=Data;LCD_E=1;Delay1ms();LCD_E=0;Delay1ms();
}
LCD1602操作流程
这里我们只进行初始化和字符显示操作;
初始化:通过写入命令的操作,进行初始化;
void LCD_Init()
{LCD_WriteCommand(0x38);//功能设置:八位数据接口两行显示LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关LCD_WriteCommand(0x06);//读数据,写入操作后,光标自动加一LCD_WriteCommand(0x01);//清屏操作}
字符显示:将DDRAM的地址与写入的行列位置进行按位或,找到对应光标位置;
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));//0x80|AC ,设置光标位置}else{LCD_WriteCommand(0x80|(Column-1)+0x40);}LCD_WriteData(Char);//写入数据,一个字符一个字符进行写入
}
原代码
LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__LCD_Init();
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 Colunm,unsigned int Number,unsigned char lenth);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char lenth);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Lenth);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Lenth);
#endif
LCD1602.c
#include <REGX52.H>
#include<INTRINS.H>
//引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DATAPORT P0//延迟函数
void Delay1ms() //@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}//LCD1602写命令
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DATAPORT=Command;LCD_E=1;Delay1ms();LCD_E=0;Delay1ms();
}//LCD1602写数据
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DATAPORT=Data;LCD_E=1;Delay1ms();LCD_E=0;Delay1ms();
}//LCD1602初始化函数
void LCD_Init()
{LCD_WriteCommand(0x38);LCD_WriteCommand(0x0c);LCD_WriteCommand(0x06);LCD_WriteCommand(0x01);}//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显示字符
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}//LCD1602显示字符串
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++)//字符串的终止字符'\0'{LCD_WriteData(String[i]);}
}//返回值=X的Y次方
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}//LCD1602显示数字
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);//通过除和取余进行取数字对应的位数//由于取得是ASCII码值,对应的数字前面需要增加'0'字符}
}//显示有符号十进制所给数字
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char lenth)
{unsigned char i;unsigned int 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'+Number/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);}}}//在LCD1602位置显示二进制数字
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);}
}
main.c
#include <REGX52.H>
#include"LCD1602.h"void main()
{LCD_Init();LCD_ShowBinNum(1,1,10,4);LCD_ShowHexNum(1,6,255,3);LCD_ShowNum(2,1,789,4);
}
对于main.c的内容,只是对LCD1602进行测试,读者可以自己进行对应的尝试;