51单片机学习--LCD模块使用
常见的液晶显示屏模块 LCD1602 LCD12864
LCD1602
LCD1602模块
工业字符型液晶。1602是指LCD显示的内容为16X2,即可以显示两行,每行16个字符.
特殊接口说明:
- RS:寄存器选择输入端
- RS=1:指向数据寄存器
- RS=0:指向指令寄存器
- RW:读写控制输入端
- RW=0:写操作 RW=1:读操作
- E:使能信号输入端,读操作时,高电平有效;写操作时,下降沿有效;
初始化过程
第一步:写指令38H,显示模式设置;
第二步:写指令08H,显示关闭;
第三步;写指令01H,显示清屏;
第四步:写指令06H,显示光标移动设置;
第五步:写指令0CH,显示光标开及光标设置
硬件电路
软件代码
#include"reg51.h"//51单片机头文件
/*相关引脚的定义*///该部分可以自己去定义,我是学习51单片机时选择普中单片机开发板。
sbit rs=P2^6; //命令/数据选择
sbit rw=P2^5; //读写口
sbit e=P2^7; //锁存控制
/*函数声明*/
void LCD1602_SetArea(unsigned char X,unsigned char Y);
void LCD1602_ShowChar(unsigned char X,unsigned char Y,unsigned char Char);
void LCD1602_ShowString(unsigned char X,unsigned char Y,unsigned char *String);
void LCD1602_ShowArray(unsigned char X,unsigned char Y,unsigned char *Array,unsigned char Count);
void LCD1602_ShowNumber_Integer(unsigned char X,unsigned char Y,int IntegerNumber,unsigned char Count);
void InitLCD();
/*延迟函数的定义*/
void DELAY_nUS(unsigned int Time)
{
while(--Time);
}
void DELAY_nMS(unsigned int time)
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<939;j++);
}
//向LCD写一命令
void wcode(unsigned char t)
{
rs=0; // 写的是命令
rw=0; // 写状态
e=1; //使能
P0=t; //写入命令
DELAY_nMS(2); //等待写入,如果时间太短,会导致液晶无法显示
e=0; //数据的锁定
}
//向LCD写一数据
void wdata(unsigned char t)
{
rs=1; // 写的是数据
rw=0; // 写状态
e=1; //使能
P0=t; //写入数据
DELAY_nMS(2); //等待写入,如果时间太短,会导致液晶无法显示
e=0; //数据的锁定
}
//LCD设置坐标位置
void LCD1602_SetArea(unsigned char X,unsigned char Y)
{
switch(Y)
{
case 0: wcode(0x80 + X); break;
case 1: wcode(0xC0 + X); break;
default:break;
}
}
//LCD显示字符
void LCD1602_ShowChar(unsigned char X,unsigned char Y,unsigned char Char)
{
LCD1602_SetArea(X,Y); // 设置显示坐标
wdata(Char); // 显示指定字符
}
//LCD显示字符串
void LCD1602_ShowString(unsigned char X,unsigned char Y,unsigned char *String)
{
LCD1602_SetArea(X,Y); // 设置显示坐标
while(*String)
{
wdata(*String);
String++;
}
}
//LCD显示数组
void LCD1602_ShowArray(unsigned char X,unsigned char Y,unsigned char *Array,unsigned char Count)
{
unsigned char i; // 定义局部变量,用于函数循环计数
LCD1602_SetArea(X,Y); // 设置显示坐标
for(i=0; i<Count; i++)
{
wdata(Array[i]);
}
}
//LCD显示有符号的整形数字
void LCD1602_ShowNumber_Integer(unsigned char X,unsigned char Y,int IntegerNumber,unsigned char Count)
{
unsigned char Number_Integer_Array[5]={
0};
//----------------------------------------------------------------------------------------------
// 判断 整型数字正负
//----------------------------------------------------------------------------------------------
if(IntegerNumber < 0)
{
IntegerNumber=0 - IntegerNumber;
LCD1602_ShowChar(X, Y, '-');
}
else
{
LCD1602_ShowChar(X, Y, '+');
}
//----------------------------------------------------------------------------------------------
// 限制 显示字符数
//----------------------------------------------------------------------------------------------
if(Count > 5)
{
Count = 5;
}
Number_Integer_Array[0] = (IntegerNumber / 10000) % 10 + 0x30;
Number_Integer_Array[1] = (IntegerNumber / 1000 ) % 10 + 0x30;
Number_Integer_Array[2] = (IntegerNumber / 100 ) % 10 + 0x30;
Number_Integer_Array[3] = (IntegerNumber / 10 ) % 10 + 0x30;
Number_Integer_Array[4] = (IntegerNumber / 1 ) % 10 + 0x30;
LCD1602_ShowArray(X+1,Y,&(Number_Integer_Array+(5-Count)),Count);
}
/*******************************************************************************
* 函 数 名 : Display_Unsignedint()
* 函数功能 : 显示无符号整形
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LCD1602_ShowNumber_UnsignedInt(unsigned char x,unsigned char y,unsigned int Number,unsigned char Count)
{
unsigned char NumbArray[6]={
0};
NumbArray[0]=(Number/10000)%10+0x30;
NumbArray[1]=(Number/1000) %10+0x30;
NumbArray[2]=(Number/100) %10+0x30;
NumbArray[3]=(Number/10) %10+0x30;
NumbArray[4]=(Number/1) %10+0x30;
NumbArray[5]= 0;
LCD1602_ShowString(x,y,&NumbArray[5-Count]);
}
/*******************************************************************************
* 函 数 名 : Display_Float()
* 函数功能 : 显示浮点数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LCD1602_Display_Float(unsigned char x,
unsigned char y,
float Number,
unsigned char Count1,
unsigned char Count2)
{
unsigned char NumberArray[11]={
0};
unsigned int Number_Integer = 0;
unsigned int Number_Decimal = 0;
float Number_Temp;
Number_Temp = Number;
if(Number_Temp < 0)
{
Number_Temp= 0 - Number_Temp;
}
Number_Integer = (unsigned int)(Number_Temp);
Number_Decimal = (unsigned short)((Number_Temp - Number_Integer + 0.0005) * 1e3);
NumberArray[ 0] = '+';
NumberArray[ 1] = Number_Integer/10000 % 10 + 0x30;
NumberArray[ 2] = Number_Integer/ 1000 % 10 + 0x30;
NumberArray[ 3] = Number_Integer/ 100 % 10 + 0x30;
NumberArray[ 4] = Number_Integer/ 10 % 10 + 0x30;
NumberArray[ 5] = Number_Integer/ 1 % 10 + 0x30;
NumberArray[ 6] ='.';
NumberArray[ 7] = Number_Decimal/ 100 % 10 + 0x30;
NumberArray[ 8] = Number_Decimal/ 10 % 10 + 0x30;
NumberArray[ 9] = Number_Decimal/ 1 % 10 + 0x30;
NumberArray[10] = 0;
if(Number>0)
{
NumberArray[5-Count1] = '+';
}
else
{
NumberArray[5-Count1] = '-';
}
NumberArray[7+Count2] = 0;
LCD1602_ShowString(x, y, &NumberArray[5-Count1]);
}
//LCD初始化
void InitLCD()
{
wcode(0x01); //清屏
wcode(0x06); //输入方式控制,增量光标不移位
wcode(0x0e); //显示开关控制
wcode(0x38); //功能设定:设置16x2显示,5x7显示,8位数据接口
}
/*******************************************************************************
* 函 数 名 : main()
* 函数功能 :主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
InitLCD();
while(1)
{
LCD1602_ShowString(0,0,"hello mcu");
LCD1602_Display_Float(0,1,123.4,3,1);
}
}
LCD12864模块
12864LCD属于点阵图形液晶显示模块,不但能显示字符,还能显示汉字和图形,分带汉字库和不带那字库两种,价格也有差别。带汉字库的12864LCD使用起来非常方便,不需要编写复杂的汉字显示程序,只要按时序写入两个字节的汉字机内码,汉字就能显示出来了,驱动程序简单许多。本文例程就是基于带汉字库的12864液晶显示模块。DM12864M 汉字图形点阵液晶显示模块,可显示汉字及图形,内置 8192 个中文汉字(16X16 点阵)、128个字符 64X256 点阵显示 RAM。
12864有两种工作模式。
(1)文本工作模式
整屏平均分成32个显示区(每个显示区是16X16点阵),每个显示区可显示一个中文,每个显示区可显示两个英文ASCII字符。下图为汉字显示坐标即地址。
(2)绘图工作模式
整屏按水平方向每16个点分为一组,所以整屏共有8192/16=512组,每次可控制任意一组的16个点。图形显示坐标:水平方向 X—以字节单位,垂直方向 Y—以位为单位。
12864的硬件接口
软件代码
#include"reg51.h"
/*********************************************************************************************************************************
实验名称:普中单片机12864的使用
实验效果:倒计时100显示
****************************************************************************************/
/**********************************************************************************************************
端口定义
************************************************************************************************************/
sbit RS=P2^6; //命令/数据选择
sbit RW=P2^5; //读写口
sbit E=P2^7; //锁存控制
sbit RES = P2^0;
sbit PSB = P2^2;
/**********************************************************************************************************
函数声明
************************************************************************************************************/
void InitLCD(void);
void Display_Char(unsigned char x,unsigned char y,unsigned char Char);
void Display_String(unsigned char x,unsigned char y,unsigned char *s);
void Display_UnsignedInt(unsigned char x,
unsigned char y,
unsigned int Number,
unsigned char Count);
void Display_SignedInt(unsigned char x,
unsigned char y,
signed int Number,
unsigned char Count) ;
void Display_Float(unsigned char x,
unsigned char y,
float Number,
unsigned char Count1,
unsigned char Count2);
void DELAY_nUS(unsigned int Time);
void DELAY_nMS(unsigned int time);
void delay(unsigned int time);
/**********************************************************************
函数主体部分
***************************************************************************/
void DELAY_nUS(unsigned int Time)
{
while(--Time);
}
void DELAY_nMS(unsigned int time)
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<939;j++);
}
void delay(unsigned int time) //int型数据为16位,所以最大值为65535
{
//0.1ms
unsigned int i,j; //定义变量i,j,用于循环语句
for(i=0;i<time;i++) //for循环,循环50*time次
for(j=0;j<50;j++); //for循环,循环50次
}
//查忙
void checkbusy(void)
{
RS=0;
RW=1;
E=1;
while((P0&0x80)==0x80);
E=0;
}
void wcode(unsigned char cmdcode)
{
checkbusy();
RS=0;
RW=0;
E=1;
P0=cmdcode;
delay(10);
E=0;
}
void wdata(unsigned char dispdata)
{
checkbusy();
RS=1;
RW=0;
E=1;
P0=dispdata;
delay(10);
E=0;
}
void InitLCD(void)
{
PSB=1;
RES=0;
delay(10);
RES=1;
wcode(0x30);
wcode(0x0c);
wcode(0x01);
wcode(0x06);
}
void Display_Char(unsigned char x,unsigned char y,unsigned char Char)
{
switch(y)
{
case 0: wcode(0x80+x);break;
case 1: wcode(0x90+x);break;
case 2: wcode(0x88+x);break;
case 3: wcode(0x98+x);break;
default:break;
}
wdata(Char);
}
void Display_String(unsigned char x,unsigned char y,unsigned char *s)
{
switch(y)
{
case 0: wcode(0x80+x);break;
case 1: wcode(0x90+x);break;
case 2: wcode(0x88+x);break;
case 3: wcode(0x98+x);break;
default:break;
}
while(*s>0)
{
wdata(*s);
delay(10);
s++;
}
}
void Display_UnsignedInt(unsigned char x,unsigned char y,unsigned int Number,unsigned char Count)
{
unsigned char NumbArray[6]={
0};
NumbArray[0]=(Number/10000)%10+0x30;
NumbArray[1]=(Number/1000) %10+0x30;
NumbArray[2]=(Number/100) %10+0x30;
NumbArray[3]=(Number/10) %10+0x30;
NumbArray[4]=(Number/1) %10+0x30;
NumbArray[5]= 0;
Display_String(x,y,&NumbArray[5-Count]);
}
void Display_SignedInt(unsigned char x,
unsigned char y,
signed int Number,
unsigned char Count)
{
unsigned char NumberArray[7]={
0};
signed int Number_Temp;
Number_Temp = Number;
if(Number_Temp<0)
{
Number_Temp = 0 - Number_Temp;
}
NumberArray[0]='+';
NumberArray[1]=(Number_Temp/10000)%10+0x30;
NumberArray[2]=(Number_Temp/1000) %10+0x30;
NumberArray[3]=(Number_Temp/100) %10+0x30;
NumberArray[4]=(Number_Temp/10) %10+0x30;
NumberArray[5]=(Number_Temp/1) %10+0x30;
NumberArray[6]=0;
if(Number>0)
{
NumberArray[5-Count] = '+';
}
else
{
NumberArray[5-Count] = '-';
}
Display_String(x, y, &NumberArray[5-Count]);
}
void Display_Float(unsigned char x,
unsigned char y,
float Number,
unsigned char Count1,
unsigned char Count2)
{
unsigned char NumberArray[11]={
0};
unsigned int Number_Integer = 0;
unsigned int Number_Decimal = 0;
float Number_Temp;
Number_Temp = Number;
if(Number_Temp < 0)
{
Number_Temp= 0 - Number_Temp;
}
Number_Integer = (unsigned int)(Number_Temp);
Number_Decimal = (unsigned short)((Number_Temp - Number_Integer + 0.0005) * 1e3);
NumberArray[ 0] = '+';
NumberArray[ 1] = Number_Integer/10000 % 10 + 0x30;
NumberArray[ 2] = Number_Integer/ 1000 % 10 + 0x30;
NumberArray[ 3] = Number_Integer/ 100 % 10 + 0x30;
NumberArray[ 4] = Number_Integer/ 10 % 10 + 0x30;
NumberArray[ 5] = Number_Integer/ 1 % 10 + 0x30;
NumberArray[ 6] ='.';
NumberArray[ 7] = Number_Decimal/ 100 % 10 + 0x30;
NumberArray[ 8] = Number_Decimal/ 10 % 10 + 0x30;
NumberArray[ 9] = Number_Decimal/ 1 % 10 + 0x30;
NumberArray[10] = 0;
if(Number>0)
{
NumberArray[5-Count1] = '+';
}
else
{
NumberArray[5-Count1] = '-';
}
NumberArray[7+Count2] = 0;
Display_String(x, y, &NumberArray[5-Count1]);
}
void main()
{
int i;
InitLCD();
while(1)
{
for(i=100;i>0;i--)
{
Display_SignedInt(0,0,i,3);
DELAY_nMS(500);
}
}
}