单片机学习笔记---LCD1602功能函数代码

2024-02-16 10:20

本文主要是介绍单片机学习笔记---LCD1602功能函数代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

LCD1602.c

模拟写指令的时序

模拟写数据的时序

初始化

显示字符

显示字符串

显示数字

显示有符号的数字

显示16进制数字

显示二进制数

LCD1602.h

main.c


上一篇讲了LCD1602的工作原理,这一节开始代码演示!

新创建工程:LCD1602功能函数代码

新创建main.c,LCD1602.c和LCD1602.h文件

开始代码讲解:

LCD1602.c

先根据原理图声明一下这三个控制引脚和八个数据引脚

#include <REGX52.H>//引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DataPort P0

然后根据上一篇讲的时序逐个定义函数

模拟写指令的时序

首先是写指令

void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;//写指令是低电平LCD_RW=0;//写LCD_DataPort=Command;//将指令放在数据口Data port上LCD_E=1;//使能LCD_Delay();//延时1msLCD_E=0;//关闭使能LCD_Delay();//延时1ms
}

由于E等于高电平是时间太快了,我们看到手册上的时序参数都是纳秒级的,单片机最低是微秒级的。

我们写指令得需要一定的执行时间,如果E的电平给高立马给低的话,如果太快的话可能读不过来

因此我们需要在E=1之后加一段延时,E=0之后也加一段延时。

我们在STC软件上生成一个1ms的延时函数

放在写指令的函数上方,将函数名改成LCD_Delay()

void LCD_Delay()		//@12.000MHz 1ms
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}

这样我们就可以直接调用这个延时函数了

模拟写数据的时序

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();
}

接下来我们把这两个函数组合起来根据LCD1602的操作流程完成我们想要的功能!

初始化

void LCD_Init(void)
{LCD_WriteCommand(0x38);LCD_WriteCommand(0x0C);LCD_WriteCommand(0x06);LCD_WriteCommand(0x01);
}

显示字符

显示字符之前我们得设置光标位置

void LCD_SetCursor(unsigned char Line,unsigned char Column)//行,列
{if(Line==1)//如果是第一行{LCD_WriteCommand(0x80|(Column-1));}else //如果是第二行{LCD_WriteCommand(0x80|(Column-1)+0x40);}
}

如果是第一行,用0x80或上列码-1

如果是第二行,用0x80或上列码-1,再+0x40

(如果不知道0x80是什么请看上一篇博客的解释)

设置好光标位置后开始写显示字符函数 

void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)//        行,                列,         显示的字符
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}

但是显示字符在实际的应用中还是远远不够的,我们可以让它显示别的东西

比如

显示字符串

void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
//传过来的unsigned char*型指针代表字符串的首地址{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)//遍历字符数组{LCD_WriteData(String[i]);}
}

显示数字

由于不能直接显示数字,得先转换成字符然后再显示,

比如传过来的数字是789,那么我们得对789进行转换成字符7,字符8,和字符9再显示

怎么转换呢?

先挨个位取出来数字7,数字8,数字9

789/100=7.89,对7.89取余7.89%10=7(取出来了高位)

789/10%10=8(取出来第二位)

789/1%10=9(取出来最低位)

我们按照这个方法从高位开始取

我们得弄个长度的变量 i,i 和取整时的除数的关系是:

于是我们可以先定义一个次方函数,通过这个函数我们就可以得到返回值等于x的y次方

int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;//如果Y=0,则下面的i<Y直接不成立,直接返回1,符合任何数的0次方等于1的规则for(i=0;i<Y;i++){Result*=X;//如果Y=1,结果等于1*X就等于X的1次方//如果Y=2,结果等于1*X*X等于X的2次方}return Result;//返回值等于x的y次方
}

我们用这个规律Number/LCD_Pow(10,i-1)规律取出来的是数字,想要显示成字符的话,要将数字转换成对应的ASCII码值。怎么转换呢?

我们看着ASCII码表找规律

