单片机C语言实例:18、LCD1602液晶显示

这篇具有很好参考价值的文章主要介绍了单片机C语言实例:18、LCD1602液晶显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 LCD1602的显示原理

学单片机的小朋友应该都见过这个显示器--LCD1602,这是最古老最简单的显示屏,上世纪80年代的产物。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

它显示的图案如下所示

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

显示部分放大就是下面这样 ,像素就是一个个小方块,相当于描点法绘图了。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

如果把所有像素全部显示出来就是下面这样,全部是小黑点

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 全部点亮的像素点如下所示,16列,2行,这就是1602名字的来历

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

每个显示区域又可以细分为35个像素,7行5列

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 整个屏幕就是35*16*2 = 1120个像素单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

要想搞清楚这1120个像素的控制,就得先明白一个像素是这么控制的。显示屏的最下面是一层LED背光板,

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

只要通上电就会发光

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

在背光板上铺上一层液晶,每一小块的液晶就可以控制一个像素点

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

当不给液晶施加电压,液晶就是透明的,给某一块液晶施加电压后,就不透光了,看到的就是一个小黑点,常见的LCD背光有白光、蓝光、绿光,所以大家一般看到的要么是黑点,要么是背光。控制像素点就是控制他所对应的液晶的电压高低。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

数码管只有8段,8个IO口就够了,可以用单片机直接控制,但是LCD1602有1120个像素点,1120个引脚的单片机我还没遇到,怎么办?这时候显示芯片HD44780U可以出场了。44780有80个引脚

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机把想要显示的东西发给HD44780U,HD44780U再来控制显示屏就可以

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

所以这个HD44780U就有点像电脑的显卡了。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

LCD1602液晶屏的背面长这个样子,首先映入眼帘的就是那两个大黑点,大黑点里面封装的就是芯片,大的那个是HD44780U,小一点的那个黑点是HD44100H,他的作用后面会讲到。关于芯片的封装,大家可能都觉得芯片 就应该是哪种方形的,有引脚的哪种,其实还有一种COB的封装,就像狗皮膏药一样黏在PCB上,这种封装便宜啊。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

LCD1602一共有16个引脚,其中数据引脚又8个,控制这8个引脚的数据,就能控制液晶屏的显示内容。因为每个显示区域就35个像素,描点法也只能描出简单的图案,比如数字,字面,符号等。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

比如大些字母A,ASCII码表是0100 0001,对应的数据引脚电平就是:

0         1         0         0         0        0        0        1

低       高       低        低      低       低      低        高

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

但是这个A在哪个区域显示呢?HD44780U里面给每个显示区域都规定的地址,这个地址就存在芯片内部的DRAM里面,

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件 单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

  这个DRAM就相当于显卡的显存了,只是大小只有80个字节,可以同时控制80个字符

 单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

LCD1602最多也就能显示32个字符,HD44780U为什么能控制80个字符,因为他是通用的芯片,不是为LCD1602定制的,多的部分可以空着不用。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 后面的红色部分就是多余的地址,控制不用

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 先发送显存的地址,再发送需要显示的内容,这样数据就会被保存在相应的显存里面

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

比如让液晶屏的第一块显示区域显示大些字母A,就先发送第一块显示区域的地址0x00,再发送A的ASCII码0100 0001,怎么显示那就是显示芯片HD44780U的事情了。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

HD44780U的芯片管脚分布如下那些SEG和COM引脚就是控制引脚,是不是似曾相识,数码管的SEG引脚和COM引脚,原理可以说是差不多的。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 COM引脚控制行,SEG引脚控制列,如果要显示A,那就是在相应的交叉点输出不同的电压就行了

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

因为不能同时控制所有行列的电压,只能用扫描的方式,一行一行的控制,是不是也似曾相识,多为数码管的动态显示也是这样的。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第一行,并输出对应的电压 

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第二行并输出对应的电压

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第三行并输出对应的电压

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第四行并输出对应的电压 

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第五行并输出对应的电压 

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第六行,并输出对应的电压

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描第七行并输出对应的电压 

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

