文章目录
一、介绍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,就会栈溢出