LCD1602详解


一、介绍LCD1602

介绍

在这里插入图片描述

引脚以及应用电路

在这里插入图片描述
在这里插入图片描述

内部结构框图

在这里插入图片描述

存储器结构

DDRAM数据显示区

在这里插入图片描述

CGROM中字符码与字符关系表

注意:与ASCII码表所对应的数据不完全一致

在这里插入图片描述

ASCII码对照表

在这里插入图片描述

时序结构

读操作
在这里插入图片描述
写操作
在这里插入图片描述

LCD1602指令集

在这里插入图片描述

LCD1602操作流程

本次案例要使用的流程如下

在这里插入图片描述
在这里插入图片描述

二、重写显示函数

关键函数写入命令与写入数据

根据上面指令集与时序结构写出写入命令与写入数据函数

/**
   * @brief		发送指令
   * @param		Command,指令值
   * @retval	无
   */
void LCD_WriteCommand(unsigned char Command){
	LCD_RS = 0;
	LCD_WR = 0;							// 写入模式
	LCD_DataPort = Command;	// 写入引脚
	LCD_EN = 1;							// 允许写入
	LCD_Delayms(1);					// 等待指令写入
	LCD_EN = 0;							// 还原电平
	LCD_Delayms(1);
}
/**
   * @brief		发送数据
   * @param		Data,数据值
   * @retval	无
   */
void LCD_WriteData(unsigned char Data){
	LCD_RS = 1;						// 读取模式
	LCD_WR = 0;							
	LCD_DataPort = Data;	// 写入引脚
	LCD_EN = 1;							// 允许写入
	LCD_Delayms(1);					// 等待指令写入
	LCD_EN = 0;							// 还原电平
	LCD_Delayms(1);
}

所有实现代码

LCD1602.c

#include <REGX52.H>
#include <intrins.h>
// 引脚声明
sbit LCD_RS = P2^6;
sbit LCD_WR = P2^5;
sbit LCD_EN = P2^7;
// 输入接口
#define LCD_DataPort P0

// 延时函数
void LCD_Delayms(unsigned char x)	//@11.0592MHz
{
	unsigned char data i, j;
	while(x--){
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}
/**
   * @brief		发送指令
   * @param		Command,指令值
   * @retval	无
   */
void LCD_WriteCommand(unsigned char Command){
	LCD_RS = 0;
	LCD_WR = 0;							// 写入模式
	LCD_DataPort = Command;	// 写入引脚
	LCD_EN = 1;							// 允许写入
	LCD_Delayms(1);					// 等待指令写入
	LCD_EN = 0;							// 还原电平
	LCD_Delayms(1);
}
/**
   * @brief		发送数据
   * @param		Data,数据值
   * @retval	无
   */
void LCD_WriteData(unsigned char Data){
	LCD_RS = 1;						// 读取模式
	LCD_WR = 0;							
	LCD_DataPort = Data;	// 写入引脚
	LCD_EN = 1;							// 允许写入
	LCD_Delayms(1);					// 等待指令写入
	LCD_EN = 0;							// 还原电平
	LCD_Delayms(1);
}
/**
   * @brief		初始化函数
   * @param		无
   * @retval	无
   */
void LCD_Init(void){
	LCD_WriteCommand(0x38);
	LCD_WriteCommand(0x0c);
	LCD_WriteCommand(0x06);
	LCD_WriteCommand(0x01);
}
/**
   * @brief		将行、列转换为DDRAM的地址并写入
   * @param		Row,行		Col,列
   * @retval	无
   */
void LCD_SetAC(unsigned char Row,unsigned char Col){
	// 将行、列转换为DDRAM的地址
	if(Row == 1){
		LCD_WriteCommand(0x80 | (Col - 1));
	}else{
		LCD_WriteCommand((0x80 | (Col - 1)) + 0x40);
	}
}
/**
   * @brief		显示一个字符
   * @param		Row 行,Col 列,Char 显示的字符
   * @retval	无
   */
void LCD_ShowChar(unsigned char Row,unsigned char Col,unsigned char Char){
	LCD_SetAC(Row,Col);
	LCD_WriteData(Char);
}
/**
   * @brief		显示一段字符串
   * @param		Row 行,Col 列,*String 显示的字符数组首地址
   * @retval	无
   */
void LCD_ShowString(unsigned char Row,unsigned char Col,unsigned char* String){
	unsigned char i;
	LCD_SetAC(Row,Col);
	// 判断一位写一位,与AC(光标)同步跳转
	for(i = 0;String[i]!='\0';i++){
		LCD_WriteData(String[i]);
	}
}
/**
   * @brief		指数函数
   * @param		x 底数,y 指数
   * @retval	result 返回x的y次方
   */
unsigned char Pow(unsigned char x,unsigned char y){
	unsigned char result = 1,i;
	for(i=0;i<y;i++){
		result *= x;
	}
	return result;
}
/**
   * @brief		显示一个数字
   * @param		Row 行,Col 列,Num 显示的数字,Length 显示的长度
   * @retval	无
   */
void LCD_ShowNum(unsigned char Row,unsigned char Col,unsigned int Num,unsigned char Length){
	unsigned char i;
	LCD_SetAC(Row,Col);
	// 判断一位写一位,与AC(光标)同步跳转
	for(i = Length;i>0;i--){
		LCD_WriteData(0x30+Num/Pow(10,i-1)%10);	// 转化为ASCII码
	}
}
/**
   * @brief		显示一个有符号数
   * @param		Row 行,Col 列,Num 显示的数字,Length 显示的长度
   * @retval	无
   */
void LCD_ShowSignedNum(unsigned char Row,unsigned char Col,int Num,unsigned char Length){
	unsigned char i;
	unsigned int Num1;
	LCD_SetAC(Row,Col);
	if(Num>=0){
		LCD_WriteData('+');
		Num1 = Num;
	}else{
		LCD_WriteData('-');
		Num1 = -Num;	// 最大负值取反后会栈溢出,使用定义一个无符号的数来接收
	}
	// 判断一位写一位,与AC(光标)同步跳转
	for(i = Length;i>0;i--){
		LCD_WriteData(0x30+Num1/Pow(10,i-1)%10);	// 转化为ASCII码
	}
}
/**
   * @brief		显示一个十六进制数
   * @param		Row 行,Col 列,Num 显示的数字,Length 显示的长度
   * @retval	无
   */
void LCD_ShowHexNum(unsigned char Row,unsigned char Col,unsigned int Num,unsigned char Length){
	unsigned char i;
	unsigned char Num_Flag;
	LCD_SetAC(Row,Col);
	// 判断一位写一位,与AC(光标)同步跳转
	for(i = Length;i>0;i--){
		Num_Flag = Num/Pow(16,i-1)%16;
		if(Num_Flag<10){
			LCD_WriteData('0'+Num_Flag);
		}else{
			LCD_WriteData('A'+Num_Flag-10);
		}
	}
}
/**
   * @brief		显示一个二进制数
   * @param		Row 行,Col 列,Num 显示的数字,Length 显示的长度
   * @retval	无
   */
void LCD_ShowBinNum(unsigned char Row,unsigned char Col,unsigned int Num,unsigned char Length){
	unsigned char i;
	LCD_SetAC(Row,Col);
	// 判断一位写一位,与AC(光标)同步跳转
	for(i = Length;i>0;i--){
		LCD_WriteData(0x30+Num/Pow(2,i-1)%2);		// 二进制转换
	}
}

注意

有符号和无符号数之间转换时要注意栈溢出问题,例如 1111 1111转化为有符号数,那么第一位就变成了符号位,相当于最大为-0111 1111,就会栈溢出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值