由此可见,我们想要将一个数字转换成对应的ASCII码值的话可以将它本身的二进制数值加上0x30,也就是字符'0"的ASCII码值就能得到它的ASCII码值了

于是就写成'0'+Number/LCD_Pow(10,i-1)%10

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);//Number/LCD_Pow(10,i-1) 10=X,i-1=Y}
}

显示有符号的数字

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;//变成正数范围是32768,为了保证范围则需要赋给一个无符号的int型}for(i=Length;i>0;i--){LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);}
}

显示16进制数字

如果是16进制了话就不是除以10除以100这样子了,而是除以16再对16取余

所以改成Number/LCD_Pow(16,i-1)%16;

而且16进制从0~F:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f

而A的ASCII码值不是紧接着9的,所以当数字大于等于10的话要用 if 判断一下

并且这时就不是加0x30了,要改成加上0x41,即 'A' 的ASCII码值

我们将取出来的单个数字(定义成SingleNumber)+‘A’,但是当取出来的SingleNumber大于等于10的话,我们将它+‘A’就会偏移10。

比如说SingleNumber=10,那么它的二进制数是0100 1010,加上‘A’的ASCII码0100 0001, 而我们想要SingleNumber是A的话就得减去10。

如果说SingleNumber=11,那么它的二进制数是0100 1011,加上‘A’的ASCII码0100 0001, 而我们想要SingleNumber是B的话就得减去10。

因此'A'+SingleNumber-10

void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;unsigned char SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;//取出单个数值if(SingleNumber<10)//如果单个数值小于10{LCD_WriteData('0'+SingleNumber);}else //如果单个数值大于等于10{LCD_WriteData('A'+SingleNumber-10);}}
}

显示二进制数

二进制的话就改成除以2和%2,Number/LCD_Pow(2,i-1)%2

取出来之后加上'0'的ASCII码就是对应的字符了

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('0'+Number/LCD_Pow(2,i-1)%2);}
}

LCD1602.h

然后声明一下这些函数

#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

main.c

最后在主程序中调用一下这些函数就可以显示了!

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"void main()
{LCD_Init();						//LCD初始化LCD_ShowChar(1,1,'A');			//在1行1列显示字符ALCD_ShowString(1,3,"Hello");	//在1行3列显示字符串HelloLCD_ShowNum(1,9,66,2);			//在1行9列显示数字66,长度为2LCD_ShowSignedNum(1,12,-88,2);	//在1行12列显示有符号数字-88,长度为2LCD_ShowHexNum(2,1,0xA5,2);		//在2行1列显示十六进制数字0xA5,长度为2LCD_ShowBinNum(2,4,0xA5,8);		//在2行4列显示二进制数字0xA5,长度为8LCD_ShowChar(2,13,0xDF);		//在2行13列显示编码为0xDF的字符LCD_ShowChar(2,14,'C');			//在2行14列显示字符Cwhile(1){}
}

效果请看视频:

LCD1602液晶显示屏

补充:

如果想要做流动字幕的效果的话,我们可以调用这个指令码0x18

将写指令的函数声明为外部可调用函数

然后在主程序中调用这个函数,传这一个移屏指令过去,放在while循环里面,调用一次,移一次

但是这样太快了,我们可以把我们之前讲过的Delay的模块化程序添加进来,每移一次就Delay 500ms

效果请看视频:

LCD1602液晶屏显示流动字幕

以上就是本节内容,源码会放在评论区,如有问题可评论区留言! 

这篇关于单片机学习笔记---LCD1602功能函数代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/714255

相关文章

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

MySQL 8 中的一个强大功能 JSON_TABLE示例详解

《MySQL8中的一个强大功能JSON_TABLE示例详解》JSON_TABLE是MySQL8中引入的一个强大功能,它允许用户将JSON数据转换为关系表格式,从而可以更方便地在SQL查询中处理J... 目录基本语法示例示例查询解释应用场景不适用场景1. ‌jsON 数据结构过于复杂或动态变化‌2. ‌性能要

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更