目录
LCD1602显示屏介绍
引脚介绍
内部结构框图
?存储器
DDRAM储存器地址
?CGRAM与?CGROM的地址
时序介绍
LCD1602快捷指令?
LCD1602指令操作流程:
字符、字符串的显示
?各种进制的数字显示
在LCD1602上显示十进制数字
在LCD1602上显示十六进制数字
在LCD1602上显示二进制数字
LCD1602显示屏介绍
LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符
显示容量:16×2个字符,每个字符为5*7点阵
引脚介绍

内部结构框图

?存储器
DDRAM储存器地址

/**
* @brief LCD1602设置光标位置(将行,列转换为地址)
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16(Column-1)
* @retval 无
*/
//DB7置1进行DDRAM设置
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));//00H,01H,,,27H
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));//40H,41H,,,67H
}
}
?CGRAM与?CGROM的地址

时序介绍
赋值数据的时候直接将16进制数据赋值给P^0端口即可,不必和之前的I2C以及单线通信一样,用“&”一位一位的移位赋值。
?

LCD1602快捷指令?

?常用的指令主要是,移屏,光标移动(常用的已经用红色标识)
LCD1602指令操作流程:
初始化:
?????? 发送指令0x38????? //八位数据接口,两行显示,5*7点阵
?????? 发送指令0x0C????? //显示开,光标关,闪烁关
?????? 发送指令0x06????? //数据读写操作后,光标自动加一,画面不动
?????? 发送指令0x01????? //清屏
显示字符:
?????? 发送指令0x80|AC //设置光标位置
?????? 发送数据????????????? //发送要显示的字符数据
?????? 发送数据????????????? //发送要显示的字符数据
字符、字符串的显示
字符:根据一定规则建立的数字到字符的映射(ASCII码表)
?????? 例如:0x21=’!’,0x41=’A’,0x00=’\0’
?????? 定义方法:char x=‘A’;(等效于char x=0x41;)
字符数组:存储字符变量的一个数组
?????? 定义方法:char y[]={’A’, ’B’, ’C’};
????????????? (等效于char y[]={0x41,0x42,0x43}; )
字符串:在字符数组后加一个字符串结束标志,本质上是字符数组
?????? 定义方法:char z[]=”ABC”;(等效于char z[]={’A’, ’B’, ’C’, ’\0’};)
从上面的解释我们也发现了,在字符数组与字符串的区别在与两者等价于带有花括号的形式时,后者系统会自动补 ’\0’而前者不会。所以我们在设计显示字符串的函数时就可以遍历数组,最后以’\0’为标志停止循环即可
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
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]);//在模式设置的时候,光标会自动移动
}
}
但是对于一些特殊的符号,比如说单引号,在应用的时候,计算机可能不知道到底哪个单引号和哪个单引号是一对的,从而报错。这时候就要用到转译符号

?各种进制的数字显示
在LCD1602上显示十进制数字
通过之前字符显示的学习,我们可以触类旁通的联想到:把一个多位数字的每一位拆分出来,然后转化为字符的形式进行显示(我们在CGRAM与?CGROM的地址中发现,相应的数字确实要加上‘0’才能显示,也进一步验证了我们的猜想)
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;//解决Y=0的情况
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
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');
}//将数字表示为ASCLL表的形式,原因是(子模库)中是以ASCLL表的形式对应
}
我们也看到了,这个Number只能最大显示65535,那么如果我们想显示更大的数呢:实现的思路和之前定时器高位低位赋值相同。设高位为Number1,低位为Number2他们共同构成Number
那么在第一个显示函数上Number1=(Number/65535),在第二个显示函数上Number2=(Number%65535)这样就可以显示大于65535的数。
在LCD1602上显示十六进制数字
和显示十进制数字的方法大致相同,只是十六进制的每一位要判断是否大于10,大于10就用0~9的阿拉伯数字表示,大于10就用A,B,C,D,E,F来表示
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
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;//和10进制不一样的是,16进制数除16求余16得到不同位
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else//10以上显示的是ABCDEF,所以要先减去10
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
在LCD1602上显示二进制数字
和显示十进制数字的方法大致相同,只是进制为每2进1
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111(注意在c语言中不能直接写2进制数据,所以写16进制替换)
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
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');//和10进制不一样的是,2进制数除2求余2得到不同位
}
}
|