我在高职教STM32——LCD液晶显示(4)

        大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享出来,主要面向广大师生朋友,单片机老鸟就略过吧。欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!

        前边我们讲解了LED、按键和蜂鸣器的应用,这三类器件本身工作原理十分简单,因此我们的重点是放在STM32的GPIO上面。这一章我们来学习一下开发板配套的那块厚厚的液晶屏——LCD1602,聚焦的是这个器件本身的特点和工作时序。因此,我们需要熟读它的数据手册,因为手册里告诉了编程的要点、参数、时序等。阅读器件手册是做单片机和嵌入式开发必备的基本能力,我们就从这一章开始锻炼起来吧。为了不让篇幅太长,本章打算分四个部分来讲解,本文是第四部分。

【学习目标】

  1. 了解LCD1602的工作原理
  2. 掌握LCD1602的工作时序
  3. 领悟软件模拟时序的思路和方法

四、字符跳动显示实验

        我们在前面的液晶指令描述中可以看到,LCD1602还支持光标和屏幕移动,下面我们就通过两个实验来感受一下动态显示的效果。

4.1 任务描述

        这个实验是让字符串里的每个字符逐个跳出来显示,我们将实验的动态效果分解在图18中,中间部分做了一些省略。

图18 字符跳动显示效果

4.2 工程源码剖析

        对于底层的 lcd1602.clcd1602.h 驱动文件来说,我们尽量不去改动。控制字符跳出的代码在主程序里实现,见如下代码清单16。

/********************************************************* 代码清单16:main.c* 项    目:LCD1602液晶显示* 任务描述:字符跳到显示* 实验平台:OneNET STM32开发板V3.2* 作    者:老耿* 日    期:yyyy/mm/dd******************************************************
**///-----------------------------------------------------
// 必要的头文件
//-----------------------------------------------------
#include "delay.h"
#include "lcd1602.h"int main()
{u8 i;	//控制列坐标的变量u8 *p;	//指向字符串的指针delay_init();			//Systick初始化,用于普通的延时Lcd1602_Init();			//LCD1602初始化while(1){i = 2;	            //列坐标初值p = "STM32 Board";	//指向待显示的字符串Lcd1602_Clear(2);	//每次开始显示前先清屏Lcd1602_ShowStr(0, 3, "KylinV3.2");	//首行静态显示delay_ms(250);		//停留一下进入下面的字符跳出效果/* ------------ 以下是控制字符逐个跳出的循环 -------------*/while(*p)	//只要不是结束字符就循环,即while(*p!='\0'){	Lcd1602_ShowChar(1, i, *p);	//第二行指定位置显示一个字符i++;			//下一列p++;			//下一个字符delay_ms(250);	//每个字符跳出的间隔}delay_ms(250);		//跳完停留一下}
}

五、液晶滚动显示实验

5.1 任务描述

        这个实验是让整个屏幕画面整体向左或向右滚动显示,我们将实验动态效果分解在图19中,中间部分做了一些省略。

图19 液晶滚动显示效果

5.2 工程源码剖析

        同理,还是只修改主程序里的控制代码,见如下代码清单17。

/********************************************************* 代码清单17:main.c* 项    目:LCD1602液晶显示* 任务描述:滚动显示* 实验平台:OneNET STM32开发板V3.2* 作    者:老耿* 日    期:yyyy/mm/dd******************************************************
**///-----------------------------------------------------
// 必要的头文件
//-----------------------------------------------------
#include "delay.h"
#include "lcd1602.h"int main()
{delay_init();			//Systick初始化,用于普通的延时Lcd1602_Init();			//LCD1602初始化Lcd1602_ShowStr(0, 3, "KylinV3.2");Lcd1602_ShowStr(1, 2, "STM32 Board");while(1){Lcd1602_WriteCmd(0x18);		//画面整体左移一个字符位置//Lcd1602_WriteCmd(0x1C);	//画面整体右移一个字符位置delay_ms(250);}
}

六、液晶显示功能的扩展

        在上面的实验中,我们通过 Lcd1602_ShowStr() 函数实现了字符串信息的显示。但不知你是否考虑过,倘若显示的内容不是字符的类型,比如传感器采集温湿度值、ADC采集的电压值等,这些数据都是浮点类型的,也想通过液晶显示出来,该如何处理呢?

        针对以上问题,我们补充一个显示函数 Lcd1602_Printf(),来实现多种数据类型的显示,就像使用 printf() 函数那样,可以通过%d、%f、%s这样的形式来指定显示内容的数据类型。该函数用到了C语言中解决变参问题的操作方式,想详细了解这部分知识的同学请自行搜索查阅,这里不展开。源码见如下代码清单18。