扫描快一点,根根人眼的视觉残留,就能看到完整的A了

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 HD44780U的SEG引脚只有40个,5个SEG脚才能控制一列显示区,40个SEG脚一共也只能控制8列显示区啊,LCD1602可是有16列显示区的,那另外的8列的显示区怎么控制,而且前面也说了,HD44780U能控制80个字符,现在怎么才16个。对HD44780U的显存DRAM是可以控制80个字符,但是引脚不够啊,这个时候该HD44100H出场了。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

HD44100H就是那个小一点的黑点

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

它正好也有40个SEG引脚

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 将HD44780U和HD44100H拼在一起不就好了

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 加4个HD44100H,换一个能显示80个字符的液晶显示屏,就能显示80个字符了,HD44780U里面的DRAM就只有80个地址,只能显示80个字符。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

LCD1602相关的寄存器以及电路

 1、认识LCD

LCD == Liquid Crystal Display ==液晶显示器

LCD1602表示一种液晶屏,能同时显示2行16列,共32个字符,这个字符可以是字母,数字,符号等

LCD结构上主要由3部分组成:

液晶:液态晶体,液晶本身不发光,但他在通电的时候可以让光线透过去,不通电时光线透不过去;

光源:这个光源才是点亮LCD的关键;

偏光片:又上下两片,液晶就在上下偏光片之间,改变偏光片的角度就可以让光线在特定的地方透过

上下两片偏光片有点像两个石子交叉的百叶窗,自己去脑补一下。

2、LCD1602的管脚以及管脚功能

管脚序号

管脚符号

管脚说明

1

VSS

电源地,

2

VDD

电源正极,是LCD1602驱动系统的电源

3

VO

液晶显示对比度调整管脚,接正电源是对比度最低,接地时对比度最高,但是对比度太高,就容易看到一些不该看到的东西,俗称“鬼影”,一般在这个脚通过电阻再接地。

4

RS

Register Select的缩写,字面意思就是寄存器选择;当RS=1的时候,通讯的是数据;当RS=0的时候,通讯的是命令。

5

R/W

读,写选择,当R/W = 1的时候表示读LCD里面的数据,R/W = 0的时候表示往LCD里面写数据。

6

E

使能信号,当E=1的时候读取信息,当E由1变为0的时候,液晶模块开始执行命令;要配合控制时序来用。

7

D0

数据第0位,D0--D7是双向的数据线,对LCD模块进行读写。

8

D1

数据第1位

9

D2

数据第2位

10

D3

数据第3位

11

D4

数据第4位

12

D5

数据第5位

13

D6

数据第6位

14

D7

数据第7位

15

BLA

背光源正极,可以理解为那个背光LED的正极电源,可以直接接VDD

16

BLK

背光源负极,可以理解为那个背光LED的负极电源,可以直接接VSS

3、LCD1602 的RAM地址映射

LCD1602能同时显示2行16列,一共32个位置,每个位置都对应着一个地址,每个地址里面可以促一个字节的字符,需要在哪个位置显示某种字符,就在他对应的地址上写入某种字符。

下图就是这32个显示位置所对应的地址,这个地址也就是DDRAM地址;

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

其实LCD1602的DDRAM一共有80个地址,依然是两行,每行40个地址,但是LCD1602一行只能同时显示16个地址的数据,剩下的24个在后面隐藏着。怎么办,只能用光标移动的方法把隐藏的部分显示出来。

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

4、LCD1602的显示设置

比如你想在第1行,第3列的位置显示个字符A,该怎么处理?

首先确定位置,第1行第3列的地址是02,转换为2进制就是0000 0010,但是LCD1602有自己的规矩,就是写地址的时候,最高位必须是1,也就是说写进LCD的地址应该为1000 0010。

