51单片机应用开发---LCD1602显示应用

实现目标

1、了解LCD1602液晶屏;

2、掌握驱动程序的编写;

  1. 具体目标:在屏幕上显示字符。

一、LCD1206概述

1.1 定义

LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符(如汉字)。

显示容量: 16 ---表示每行显示16个字符;02---表示显示两行。

1.2 实物与管脚

(1)实物

(2)管脚定义

1.3 内部结构框图

屏幕: 16*2

字模库:类似于数码管的数码表

DDRAM (data display RAM):前16列与屏幕一一对应的

AC: address counter

显示流程:在数据显示区写入相应的值(ASCII码),之后通过字模库找到对应的字符,将其显示到屏幕上。

(1)存储器结构:DDRAM(数据显示区)

LCD1602 实际有80个字节的DDRAM,只不过 LCD1602 只有 16X2 个位置,后面很多位置显示不出来,可以使用 指令5 "光标或显示移动指令" 使字符慢慢移动到可见的显示范围内,看到字符的移动效果。

(2)显示原理

如上图,每个字符由 5X8 点阵组成(也可选用 5X10),想要实现显示,只需如下图:

例:以 5X7 点阵为例, 显示字符 A

0 代表灭,1 代表亮

只需将想要显示的字符的对应位置1,就能显示该字符

LCD1602 固化了字模寄存器,即 CGROM 和 CGRAM,存储了192个常用字符的字模。

(3) CGRAM+CGROM(字模库)

例如:要显示A,则索引码为0100 0001 该表 行是低四位,列是高四位

1.4 LCD1602指令集

常用指令:

0x80+0xdd:dd为地址,这条命令用于设置显示起点坐标

0x0c :开显示,无光标,光标不闪烁 。一般做带键盘输入的才加入光标,如计算器。常用的计量显示不显示光标。

0x06 :写一个数据,地址指针加1,由1602地址表可以看出,实际上就是设置成从左往右写数据而已。

0x38 : 设置显示模式,16x2显示 5x7点阵,8位数据接口。端口不够用时,这个命令也可以换用4位数据接口的。

0x01 :清屏。

1.5 LCD1602操作流程

(1) 初始化

发送指令0x38 //八位数据接口,两行显示,5*7点阵

发送指令0x0C //显示开,光标关,闪烁关

发送指令0x06 //数据读写操作后,光标自动加一,画面不动

发送指令0x01 //清屏

(2) 显示字符

发送指令 0x80 | AC //设置光标位置(之所以要将AC与0x80进行或运算,是因为DDRAM地址设置指令的DB7为1,故发送指令的最高位要为1)

【将光标设置在一行一列输入1000 0000,1为设置,剩下为00H】

【将光标设置在二行一列输入1100 0000,1为设置,剩下为40H(二进制100 0000转化为十进制为64,十六进制40转化为十进制也是64)】

发送数据 //发送要显示的字符数据

1.6 时序结构

写数据/指令(对于LCD来说,一般不需要进行读操作)

写数据:先将RS置1,再将R/W置0,之后将数据写入对应I0口,将 E 置1,则此时数据有效;写数据完成后;E置0 。写指令同理

驱动编写:

(1) 管脚定义

cpp 复制代码
#include "LCD1602.h"
#include <REGX52.H>
//管脚定义
sbit LCD_RW=P2^5;
sbit LCD_RS=P2^6;
sbit LCD_E =P2^7;
#define LCD_DataPort P0

(2)写命令

cpp 复制代码
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()		//@12.000MHz 1ms
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_E=1;
	LCD_Delay();
	LCD_E=0;
	LCD_Delay();
}

(3)写数据

cpp 复制代码
/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_E=1;
	LCD_Delay();
	LCD_E=0;
	LCD_Delay();
}

(4)LCD1602初始化

cpp 复制代码
/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init(void)
{
	LCD_WriteCommand(0x38);
	LCD_WriteCommand(0x0C);
	LCD_WriteCommand(0x06);
	LCD_WriteCommand(0x01);
}

(5)设置光标位置

cpp 复制代码
/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else
	{
		LCD_WriteCommand(0x80|(Column-1)+0x40);
	}
}

(6)显示一个字符

cpp 复制代码
/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

(7)显示字符串

cpp 复制代码
/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
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++)
	{
		LCD_WriteData(String[i]);
	}
}

(8)X的Y次方

cpp 复制代码
/**
  * @brief  返回值=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;
}

(9)显示数字

cpp 复制代码
/**
  * @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('0'+Number/LCD_Pow(10,i-1)%10);
	}
}

(10)显示有符号数字

cpp 复制代码
/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
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;//int型-32768~32767
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);
	}
}

二、原理图设计

三、程序设计

3.1 LCD1602.h 文件

cpp 复制代码
#ifndef __LCD1602_H__
#define __LCD1602_H__

void LCD_Init(void);
void 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 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);

#endif

3.2 LCD1602.c 文件

将前面的各项驱动程序模块添加到LCD1602.c文件中。

3.3 测试程序

cpp 复制代码
#include <REGX52.H>
#include "LCD1602.h"
 
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
 
void main()
{
	LCD_Init();
	LCD_ShowString(1,16,"day day up!");
	while(1)
	{//指令集0x18:画面向左平移一个字符位,但光标不动。移屏
		LCD_WriteCommand(0x18);
		Delay500ms();
	}
}

四、实验效果

五、仿真实现


总结

相关推荐
智商偏低6 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen7 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森9 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白9 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D10 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术13 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt13 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘13 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang13 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n16 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件