1. 常见的LCD1602函数
下文Code1是LCD1602的常见函数,来自b站的up:江协科技。这里就不介绍如何使用了,感兴趣的可以去up那里看看。
#include <REGX51.H>
#include <intrins.h>
//Wiring Mode 接线方式
#define LCD_DataPort P0
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P1^2;
void LCD_Delay()
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
// 写入命令
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
// 写入数据
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort = Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=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));
}
}
// LCD初始化
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
// LCD显示一个字符,第Line行,第Column列
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
// LCD显示字符串,第Line行,第Column列开始
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
// 清空屏幕:写入空格
void LCD_ClearAll()
{
LCD_ShowString(1,1," ");
LCD_ShowString(2,1," ");
}
//
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
// LCD显示一个正数(0~65535):第Line行,第Column列开始,展示Number,长度为Lenght:(1,1,25633,7) -> 0025633
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(Number/LCD_Pow(10,i-1)%10+'0');
}
}
// LCD显示一个带符号数字
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(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,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
// 二进制数
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(Number/LCD_Pow(2,i-1)%2+'0');
}
}
Code1
2. 生成特殊字符的编码。
这里将简要介绍如何生成特殊字符的编码,以“我水杯”为例。首先打开LCD1602的字模软件,一个一个地点出想要的字符(如图1),然后转化成十六进制,储存在数组LCD_SCC[]中(如Code2),其中SCC(Special Chinese Characters)表示为特殊中文字符。
图1
code unsigned char LCD_SCC[] ={
0x02,0x0C,0x02,0x1F,0x02,0x02,0x14,0x08,
0x00,0x02,0x09,0x1E,0x08,0x0A,0x04,0x0B,
0x01,0x01,0x0D,0x03,0x05,0x09,0x11,0x02,
0x00,0x04,0x08,0x10,0x08,0x04,0x03,0x00,
0x04,0x04,0x1F,0x0E,0x15,0x05,0x05,0x04,
0x00,0x1F,0x04,0x04,0x0E,0x15,0x05,0x04,
};
Code2
3. 将特殊字符写入LCD的RAM区。
LCD的ROM区在出场时已经写好,保存着常用的字符(如图2)。ROM不要更改,LCD内部还留有8个RAM区供使用者定义特殊字符。我们就是要将自定义的特殊字符写入LCD的RAM区域,然后读出显示。
图2:LCD内部RAM和ROM
对此,我们定义一个函数LCD_SCC_Init,用于将LCD_SCC[]中的编码输入到LCD的RAM中。具体做法很简单,我们首先需要选中LCD1602的RAM区域的具体某一行,然后写入数据。LCD_SCC_Init如Code3。
void LCD_SCC_Init()
{
unsigned char i=0;
for(i=0; i<SCC_num*8; i++)
{
LCD_WriteCommand(0x40+i);
LCD_WriteData(LCD_SCC[i]);
}
}
Code3
4. 在屏幕上显示特殊字符
初始化之后,我们需要读出数据显示在屏幕上,这里我们定义了一个函数LCD_ShowSCC,如Code4所示。它的内容和Code1中的LCD_ShowChar是完全一样的,即LCD_ShowSCC(1,1,0)和LCD_ShowChar(1,1,0)的结果完全一样。额外定义一个函数只是为了功能上的区分。
// LCD展示“一个”特殊字符:第Line行,第Column列,第Char(0~8)个字符
void LCD_ShowSCC(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line, Column);
LCD_WriteData(Char);
}
Code4
在main函数中调用对应的函数即可显示特殊字符了,如Code5。实现效果如图3。
void main()
{
LCD_Init(); //初始化LCD
LCD_SCC_Init(); //初始化特殊函数
LCD_ShowSCC(1,1,0); //显示
LCD_ShowSCC(1,2,1); //显示
LCD_ShowSCC(1,3,2); //显示
LCD_ShowSCC(1,4,3); //显示
LCD_ShowSCC(1,5,4); //显示
LCD_ShowSCC(1,6,5); //显示
while(1)
{
}
}
Code5
图3
5. 代码整合
LCD.c和LCD.h分别如Code6和Code7所示。注意:(1)请根据手上开发板的接线方式修改LCD.c;(2)请修改SCC_num,其中SCC_num<=8;
#include <REGX51.H>
#include <intrins.h>
//Wiring Mode 接线方式
#define LCD_DataPort P0
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P1^2;
// Define of Special Chinese Characters 特殊字符定义
#define SCC_num 6 //Special Chinese Characters num 共num个特殊字符
// LCD Special Chinese Characters
code unsigned char LCD_SCC[] ={
0x02,0x0C,0x02,0x1F,0x02,0x02,0x14,0x08,
0x00,0x02,0x09,0x1E,0x08,0x0A,0x04,0x0B,
0x01,0x01,0x0D,0x03,0x05,0x09,0x11,0x02,
0x00,0x04,0x08,0x10,0x08,0x04,0x03,0x00,
0x04,0x04,0x1F,0x0E,0x15,0x05,0x05,0x04,
0x00,0x1F,0x04,0x04,0x0E,0x15,0x05,0x04
};
void LCD_Delay()
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
// 写入命令
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
// 写入数据
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort = Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=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));
}
}
// LCD初始化
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
// LCD显示一个字符,第Line行,第Column列
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
// LCD显示字符串,第Line行,第Column列开始
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
// 清空屏幕:写入空格
void LCD_ClearAll()
{
LCD_ShowString(1,1," ");
LCD_ShowString(2,1," ");
}
//
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
// LCD显示一个正数(0~65535):第Line行,第Column列开始,展示Number,长度为Lenght:(1,1,25633,7) -> 0025633
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(Number/LCD_Pow(10,i-1)%10+'0');
}
}
// LCD显示一个带符号数字
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(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,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
// 二进制数
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(Number/LCD_Pow(2,i-1)%2+'0');
}
}
// Initialize Special Chinese Characters 特殊字符初始化
void LCD_SCC_Init()
{
unsigned char i=0;
for(i=0; i<SCC_num*8; i++)
{
LCD_WriteCommand(0x40+i);
LCD_WriteData(LCD_SCC[i]);
}
//另一种方法
// unsigned char i=0,j=0;
// for(i=0;i<SCC_num;i++)
// {
// for(j=0;j<8;j++)
// {
// LCD_WriteCommand(0x40+(i<<3)+j);
// LCD_WriteData(LCD_SCC[i*8+j]);
// }
// }
}
// LCD展示“一个”特殊字符:第Line行,第Column列,第Char(0~7)个字符
void LCD_ShowSCC(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line, Column);
LCD_WriteData(Char);
}
Code6
#ifndef __LCD1602_H__
#define __LCD1602_H__
// Common Functions 普通函数
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ClearAll();
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);
// Functions of Special Chinese Characters 特殊字符函数
void LCD_SCC_Init();
void LCD_ShowSCC(unsigned char Line,unsigned char Column,unsigned char Char);
#endif
Code7