然后确定字符,LCD1602模块里面有个字符产生器,简称CGROM(Character Generator ROM)里面存着一些常用的字模,你只需要根据地址来查询就可以了,比如字符A的地址就是0x41。

5、LCD1602的命令列表

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

6、单片机控制LCD1602电路

单片机C语言实例:18、LCD1602液晶显示,单片机项目,单片机,c语言,嵌入式硬件

 

LCD1602液晶静态显示

程序实例1:

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}

/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{    
	while(t--)
	{
		//大致延时1mS
		DelayUs2x(245);
		DelayUs2x(245);
	}
}

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void) 
{ 
	DataPort= 0xFF; 
	RS_CLR; 
	RW_SET; 
	EN_CLR; 
	_nop_(); 
	EN_SET;
	return (bit)(DataPort & 0x80);
}

/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com) 
{  
	while(LCD_Check_Busy()); //忙则等待
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	DataPort= com; 
	_nop_(); 
	EN_CLR;
}

/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data) 
{ 
	while(LCD_Check_Busy()); //忙则等待
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	DataPort= Data; 
	_nop_();
	EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void) 
{ 
	LCD_Write_Com(0x01); 
	DelayMs(5);
}

/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     //表示第一行
 	}
	else 
 	{      
		LCD_Write_Com(0xC0 + x);      //表示第二行
 	}        
	while (*s) 
 	{     
		LCD_Write_Data( *s);     
		s ++;     
 	}
}

/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}    
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	LCD_Write_Data( Data);  
}

/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
	LCD_Write_Com(0x38);    /*显示模式设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38);  
	LCD_Write_Com(0x08);    /*显示关闭*/ 
	LCD_Write_Com(0x01);    /*显示清屏*/ 
	LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	LCD_Init(); 
	LCD_Clear();//清屏
	while (1) 
	{  
		LCD_Write_Char(7,0,'o');
		LCD_Write_Char(8,0,'k');
		LCD_Write_String(1,1,"hello world!");
		while(1);
	}
}

LCD1602液晶动态显示

程序实例2:

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}

/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{    
	while(t--)
	{
		//大致延时1mS
		DelayUs2x(245);
		DelayUs2x(245);
	}
}

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void) 
{ 
	DataPort= 0xFF; 
	RS_CLR; 
	RW_SET; 
	EN_CLR; 
	_nop_(); 
	EN_SET;
	return (bit)(DataPort & 0x80);
}

/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com) 
{  
	while(LCD_Check_Busy()); //忙则等待
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	DataPort= com; 
	_nop_(); 
	EN_CLR;
}

/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data) 
{ 
	while(LCD_Check_Busy()); //忙则等待
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	DataPort= Data; 
	_nop_();
	EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void) 
{ 
	LCD_Write_Com(0x01); 
	DelayMs(5);
}

/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	while (*s) 
 	{     
		LCD_Write_Data( *s);     
		s ++;     
 	}
}

/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}    
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	LCD_Write_Data( Data);  
}

/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
	LCD_Write_Com(0x38);    /*显示模式设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38);  
	LCD_Write_Com(0x08);    /*显示关闭*/ 
	LCD_Write_Com(0x01);    /*显示清屏*/ 
	LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	unsigned char i; 
	unsigned char *p; 

	LCD_Init(); 

	while (1) 
	{  
		i = 1;  
		p = "hello world!";  
		LCD_Clear();  
		LCD_Write_String(2,0,"Welcome to");  
		DelayMs(250);   
		while (*p) 
		{   
			LCD_Write_Char(i,1,*p);   
			i ++;   
			p ++;   
			DelayMs(250);   
		}  
		DelayMs(250);  
	}
}

LCD1602液晶滚动显示

程序实例3:

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}

/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
	while(t--)
	{
		//大致延时1mS
		DelayUs2x(245);
		DelayUs2x(245);
	}
}

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void) 
{ 
	DataPort= 0xFF; 
	RS_CLR; 
	RW_SET; 
	EN_CLR; 
	_nop_(); 
	EN_SET;
	return (bit)(DataPort & 0x80);
}


