STM32
直播中

贾飞小

7年用户 1779经验值
私信 关注
[问答]

LCD1602是如何去实现按键控制光标移动及闪烁的

该如何去调试时间显示的程序呢?
LCD1602是如何去实现按键控制光标移动及闪烁的?

回帖(1)

龙慧

2021-12-22 14:05:47
第三部分、随堂记录

2.4.1.单片机做项目常识

2.4.1.1、行业常识
(1)单片机做产品主要行业:小家电、物联网终端设备等,要求功能不复杂、无大屏幕显示、人机界面多为按键(机械式、电容触摸式),要求长时间可靠运行。
(2)产品开发包括:产品定义(产品经理)+外观、结构设计(结构工程师等)+电子硬件(硬件工程师)+软件设计(软件工程师)
(3)一般步骤:选定方案后先使用方案商提供的开发板进行硬件连接和核心功能的软件开发,同时移植设计自己的硬件板子(发出、买元器件、拿回来焊接等),再移植调试。
2.4.1.2、方案选型
(1)行业内经验
(2)选自己熟悉、擅长使用的方案
(3)比较专的方向选面向方向的解决方案
(4)开发效率、成本、性能扩展、稳定供货等
2.4.1.3、本课程定位和思路
(1)学习是面向知识和能力培养,而做项目是面向产品的。
(2)本课程目标是:充分使用手头硬件资源,做一个练习性的项目,主要目的是学习把项目工程源码写的更多、功能更复杂,在过程中锻炼自己的编程能力、调试能力、把控能力。
(3)实践中用51去做的项目都不会太复杂,51当前更大的用途是做专用SoC(譬如电容触摸IC、指纹识别IC等)

2.4.2.单片机小项目介绍

2.4.2.1、项目名称:基于51单片机的温度报警器
(1)主控:stc51;编程语言:C语言;开发环境:Keil;主要功能:
(2)系统人机界面:按键和IR:修改时间
(3)1602屏显示时间和温度;当温度超过预定值时蜂鸣器和电机工作报警
2.4.2.2、硬件资源分配
    1602屏  P0;P2^7;P2^5;P2^6;
    4*4按键 P2
    串口    P3.0 P3.1
    IR(红外)P3.2
    传感器  DS18B20 P3.7 ; DS1302 P3.4 P3.6
    步进电机(四线双极性) P1.0 - P1.5
    蜂鸣器  P1.6
2.4.2.3、项目流程
(1)编写、移植、封装、测试底层硬件模块操作库
(2)梳理、定义应用层功能
(3)逐个实现各功能,并联合调试,测试功能是否正常
(4)实际测试使用,并解决bug持续维护。
3.4.2.4、一些小问题
(1)项目中需要用到的一些额外知识(譬如C语言结构体之类的),用到时再讲。不会系统讲,还是以用为主,需要额外学习的要去另外找资料来看。
(2)注意语法和格式
(3)关键不在于听课,而在于实践动手。

2.4.3.工程建立及框架构建

2.4.3.1、建立工程项目
(1)建立各文件夹
(2)建立Keil工程
(3)创建c和h文件并尝试编译
2.4.3.2、端口分配检查确定
(1)主要是P2端口的确定
(2)后续思路:逐个接线并调试底层驱动,遇到问题再尝试调整
    1602屏  P0;P1^4;P1^5;P1^6;
    4*4按键 P2
    串口    P3.0 P3.1
    IR(红外)P3.2
    传感器  DS18B20 P3.7 ; DS1302 P3.4 P3.5 P3.6
    步进电机(四线双极性) P1.0 - P1.3
    蜂鸣器  P1.7

2.4.4.第一个模块-串口

2.4.4.1、移植并调试确认基本功能
(1)驱动源码移植
(2)测试
2.4.4.2、封装
(1)何为封装
(2)封装底层接口实践
(3)加说明头

2.4.5_6.DS18B20移植1_2

问题:double t = 25.4; 要用串口把25.4打印出来给串口助手去显示
串口助手显示方式有2种:二进制方式和文本方式。文本方式最直观,但是需要通过串口去发送的不是double,不是int,而是ASCII码的字符串
意思就是:想要看到25.4,得uart_send_string("25.4");
所以我们需要一个函数,能够把double类型的t,给转成对应的字符串来发给串口去显示
怎么得到这个函数?方法1:自己写;方法2:用库函数

2.4.7.问题解决和LCD1602的移植

2.4.7.1、上节问题分析与解决思路
2.4.7.2、LCD1602的移植和封装
1602屏  P0;P2^5;P2^6;P2^7;

2.4.8.测温和LCD1602联调


2.4.9.DS1302的移植和联合调试

2.4.9.1、DS1302移植
2.4.9.2、时间数据的封装
(1)一个时间=年+月+日+时+分+秒+周几,所以时间是一个复杂变量(对比温度是一个简单变量)
(2)C语言提供结构体这种语法技巧,来处理复杂变量
(3)区分清楚2个概念:结构体类型和结构体变量
(4)结构体这种语法使用时有套路的:第一步先定义结构体类型,第二步用类型去生产结构体变量,第三步使用结构体变量(其实是使用结构体变量肚子里包着的内容的)

2.4.10_11.用结构体来实现时间读写1_2