/*
************************************************************
*	代码清单18:	Lcd1602_Printf()函数
*	函数功能:	设置LCD1602显示的内容
*	入口参数:	x和y:显示的起始坐标(同上)
*				fmt:不定长参
*	返回参数:	无
*	说明:		
************************************************************
*/
void Lcd1602_Printf(u8 x, u8 y, char *fmt, ...)
{u8 LcdPrintfBuf[33];	//”打印“字符的缓冲区va_list ap;		//定义一个可变参数列表u8 *ptr = LcdPrintfBuf;	//指向缓冲区的指针va_start(ap, fmt);	//获取可变参数列表第一个参数的地址vsprintf((char *)LcdPrintfBuf, fmt, ap);	//把可变参数列表内容格式化成字符串存入缓冲区va_end(ap);			//清空可变参数列表Lcd1602_SetCursor(x, y);	//设置显示位置while(*ptr)		//循环显示缓冲区里的每个字符{Lcd1602_WriteData(*ptr);ptr++;}
}

        有了这个函数,我们就可以在主程序中像使用 printf() 函数那样在液晶屏上“打印”需要的内容了,代码清单19给了一个简单示例。

/********************************************************* 代码清单18:main.c* 项    目:LCD1602液晶显示* 任务描述:用液晶“打印”函数来显示* 实验平台:OneNET STM32开发板V3.2* 作    者:老耿* 日    期:yyyy/mm/dd******************************************************
**///-----------------------------------------------------
// 必要的头文件
//-----------------------------------------------------
#include "delay.h"
#include "lcd1602.h"int main()
{char *str = "Kylin STM32";	//字符串类型float ver = 3.2;			//浮点类型delay_init();				//Systick初始化,用于普通的延时Lcd1602_Init();				//LCD1602初始化Lcd1602_Printf(0, 0, "%s", str);Lcd1602_Printf(1, 0, "version:%.1f", ver);while(1);
}

        可以看到,带变参的 Lcd1602_Printf() 函数更灵活通用,使我们不必再纠结显示内容究竟是什么数据类型,这是它的优势。那有没有劣势呢?当然有了,在显示同样内容的情况下,使用Lcd1602_Printf() 函数比用 Lcd1602_ShowStr() 函数编译出来的代码量大了不是一点儿,如图20所示。

图20 编译的代码量对比

(第四部分完,共四部分)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[经验] 如何做虾炒白菜 #学习方法#知识分享