/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com) 
{  
	while(LCD_Check_Busy()); //忙则等待
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	DataPort= com; 
	_nop_(); 
	EN_CLR;
}

/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data) 
{ 
	while(LCD_Check_Busy()); //忙则等待
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	DataPort= Data; 
	_nop_();
	EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void) 
{ 
	LCD_Write_Com(0x01); 
	DelayMs(5);
}

/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     //表示第一行
 	}
	else 
 	{      
		LCD_Write_Com(0xC0 + x);      //表示第二行
 	}        
	while (*s) 
 	{     
		LCD_Write_Data( *s);     
		s ++;     
 	}
}

/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}    
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	LCD_Write_Data( Data);  
}

/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
	LCD_Write_Com(0x38);    /*显示模式设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38);  
	LCD_Write_Com(0x08);    /*显示关闭*/ 
	LCD_Write_Com(0x01);    /*显示清屏*/ 
	LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}

   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	LCD_Init(); 
	LCD_Clear();//清屏
	LCD_Write_Char(7,0,'o');
	LCD_Write_Char(8,0,'k');
	LCD_Write_String(1,1,"hello world!");
	while (1) 
	{  
		DelayMs(200); 
		LCD_Write_Com(0x18);//左平移画面 0x1C 是右平移
	}
}

LCD1602移动显示

程序实例4:

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}

/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{    
	while(t--)
	{
		//大致延时1mS
		DelayUs2x(245);
		DelayUs2x(245);
	}
}

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void) 
{ 
	DataPort= 0xFF; 
	RS_CLR; 
	RW_SET; 
	EN_CLR; 
	_nop_(); 
	EN_SET;
	return (bit)(DataPort & 0x80);
}

/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com) 
{  
	while(LCD_Check_Busy()); //忙则等待
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	DataPort= com; 
	_nop_(); 
	EN_CLR;
}

/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data) 
{ 
	while(LCD_Check_Busy()); //忙则等待
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	DataPort= Data; 
	_nop_();
	EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void) 
{ 
	LCD_Write_Com(0x01); 
	DelayMs(5);
}

/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	while (*s) 
 	{     
		LCD_Write_Data( *s);     
		s ++;     
 	}
}
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}    
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	LCD_Write_Data( Data);  
}

/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
	LCD_Write_Com(0x38);    /*显示模式设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38);  
	LCD_Write_Com(0x08);    /*显示关闭*/ 
	LCD_Write_Com(0x01);    /*显示清屏*/ 
	LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	unsigned char i; 
	unsigned char *pa,*pb; 

	LCD_Init(); 
	LCD_Write_Com(0x0f);//光标开,光标闪烁开
	while (1) 
	{  
		pa = "Welcome to";
		pb = "hello world!";  
		LCD_Clear();  
		LCD_Write_String(2,0,pa);  //显示2行信息
		LCD_Write_String(1,1,pb);
		for(i=0;i<8;i++)            //延时2s左右
			DelayMs(250); 
		LCD_Clear();                //清屏显示其他信息
		i = 2; 
		while (*pa)                 //循环输入方式显示2行信息
		{   
			LCD_Write_Char(i,0,*pa);   
			i ++;   
			pa ++;   
			DelayMs(250);   
		}  
		i=1;  
		while (*pb) 
		{   
			LCD_Write_Char(i,1,*pb);   
			i ++;   
			pb ++;   
			DelayMs(250);   
		}  
	
		DelayMs(250);  
	}
}

LCD1602液晶按键输入显示

程序实例5:文章来源地址https://www.toymoban.com/news/detail-707896.html

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0
#define KeyPort P1

unsigned char code show_code[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//转换成液晶显示的字符
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}

/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
	while(t--)
	{
		//大致延时1mS
		DelayUs2x(245);
		DelayUs2x(245);
	}
}

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void) 
{ 
	DataPort= 0xFF; 
	RS_CLR; 
	RW_SET; 
	EN_CLR; 
	_nop_(); 
	EN_SET;
	return (bit)(DataPort & 0x80);
}

