51单片机-LCD1602(液晶显示屏)- 写驱动

时间永远是检验真理唯一标准!Whappy!

主要简单写出几个驱动

初始化、显示字符、显示字符串、显示整形数据、有符号数据、十六进制、二进制!

void LCD_Init(); 
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,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);

介绍
 

LCD1602驱动程序编写

根据时序写出发送指令和发送数据的操作,

首先设置指令(查看指令格式)集存取RS,RS=0,输入指令,1输入数据。再RS=1期间,将R/W设置位写,并打开使能从1 -0,然后数据就会被写入进去。

下面两个函数实现写数据和写指令的操作,接下来我们就要根据相关寄存器发送,对应的指令和数据即可,可参考数据手册。

//RS写指令的驱动
void LCD1602_WriteCommand(unsigned char Command)
{LCD_RS = 0; //写入指令LCD_WR = 0; //写入数据LCD_DataPort = Command; //将指令放到数据总线上,并行端口,Commmand的8位可以直接放上去LCD_EN = 1;  //使能1-0,写入数据Delay1ms();LCD_EN = 0;	Delay1ms();}//RW写数据的驱动
void LCD1602_WriteData(unsigned char Data)
{LCD_RS = 1; //写入指令LCD_WR = 0; //写入数据LCD_DataPort = Data; //将指令放到数据总线上,并行端口,Commmand的8位可以直接放上去LCD_EN = 1;  //使能1-0,写入数据Delay1ms();LCD_EN = 0;	Delay1ms();
}

代码写数据写指令已经完成,接下我们就要根据LCD1602的相关寄存器配置进行我们需要的操作,下图表位LCD1602的相关操作配置指令(也是寄存器配置)

具体操作流程如下,对照指令集写的初始化函数和显示字符函数等(通过发送指令和数据函数完成)

(1)对功能指令的寄存器配置为0X38,  发送指令0x38    //八位数据接口,两行显示,5*7点阵

给出功能指令配置,其余指令配置请参考指令集,自行研究,也很容易!

初始化函数编写

//初始化
void LCD1602_Init(void)
{LCD1602_WriteCommand(0X38);//八位数据接口,两行显示,5*7点阵LCD1602_WriteCommand(0X0C);//显示开,光标关,闪烁关LCD1602_WriteCommand(0X06);//数据读写操作后,光标自动加一,画面不动LCD1602_WriteCommand(0X01);//光标复位,清屏}//光标位置
void LCD1602_SetCursor(unsigned char Line, unsigned char Column)
{if(Line == 1){LCD1602_WriteCommand(0X80 | (Column-1));}else{LCD1602_WriteCommand(0X80 | (Column-1)+0X40);}
}

整体函数

LCD1602.c

#include <REGX52.H>#include "LCD1602_W.h"unsigned int LCD_Pow(unsigned char base, unsigned char exponent)
{unsigned int result = 1;while (exponent--){result *= base;}return result;
}//初始化
void LCD1602_Init(void)
{LCD1602_WriteCommand(0X38);//八位数据接口,两行显示,5*7点阵LCD1602_WriteCommand(0X0C);//显示开,光标关,闪烁关LCD1602_WriteCommand(0X06);//数据读写操作后,光标自动加一,画面不动LCD1602_WriteCommand(0X01);//光标复位,清屏}/*
行与地址映射
第一行地址起点:通常,LCD 屏幕的第一行的 DDRAM 地址从 0x00 开始。
第二行地址起点:第二行的 DDRAM 地址通常从 0x40 开始。
所以,如果我们想移动光标到显示屏的第一行的第 1 列,就需要发送的命令是 0x80 加上该列的偏移量(即 Column-1)。解释 0x80 | (Column - 1)
0x80:0x80 是一个命令位,表示将要设置光标的 DDRAM 地址。LCD 控制器的命令格式中,高位 1 用来表明我们要设置光标。
它是“设置地址”指令的标识符,告诉 LCD 控制器接下来传递的值是 DDRAM 的地址。
Column - 1:Column 是用户输入的列数,它通常是从 1 开始的。然而,LCD 的内存地址是从 0 开始的(即第 1 列对应地址 0,第 2 列对应地址 1,以此类推)。
所以我们需要将 Column 减去 1,将它转换为从 0 开始的索引值,匹配 DDRAM 地址。
*/
//光标位置
void LCD1602_SetCursor(unsigned char Line, unsigned char Column)
{if(Line == 1){LCD1602_WriteCommand(0X80 | (Column-1));}else{LCD1602_WriteCommand(0X80 | (Column-1)+0X40);}
}//显示字符
void LCD1602_ShowChar(unsigned char Line, unsigned char Column,unsigned char Char)
{LCD1602_SetCursor(Line,Column); //光标位置LCD1602_WriteData(Char); //要显示的字符
}//显示字符串
void LCD_DisplayString(unsigned char Line, unsigned char Column, char *str)
{// 将光标移动到指定的行和列LCD1602_SetCursor(Line, Column);// 循环显示字符串中的每个字符,直到遇到字符串结束符 '\0'while(*str != '\0'){LCD1602_WriteData(*str);// 显示当前字符str++;                // 移动到下一个字符}
}// 显示16进制数字
void LCD1602_ShowHexNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
{unsigned char i;unsigned char hexDigit;unsigned int divisor = LCD_Pow(16, Length - 1); // 初始除数为16的Length-1次方LCD1602_SetCursor(Line,Column);for (i = 0; i < Length; i++){hexDigit = Number / divisor;          // 获取当前最高位的16进制数字Number %= divisor;                    // 计算剩余的数值divisor /= 16;                        // 更新除数以处理下一位if (hexDigit < 10){LCD1602_WriteData(hexDigit + '0');    // 数字字符}else{LCD1602_WriteData(hexDigit - 10 + 'A'); // 字母字符}}
}void LCD1602_ShowBinNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
{unsigned char i;unsigned char hexDigit;unsigned int divisor = LCD_Pow(2, Length - 1); // 初始除数为16的Length-1次方LCD1602_SetCursor(Line,Column);for (i = 0; i < Length; i++){hexDigit = Number / divisor;          // 获取当前最高位的16进制数字Number %= divisor;                    // 计算剩余的数值divisor /= 2;                        // 更新除数以处理下一位if (hexDigit < 10){LCD1602_WriteData(hexDigit + '0');    // 数字字符}else{LCD1602_WriteData(hexDigit - 10 + 'A'); // 字母字符}}
}// 显示数字字符
void LCD_ShowNumber(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
{unsigned char i;unsigned char digit;unsigned char displayDigit[10]; // 用于存储每一位的数字字符// 计算每一位的数字字符for (i = 0; i < Length; i++){digit = Number % 10; // 取当前最低位数字displayDigit[Length - i - 1] = digit + '0'; // 转换为字符并存储Number /= 10; // 处理下一个数字}// 显示每一位数字LCD1602_SetCursor(Line, Column); // 设置光标位置for (i = 0; i < Length; i++){LCD1602_WriteData(displayDigit[i]); // 显示字符}
}//指定位置显示有符号的数字
void LCD1602_DisplaySignedNum(unsigned char Line, unsigned char Column, int Number, unsigned char Length)
{unsigned char i;unsigned int Number1;unsigned char digit;unsigned char displayDigit[10]; // 用于存储每一位的数字字符LCD1602_SetCursor(Line, Column); // 设置光标位置if(Number > 0){LCD1602_WriteData('+'); //写数据Number1 = Number;}else{LCD1602_WriteData('-'); //写数据Number1 = -Number;}// 计算每一位的数字字符for (i = 0; i < Length; i++){digit = Number1 % 10; // 取当前最低位数字displayDigit[Length - i - 1] = digit + '0'; // 转换为字符并存储Number1 /= 10; // 处理下一个数字}for (i = 0; i < Length; i++){LCD1602_WriteData(displayDigit[i]); // 显示字符}
}// 显示流动字母的函数
void LCD1602_FlowLetters(unsigned char Line, unsigned char StartColumn, char *str, unsigned char Delay)
{unsigned char i, j;unsigned char length = 0;unsigned int delay;char buffer[17]; // 用于存储显示内容(16字符 + 1个终止符)// 计算字符串的长度while (str[length] != '\0'){length++;}// 将字符串末尾添加空格填充到屏幕宽度for (i = 0; i < 16 - length; i++){buffer[length + i] = ' ';}for (i = 0; i < length; i++){buffer[i] = str[i];}buffer[16] = '\0'; // 添加字符串结束符// 流动显示for (i = 0; i < length + (16 - length); i++){LCD1602_SetCursor(Line, StartColumn); // 设置光标位置for (j = 0; j < 16; j++){LCD1602_WriteData(buffer[j + i]); // 显示字符}// 等待一段时间for (delay = 0; delay < Delay * 1000; delay++);// 清屏LCD1602_WriteCommand(0x01);}
}

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__void LCD1602_Init(void); //初始化
void LCD1602_SetCursor(unsigned char Line, unsigned char Column); //设置光标的位置
void LCD1602_ShowChar(unsigned char Line, unsigned char Column,unsigned char Char); //显示字符
void LCD_DisplayString(unsigned char Line, unsigned char Column, char *str); //显示字符串
void LCD1602_ShowHexNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length);// 显示16进制数字
void LCD1602_ShowBinNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length); //显示二进制
void LCD_ShowNumber(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length); // 显示数字字符
void LCD1602_DisplaySignedNum(unsigned char Line, unsigned char Column, int Number, unsigned char Length);  //显示有符号数字
void LCD1602_FlowLetters(unsigned char Line, unsigned char StartColumn, char *str, unsigned char Delay);//流动字母#endif

LCD1602_W.h

#ifndef __LCD1602_W_H__
#define __LCD1602_W_H__void LCD1602_WriteCommand(unsigned char Command); //写指令
void LCD1602_WriteData(unsigned char Data); //写数据#endif

LCD1602_W.c

#include <REGX52.H>
#include "intrins.h"//管脚定义
sbit LCD_WR = P2^5; //数据写入操作
sbit LCD_RS = P2^6; //指令输入
sbit LCD_EN = P2^7; //使能#define LCD_DataPort	P0   //端口P0设置为数据位void Delay1ms()		//@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}//RS写指令的驱动
void LCD1602_WriteCommand(unsigned char Command)
{LCD_RS = 0; //写入指令LCD_WR = 0; //写入数据LCD_DataPort = Command; //将指令放到数据总线上,并行端口,Commmand的8位可以直接放上去LCD_EN = 1;  //使能1-0,写入数据Delay1ms();LCD_EN = 0;	Delay1ms();}//RW写数据的驱动
void LCD1602_WriteData(unsigned char Data)
{LCD_RS = 1; //写入指令LCD_WR = 0; //写入数据LCD_DataPort = Data; //将指令放到数据总线上,并行端口,Commmand的8位可以直接放上去LCD_EN = 1;  //使能1-0,写入数据Delay1ms();LCD_EN = 0;	Delay1ms();
}

后期调用都非常方便,都已经模块化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141305.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

平安养老险阜阳中心支公司开展金融教育宣传专项活动

为全面深入开展“金融教育宣传月”的各项工作&#xff0c;不断完善金融惠民利民举措&#xff0c;提升金融服务质效&#xff0c;帮助基层群众增强维权意识、防非反诈的自我保护能力。近日&#xff0c;平安养老保险股份有限公司&#xff08;以下“平安养老险”&#xff09;阜阳中…

【Node.js】RabbitMQ 延时消息

概述 在 RabbitMQ 中实现延迟消息通常需要借助插件&#xff08;如 RabbitMQ 延迟队列插件&#xff09;&#xff0c;因为 RabbitMQ 本身不原生支持延迟消息。 延迟消息的一个典型场景是&#xff0c;当消息发布到队列后&#xff0c;等待一段时间再由消费者消费。这可以通过配置…

带你0到1之QT编程:十一、掌握Containers容器艺术,一网打尽开发利器

此为QT编程的第十一谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

npm install报错,gyp verb `which` failed Error: not found: python

主要错误 gyp verb which failed Error: not found: python2 gyp ERR! configure error gyp ERR! stack Error: Cant find Python executable "python", you can set the PYTHON env variable. npm ERR! node-sass4.14.1 postinstall: node scripts/build.js 全部错…

几分钟学会搭建一个自己的外卖霸王餐系统

大家好&#xff0c;我是鲸天科技千千&#xff0c;大家都知道我是做小程序开发的&#xff0c;平时会给大家分享一些互联网相关的创业项目&#xff0c;感兴趣的可以跟我关注一下。 搭建一个首先就是要搭建一个自己的霸王餐小程序&#xff0c;我们自己的工作就是把这个小程序推广…

合肥鲸天科技的外卖会员卡系统有人做过吗?赚钱吗?

我们先来了解一下这个合肥鲸天科技&#xff0c;通过我在网上找到的资料和企业查询&#xff0c;这家公司还是很有实力的&#xff0c;合肥鲸天科技有限公司也是欢迎有合作的人到公司来进行一个考察和合作其他一些项目的。 外卖会员卡简介绍&#xff1a; 这个外卖会员卡&#xf…

地震勘探原理视频总结(1-6)

目录 一、为什么要学好这门课&#xff1f; 1.1 为什么要学这门课&#xff08;为啥学&#xff09;&#xff1f; 1.2 课程包括哪些主要内容&#xff08;学什么&#xff09;&#xff1f; 1.3 如何学好这门课&#xff08;怎么学&#xff09;&#xff1f; 二、石油的生成与聚集…

linux 操作系统下的cut命令介绍和使用案例

linux 操作系统下的cut命令介绍和使用案例 在 Linux 操作系统中&#xff0c;cut 命令是一个用于文本处理的命令行工具&#xff0c;允许用户从文件或管道数据中提取特定部分并将结果输出到标准输出 1. cut 命令简介 cut 命令主要用于从文本文件中提取特定的字段、字节或字符。…

01.AI推出Yi模型家族:多维度能力的展示

人工智能咨询培训老师叶梓 转载标明出处 01.AI公司提出了Yi模型家族&#xff0c;这一系列语言和多模态模型展示了强大的多维能力&#xff0c;旨在成为下一代计算平台&#xff0c;通过大规模数据和精心设计的训练过程&#xff0c;实现接近人类智能的模型。Yi模型家族基于6B和34…

CrossOver24.0.5破解版免费下载和永久激活图文教程,苹果电脑怎么玩《黑神话:悟空》

CrossOver24可以玩《黑神话&#xff1a;悟空》么&#xff1f;答案是可以的。 1、首先我们需要下载CrossOver24软件。 CrossOver24安装包夸克网盘链接&#xff1a;https://pan.quark.cn/s/35e64d746778 2、下载完成后&#xff0c;我们双击CrossOver.pkg开始安装&#xff0c;然…

【Vue】2

1 Vue 生命周期 Vue生命周期&#xff1a;一个 Vue 实例从 创建 到 销毁 的整个过程 创建(create)阶段&#xff1a;组件实例化时&#xff0c;初始化数据、事件、计算属性等挂载(mount)阶段&#xff1a;将模板渲染并挂载到 DOM 上更新(update)阶段&#xff1a;当数据发生变化时…

【Android】Room—数据库的基本操作

引言 在Android开发中&#xff0c;数据持久化是一个不可或缺的部分。随着应用的复杂度增加&#xff0c;选择合适的数据存储方式变得尤为重要。Room数据库作为Android Jetpack架构组件之一&#xff0c;提供了一种抽象层&#xff0c;使得开发者能够以更简洁、更安全的方式操作SQ…

八股(8)——Spring,SpringBoot

八股&#xff08;8&#xff09;——Spring&#xff0c;SpringBoot 基础1.Spring 是什么&#xff1f;特性&#xff1f;有哪些模块&#xff1f;Spring 有哪些特性呢&#xff1f; 2.Spring 有哪些模块呢&#xff1f;3.Spring 有哪些常用注解呢&#xff1f;Web 开发方面有哪些注解呢…

P5425 [USACO19OPEN] I Would Walk 500 Miles G

*原题链接* 很离谱的题。首先可以想到暴力连边&#xff0c;整个图为一个完全图&#xff0c;将所有的边选出来&#xff0c;然后从小到大一条条加入&#xff0c;当剩下集合数量 <K 的时候就结束。答案为加入的最后一条边的大小。如果用prim算法的话时间复杂度为。足以通过此题…

Python [ GUI编程自学 ],虽然但是,还是想出一个系列

本文主要介绍了GUI组件的其他常用组件部分&#xff1a;optionmenu选项菜单&#xff0c;scale滑块&#xff1b;颜色框、文件选择框&#xff0c;读取文件内容&#xff1b;简单对话框、通用消息、ttk子模块问题&#xff1b; 一系列GUI编程&#xff0c;有相关的专栏&#xff0c;欢迎…

【第36章】Spring Cloud之Seata分布式事务

文章目录 前言一、架构图1. 介绍2. 项目结构3. 功能描述 二、用例1. 准备1.1 系统表1.2 业务表1.3 初始化数据 2. 项目搭建2.1 项目结构2.2 主要依赖2.3 主要配置 三、1. 介绍 总结 前言 上一章我们已经搭建好了Seata服务端&#xff0c;这里我们根据官方案例来完成分布式事务。…

JMeter测试工具的简单了解

Apache JMeter 是一款开源的测试工具&#xff0c;主要用于对软件的性能进行测试。它最初被设计用于测试Web应用&#xff0c;但随着时间的推移&#xff0c;它的功能已经扩展到了其他测试领域。 可以应用到的场景 性能测试&#xff1a;评估应用程序在不同负载下的表现。负载测试…

自闭症学校康复寄宿:点亮每个孩子的希望

自闭症学校康复寄宿&#xff1a;在星贝育园&#xff0c;点亮每个孩子的希望 在自闭症儿童教育的广阔天地里&#xff0c;寄宿制学校以其独特的康复环境和全方位的支持体系&#xff0c;为这些特殊的孩子点亮了一盏希望之灯。广州的星贝育园自闭症儿童寄宿制学校&#xff0c;正是…

2024.9.15周报

一、题目信息 题目&#xff1a;Physics-informed neural networks for solving flow problems modeled by the 2D Shallow Water Equations without labeled data 链接&#xff1a;物理信息神经网络用于解决由二维浅水方程建模的流动问题&#xff0c;无需标记数据- ScienceDi…

【拦截导弹】

​ 题目 ​​ 题解 题解&#xff1a;1010. 拦截导弹&#xff08;dp与贪心&#xff09; - AcWing 我谈几点&#xff1a; 第一&#xff0c;由此复习了upper_bound和lower_bound函数 第二&#xff0c;由此学习了贪心方式求“最多分割不严格递减子序列的数目”和“最长不严格递…