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


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

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

    【学习目标】

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

    四、字符跳动显示实验

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

    4.1 任务描述

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

    图18 字符跳动显示效果

    4.2 工程源码剖析

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

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

    五、液晶滚动显示实验

    5.1 任务描述

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

    图19 液晶滚动显示效果

    5.2 工程源码剖析

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

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

    六、液晶显示功能的扩展

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

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

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

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

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

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

    图20 编译的代码量对比

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

  • 相关阅读:
    洛谷 P8762 [蓝桥杯 2021 国 ABC] 123
    我的递归从不爆栈
    JS--localStorage设置过期时间的方案(有示例)
    imu绘制运动轨迹
    【luogu SP7685】FLWRS - Flowers(DP)(容斥)
    Java Double toHexString()方法具有什么功能呢?
    如何让页面跳转更丝滑
    探究SpringWeb对于请求的处理过程
    R语言——类与对象
    半导体行业调研:工业芯片市场规模分析及发展前景预测
  • 原文地址:https://blog.csdn.net/gmc832002/article/details/139920116