/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com) 
{  
	while(LCD_Check_Busy()); //忙则等待
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	DataPort= com; 
	_nop_(); 
	EN_CLR;
}
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data) 
{ 
	while(LCD_Check_Busy()); //忙则等待
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	DataPort= Data; 
	_nop_();
	EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void) 
{ 
	LCD_Write_Com(0x01); 
	DelayMs(5);
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	while (*s) 
 	{     
		LCD_Write_Data( *s);     
		s ++;     
 	}
 }
 
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
 	{     
		LCD_Write_Com(0x80 + x);     
 	}    
	else 
 	{     
		LCD_Write_Com(0xC0 + x);     
 	}        
	LCD_Write_Data( Data);  
 }
 
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
	LCD_Write_Com(0x38);    /*显示模式设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38); 
	DelayMs(5); 
	LCD_Write_Com(0x38);  
	LCD_Write_Com(0x08);    /*显示关闭*/ 
	LCD_Write_Com(0x01);    /*显示清屏*/ 
	LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
	DelayMs(5); 
	LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
 
   /*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void)  //键盘扫描函数,使用行列反转扫描法
{
	unsigned char cord_h,cord_l;//行列值中间变量
	KeyPort=0x0f;            //行线输出全为0
	cord_h=KeyPort&0x0f;     //读入列线值
	if(cord_h!=0x0f)    //先检测有无按键按下
	{
		DelayMs(10);        //去抖
		if((KeyPort&0x0f)!=0x0f)
		{
			cord_h=KeyPort&0x0f;  //读入列线值
			KeyPort=cord_h|0xf0;  //输出当前列线值
			cord_l=KeyPort&0xf0;  //读入行线值
	
			while((KeyPort&0xf0)!=0xf0);//等待松开并输出
	
			return(cord_h+cord_l);//键盘最后组合码值
		}
	}
	return(0xff);     //返回该值
}

/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{
	switch(KeyScan())
	{
		case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
		case 0x7d:return 1;break;//1
		case 0x7b:return 2;break;//2
		case 0x77:return 3;break;//3
		case 0xbe:return 4;break;//4
		case 0xbd:return 5;break;//5
		case 0xbb:return 6;break;//6
		case 0xb7:return 7;break;//7
		case 0xde:return 8;break;//8
		case 0xdd:return 9;break;//9
		case 0xdb:return 10;break;//a
		case 0xd7:return 11;break;//b
		case 0xee:return 12;break;//c
		case 0xed:return 13;break;//d
		case 0xeb:return 14;break;//e
		case 0xe7:return 15;break;//f
		default:return 0xff;break;
	}
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	unsigned char i,j,num; 

	LCD_Init(); 
	LCD_Write_Com(0x0F);//光标开,光标闪烁开

	LCD_Write_String(0,0,"Press the key !");

	while (1) 
	{  
		num=KeyPro();
		if(num!=0xff)
		{
			if((i==0)&&(j==0))//回到第一个字符时清屏
				LCD_Clear();//清屏
			LCD_Write_Char(0+i,0+j,show_code[num]);//依次显示输入字符
			i++;
			if(i==16)//如果第一行显示满,转到第二行
			{
				i=0;j++;
				if(j==2)//如果2行都显示满,清屏后重新从第一行显示
				{
					j=0;
				}
			}
		}
	}
}

到了这里,关于单片机C语言实例:18、LCD1602液晶显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【附报告】51单片机计算器(LCD1602液晶显示)

      由于本文较早,这里推荐一下近期刚优化的:【优化】51单片机计算器(LCD1602液晶显示)_Gxtoeilee的博客-CSDN博客   1 设计目标 设计可选模式的计算器  2 主要功能 功能一:可选两种计算模式,模式一为四则运算,模式二为扩展内容; 功能二:除法的计算结果保留到小数点

    2024年02月11日
    浏览(57)
  • 单片机入门教程:第七章 1602LCD液晶显示模块

    在单片机的人机交互系统中,常常需要显示系统运行中的某些信息和数据,例如,字符、汉字或者图形等。液晶显示器(LCD)正好可以完成此项任务,它是一种功耗很低的显示器,在电子表、计算器、数码相机、计算机的显示器和液晶电视上都可以看到它的身影。液晶显示器

    2024年02月09日
    浏览(55)
  • 51单片机LCD1602液晶屏显示字符,字符串,(有)无符号整数,十六进制数,二进制数等

    LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。液晶显示模块具有体积小、功耗低、显示内容丰富、超薄轻巧等优点,在嵌入式应用系统中得到越来越广泛的应用,这讲中向大家介绍的LCD1602 液晶显示模块(其内部控制器为HD44780 芯片),它可以显示两行,每行16 个字

    2024年02月04日
    浏览(67)
  • 基于51单片机 + MQ-3酒精传感器 + ADC0832模数转换器 + LCD1602液晶显示器的酒精检测系统

    废话不多说,直接上东西。本文是基于51单片机的酒精检测系统设计,用的元器件有:51单片机、MQ-3酒精传感器、ADC0832模数转换器、 LCD1602液晶显示器、喇叭等元器件。 1、MQ-3 酒精检测传感器,用于检测酒精浓度。当然采集到的数据是模拟的还需要通过ADC0832模数转换器将其转

    2024年02月12日
    浏览(59)
  • 51单片机DS18B20测温LCD1602显示

    主函数 自定义头文件 LCD1602函数 DS18B20 共用函数

    2024年02月11日
    浏览(43)
  • 51单片机——LCD1602液晶屏 C语言入门编程

    目录 LCD1602: 数据指令:  字节写入时序: 1. LCD1602:LCD1602液晶上显示字符信息         1602液晶也叫1602字符型液晶,它能显示2行字符信息,每行又能显示16个字符。它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若 干个5x7的点阵字符位组成,每个点

    2024年02月05日
    浏览(52)
  • 基于51单片机直流电机PWM调速液晶1602显示设计

    一、系统方案 本文主要研究了利用MCS-51系列单片机控制PWM信号从而实现对直流电机转速进行控制的方法。本文中采用了三极管组成了PWM信号的驱动系统,并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节,从而控制其输入信号波形等均作了详细的

    2024年02月11日
    浏览(49)
  • 51单片机DS18B20温度传感器使用及数码管温度计、LCD1602温度显示代码详解

    温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读中文手册,并且对照代码注释充分分析代码。请不要觉得中文手册内容繁多!如能静心分析,定能深有体会,获益匪浅! 主函数操作顺序(执行序列) 功能指令 最后希望我的分享对你有所帮助!敬请关

    2024年02月12日
    浏览(52)
  • 【TB作品】MSP430单片机 Proteus仿真 DS18B20温度 LCD1602显示器 温度读取与显示

    效果图如下: 首先,让我们先来说说DS18B20集成电路。 • DS18B20是一款采用OneWire通讯协议的集成电路,因此只需要一条线就可以与微控制器通讯。它不需要额外的电源,但是也有外部电源输入端口。 • OneWire设备具有64位的ROM代码。如我们之前所说,这64位的前8位是家族代码,中间

    2024年02月08日
    浏览(69)
  • 单片机——LCD1602

    1.基础知识介绍 1.1、为什么叫1602 因为可以显示两行,一行16个 1.2、LCD1602管脚认识 编号 符号 引脚说明 1 VSS 电源地 2 VDD 电源正极 3 VEE 液晶显示偏压信号 4 RS 数据/命令选择(H/L) 5 R/W 读/写选择(H/L) 6 E 使能端 7 D0 数据 8 D1 数据 9 D2 数据 10 D3 数据 11 D4 数据 12 D5 数据 13 D6 数

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包