如何做虾炒白菜 虾炒白菜的做法 虾炒白菜是一道营养丰富且美味可口的菜肴,虾肉的鲜嫩与白菜的甜脆相结合,口感极佳。接下来,让我们一起来学习一下虾炒白菜的详细做法。 食材准备 虾:约200克(选用新鲜活虾&#xff…

【深度学习】python之人工智能应用篇——视频生成技术

视频生成技术是一种基于深度学习和机器学习的先进技术,它使得计算机能够根据给定的文本、图像、视频等单模态或多模态数据,自动生成符合描述的、高保真的视频内容。这种技术主要依赖于深度学习模型,如生成对抗网络(GAN&#xff09…

基于 Native 技术加速 Spark 计算引擎

本文整理自 2024 年 6 月 DataFunSummit 2024 OLAP 架构峰会 Lakehouse 湖仓一体化架构论坛的同名主题分享。 今天分享的主题是基于 Native 技术加速 Spark 计算引擎,大家将会了解到如何基于 ClickHouse 来改造 Spark 引擎,最终获得较为可观的性能提升。…

C++实现多线程安全的生产者消费者字节缓冲区

文章目录 介绍实现细节**BytesBuffer 类****生产者和消费者** 性能优化总结 介绍 本文介绍如何使用C实现一个多线程安全的简单字节缓冲区,并进行性能测试。 实现细节 BytesBuffer 类 BytesBuffer 类通过使用条件变量和双缓冲区机制,实现了生产者和消…

【Linux】 在 Linux 中更换主机名

那年夏天我和你躲在 这一大片宁静的海 直到后来我们都还在 对这个世界充满期待 今年冬天你已经不在 我的心空出了一块 很高兴遇见你 让我终究明白 回忆比真实精彩 🎵 王心凌《那年夏天宁静的海》 在 Linux 系统中,更换主机名是系统…

使用Redis Lua脚本实现高级限流策略

引言 在现代的Web应用中,限流是一个非常重要的功能,它帮助我们控制对某些资源的访问频率,以防止系统过载和滥用。Redis是一个高性能的键值存储系统,它的原子操作和Lua脚本功能为实现复杂的限流策略提供了强大的支持。本文将详细介…

day50 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 392.判断子序列

1143. 最长公共子序列 提示 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删…

大腾智能,基于云原生的国产工业协同平台

大腾智能是一家基于云原生的国产工业软件与数字化协同平台,专注于推动企业数字化转型与升级,为企业提供一系列专业、高效的云原生数字化软件及方案,推动产品设计、生产及营销展示的革新,实现可持续发展。 大腾智能旗下产品 3D模型…

USB2.0学习4--USB包结构和包类型

目录 1. USB包基本结构 1.1 SOP域(Start Of Packet) 1.2 SYNC域(同步域) 1.3 PID域(标识域) 1.4 地址域(ADDR) 1.5 帧号域(Fram) 1.6 数据域&#xff…

前端也需要知道的一些常用linux命令

前端也需要知道的一些常用linux命令 1.问题背景2.连接工具(SecureCRT_Portable)a.下载工具b.连接服务器c.登录到root账户 3.基本命令a.cd命令和cd ..b.ll命令和ls命令c:cp命令d.rm命令e:rz命令f.unzip命令g.mv命令h.pwd命令(这里没有用到&…

机器学习之支持向量机丨神经网络测试

选择题 SVM中的什么是支持向量? 【 正确答案: D】 A. 数据集中的所有样本 B. 模型参数 C. 模型的预测输出 D. 训练数据中离决策边界最近的样本点 支持向量机(SVM)算法的主要目标是: 【 正确答案: C】 A. 最小化间隔 B. 最小化损失函数 C. 最大化间隔 D.…

【LinuxC语言】TCPIP的经典5层结构

文章目录 前言TCP/IP的结构结构示意图结构的含义生活中的TCP/IP例子总结前言 TCP/IP,全称传输控制协议/因特网互联协议,是用于在互联网上进行数据交换的一组协议,形成了互联网的基础。TCP/IP的经典五层结构包括:物理层、数据链路层、网络层、传输层和应用层。这些层次各自…

CSS 相对父级固定,且不随滚动条滚动

CSS 相对父级固定&#xff0c;且不随滚动条滚动 <div class"parent"><div class"child-one">我是固定位置的子元素</div><div class"child-tow">我是滚动的子元素</div> </div>.parent {height: 200px; /*…

以正合,以奇胜,守正出奇,稳健

个人感觉说实话&#xff0c;在所里待的这几年&#xff0c;尤其是后两年&#xff0c;收获颇多&#xff0c;不管是智识上的&#xff0c;还有一堆兄弟&#xff0c;还有愿意分享和帮助我的老师们。 不管是搞科研还是做生意&#xff0c;稳健&#xff0c;在所里的时候&#xff0c;有…

Python-天天基金网爬虫分析

1.主题式网络爬虫名称&#xff1a;天天基金网爬虫分析 2.主题式网络爬虫爬取的内容与数据特征分析&#xff1a;通过访问天天基金的网站&#xff0c;爬取相对应的信息&#xff0c;最后保存下来做可视化分析。 3.主题式网络爬虫设计方案概述&#xff08;包括实现思路与技术难点…

益百分4.0版益生君重磅来袭,为您保驾护航

益百分4.0版益生君重磅来袭&#xff0c;为您保驾护航 暑期来临&#xff0c;很多人们终于等来了一年中最幸福的时刻&#xff0c;三五成群、结伴旅游成为他们选择欢度暑假的方式。 全国各地的旅游景点也迎来了旺季&#xff0c;各大旅游公司也推出了各种各样的旅游团购活动&#x…

FFmpeg交叉编译报错pkg-config not found

ffmpeg交叉编译时报错&#xff1a; WARNING: arm-linux-gnueabihf-pkg-config not found, library detection may fail.不慌&#xff0c;没有就下载嘛&#xff0c;直接install&#xff1a; sudo apt-get install pkg-config-arm-linux-gnueabihf 参考&#xff1a; How To I…

C++面试八股文:std::deque用过吗?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C工程师开发岗位第26面&#xff1a; 面试官&#xff1a;deque用过吗&#xff1f; 二师兄&#xff1a;说实话&#xff0c;很少用&#xff0c;基本没用过。 面试官&#xff1a;为什么&#xff1f; 二师兄&#xff1a;因为使…

[学习笔记]3GPP R18宣布冻结,对物联网的影响是哪些?

6月18日&#xff0c;在上海举行的3GPP RAN&#xff08;无线接入网络项目&#xff09;第104次会议上&#xff0c;5G-A的第一代技术标准R18标准正式冻结。R18标准从立项到冻结历时3年多&#xff0c;是5G标准的第四版&#xff0c;也是面向5G-Advanced&#xff08;5G-A&#xff09;…

API-事件对象

学习目标&#xff1a; 掌握事件对象 学习内容&#xff1a; 获取事件对象事件对象常用属性trim方法案例 获取事件对象&#xff1a; 事件对象是什么 也是个对象&#xff0c;这个对象里有事件触发时的相关信息。 例如&#xff1a;鼠标点击事件中&#xff0c;事件对象就存了鼠标…