2.4.12.时间显示的调试

2.4.12.1、如何调试程序
(1)第一步,也是最关键的一步,就是定位问题
(2)第二步,修改代码,看效果,再修改····
C语言位运算,参考《朱有鹏老师嵌入式linux核心课程》的第4部分《C语言高级专题》的第2部分

2.4.13.时间写入函数的封装


2.4.14.蜂鸣器的封装和调试1


2.4.15.蜂鸣器的封装和调试2


2.4.16.蜂鸣器频率的设置问题解决


2.4.17.步进电机的移植和调试

接线:
P1.0 - A-
P1.1 - A+
P1.2 - B-
P1.3 - B+

2.4.18.按键的移植和调试

   
2.4.19.按键引脚冲突的解决

    1602屏  P0;P2^5;P2^6;P2^7;
    4*4按键 P1
    串口    P3.0 P3.1
    IR(红外)P3.2
    传感器  DS18B20 P3.7 ; DS1302 P3.4 P3.5 P3.6
    步进电机(四线双极性) P2.0 - P2.3
    蜂鸣器  P2.4

2.4.20.红外的移植和调试

第一步:用中断的方式来解码红外接收,完成
第二步:因为中断接收红外的时间太长,所以和别的模块容易产生冲突。怎么办?办法就是
在外面(不在中断isr内)进行延时并接收红外的一帧数据,不在中断中做。
难点和问题在哪里:
1、中断还要不要?因为红外遥控信号是异步的,所以必须用中断来处理
2、但是完整接收时间又太长不能都放在中断中,所以我们在中断中启动接收开个头,然后交给外部去做整个接收工作。
3、外部做的时候精确延时函数的实现是关键,不能用delay方式,而是用定时器来实现的
最后总结一下:其实这里很复杂,很麻烦。

2.4.21.项目功能梳理和定义

2.4.21.1、功能规划
(1)默认情况下显示时间和温度
(2)温度阈值显示及调整
(3)温度超过阈值后报警
(4)时间调整
(5)扩展功能:闹钟
2.4.21.2、细节实现
(1)时间和温度显示的格式
T:23.6-37.9
20170423-162312
(2)在LCD1602上显示时设置一个光标,显示分2种模式,常规模式和调整模式。常规模式下没有光标显示,调整模式下有个光标,光标闪烁落在哪个格子,就是要调整哪个格子内容。
(3)按键中有一个模式切换键(譬如定义键值为0的按键),默认是普通模式,按一下切换为调整模式,再按切换回普通模式。
(4)调整模式下光标的移动要靠按键,按键中有4个按键分别为上下左右。
(5)当光标落在某个格子上时,按下+或者-按键,数字会加1和减1处理。
(6)硬件闹钟、软件闹钟

2.4.22.LCD1602实现按键控制光标移动及闪烁1

单片机项目的分层:
分2层的体系:驱动层、应用层
分3层的体系:底层驱动层、上层驱动层、应用层
分3层的体系:驱动层、中间层、应用层

2.4.23.LCD1602实现按键控制光标移动及闪烁2

C语言的2种取反
! 逻辑取反
~ 按位取反        ~0b1011 == 0b0100
x = !!y;
定义:keyValue = 1时,这个按键定义为模式调整按键。

2.4.24_25.LCD1602实现按键控制光标移动及闪烁3_4

按键定义:2往左,3往上,4往右
绝对坐标系、相对坐标系

2.4.26.程序流程梳理及基本显示功能实现

2.4.26.1、程序流程梳理
(1)按键获取与其他代码的合理安排
(2)一个单片机程序只有且只能有一个主程序
2.4.26.2、基本显示功能实现
(1)温度显示
(2)阈值温度显示
(3)时间显示
(4)待实现:阈值温度调整

2.4.27.bug查找和解决

程序运行逻辑:
1、当按下模式调整按键时,如果是由常规模式变到调整模式,那么:停止温度和时间的刷新(此时LCD1602上显示的内容就是刚才正在显示的),响应按键事件(主要有2种,2、3、4按键是调整光标位置,5、6按键是调整光标所在位置的数字加减)
2、当按下模式调整按键时,如果是由调整模式变到常规模式下,那么:恢复温度和时间的刷新,停止响应按键2、3、4、5、6,只响应按键1。同时要把刚才调整模式下做的调整结果生效(譬如温度阈值变化了要更新,譬如时间调整了要写入ds1302内部去生效)

2.4.28.增加调试解决问题


2.4.29.数字加减调整功能的分析


2.4.30.时间加减调整功能实现1

20170425153919-2

2.4.31.时间加减功能完整实现2

使用switch case
在51单片机裸机程序中,DS18B20的时序时间都是用delay的方式算出来的,其实这个是非
典型的做法。真正主流的做法是用定时器来实现精确定时(操作系统下会使用系统systick
来计时),这样时序不会被其他代码所影响。
我们这里遇到的问题应该就是蜂鸣器的代码影响到了主程序中delay函数,导致延时不准
所以DS18B20有时读出的温度是错的,解决办法就是DS18B20的延时用定时器来实现即可。
一般的51单片机程序不会这么复杂,51本来就是几十年前的东西,做简单任务的。复杂些
的设计用STM32会更好,而且STM32现在也很便宜了,性价比更高。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分