• 江协科技51单片机学习- p16 矩阵键盘


    🚀write in front🚀  
    🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
    🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

    💬本系列哔哩哔哩江科大51单片机的视频为主以及自己的总结梳理📚 

    前言:

    本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记,在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。

    引用:

    51单片机入门教程-2020版 程序全程纯手打 从零开始入门_哔哩哔哩_bilibili

    ​​​​​​c51语言变量语句意思,C51中循环语句-CSDN博客

    矩阵键盘引用:

    【51单片机】矩阵键盘_51单片机4×4矩阵键盘-CSDN博客

    51单片机学习笔记 ——(二)矩阵键盘_51单片机 矩阵键盘-CSDN博客

    郭天祥:

    (51单片机)第三章-数码管显示原理及应用实现-中断_51单片机数码管中断程序-CSDN博客

    正文:

    0. 🌿概述

    在淘宝上购买了江协科技51单片机开发板套件(普中科技STC51单片机A2型号),就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程,通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。

    1. 🚀矩阵键盘

    • 在键盘中当按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵的形式。
    • 采用逐行或逐列的“扫描”,就可以独处任何位置按键的状态。

    矩阵键盘的目的是减少I/O口占用 

    矩阵键盘采用的是矩阵的连接方式,目的是为了减少IO口的使用。

    如果每一个按键都像独立按键一样专门使用一个IO口来控制,那么我们需要的IO口数量就是行×列个。

    但是如果采用矩阵的连接方式,我们需要的IO口数目就会变成行+列个,矩阵的行列数越多,减小的程度就越明显。

    但是按照矩阵形式排列也会出现一些不方便的结果,所以我们采用了类似之前数码管的解决方式——扫描。

    但是与数码管的扫描略有不同,数码管是输出元件,所以数码管的扫描是输出扫描,我们不断循环输出不同的值,利用人眼的视觉暂留实现我们需要的操作。

    而矩阵键盘是输入元件,所以我们矩阵键盘采用的扫描是输入扫描,以非常快的速度不断循环读取IO口的值,达到与正常按键相同的效果。这里还是利用了扫描速度远大于人操作的速度的原理。

    那么如何实现上述操作呢?

    与之前的独立按键进行比较,如果我们单独看矩阵键盘的一行或者一列,就会发现它们有着相同的结构,在此用列来进行比较(用行同理)

    2. 🚀 单片机IO口(准双向口)

    单片机的io口是一种弱上拉的模式~!又被称作是准双向口(input,output) 既可以输入又可以输出,这种就叫做是双向口。

    • 但是这种双向口有点问题:这么样才可以达到输入或者是输出呢 ?像我们这种矩阵键盘的话是不是给上,一端是0,然后读取另一头。
    • 但是另一头你怎么知道它是一种输入低电平)呢?它其实也是作为一种输出端(高电平),它既是输出(高电平)也是输入(低电平)。
    • 那么为什么单片机它的 io 口是默认为高电平呢?是因为它里面拥有一个上拉电阻把低电平变成高电平了 !所以才导致单片机是高电平,
    • 还有一个是当口输出为1的时候驱动能力很弱,允许外部装置将其拉低。当引脚的输出为低电平的时候,它的驱动能力很强,可以吸收相当大的电流。单片机中 P1、P2、P3 都是一种弱上拉的一种模式。

    准双向口输出如下所示:

     单片机的io口是一种弱上拉的模式~!又被称作是准双向口(input,output) 既可以输入又可以输出,这种就叫做是双向口。此种双向口是弱上拉,强下拉,当将IO的输出当为1的时候驱动能力很弱,允许外部装置将其拉。当引脚的输出为低电平的时候,它的驱动能力很强,可以吸收相当大的电流。

    单片机中 P1、P2、P3 都是一种弱上拉的一种模式。

    单片机中 P0 口是开漏输出模式。

    一般按键检测都是接地,检测第电平。为什么不接Vcc,检测高电平哪,因为I/O口配置为低电平要将其拉高为高电平需要比较大的电流。 

    准双向口是一种弱上拉模式,可以用如下的示意图来解释:当IO口开关选择输出1 高电平时,通过电阻接Vcc进行弱上拉其上拉输出能力比较弱,此时I/O接口如果接地可以将其拉低为低电平。

     3. 🚀矩阵键盘扫描

     首先我们需要知道51单片机的引脚默认为高电平,所以我们需要对这8个引脚进行一个初始化,即P1 = 0xFF ;这样就和独立按键的操作基本一致了。

    • 可以发现,如果我们此时只给P13低电平,第一列就和独立按键一样了。
    • 接下来需要做的就是判断在P13为低电平时,P14、P15、P16、P17是否为低电平。如果是,则说明此时有按键按下,接通了电路,使原来是高电平的引脚变为了低电平。
    • 第一列扫描完后,重新初始化P1 = 0xFF ;然后给P12低电平,继续检测P14、P15、P16、P17是否为低电平。
    •  以此类推,不断循环读取按键是否按下,就达到了随时按下任意按键都可以检测出来的效果

     本实验使用的普中科技C51单片机开发板矩阵键盘扫描时需要注意的点,因为开发板的引脚复用冲突,本实验使用按列扫描的方式。

    我们这个开发板 P1_5 口可能会有问题,P1_5口可能一会读到高电平一会读到第 电平,因为在此开发板是行 P1_5 连接到了 Beep ,会造成蜂鸣器鸣叫。

    为了避免这个问题,此实验中使用逐列扫描的方式。

     4. 🚀源码编写

    本次实验使用逐列扫描矩阵键盘的方式,来检测有哪个按键被按下。

    matrix.h

    1. #ifndef __MATRIX_H__
    2. #define __MATRIX_H__
    3. unsigned char MatrixKey();
    4. #endif

    matrix.c

    1. #include
    2. #include "Delay.h"
    3. #include "matrix.h"
    4. /**
    5. * @brief 获取按下按键的键值
    6. * @param 无
    7. * @retval 按下按键的键值,没有按键按下时返回0
    8. * S1=1, S1=2, S3=3, S4=4, S5=5, S6=6, S7=7, S8=8
    9. * S9=9, S10=0, S3=3, S11=确认, S12=取消, S13=删除, S14=,
    10. */
    11. unsigned char MatrixKey()
    12. {
    13. unsigned char keyNumber = 0;
    14. //每次扫描键盘之前,先把P1全部初始化为高电平
    15. P1=0xFF;
    16. P1_3 = 0;
    17. //delay(20)延时进行按键按下消抖, while循环检测松手, delay(20) 按键松开消抖
    18. if(P1_7 == 0) {Delay(20); while(P1_7 == 0); Delay(20); keyNumber = 1;}
    19. if(P1_6 == 0) {Delay(20); while(P1_6 == 0); Delay(20); keyNumber = 5;}
    20. if(P1_5 == 0) {Delay(20); while(P1_5 == 0); Delay(20); keyNumber = 9;}
    21. if(P1_4 == 0) {Delay(20); while(P1_4 == 0); Delay(20); keyNumber = 13;}
    22. P1=0xFF;
    23. P1_2 = 0;
    24. if(P1_7 == 0) {Delay(20); while(P1_7 == 0); Delay(20); keyNumber = 2;}
    25. if(P1_6 == 0) {Delay(20); while(P1_6 == 0); Delay(20); keyNumber = 6;}
    26. if(P1_5 == 0) {Delay(20); while(P1_5 == 0); Delay(20); keyNumber = 10;}
    27. if(P1_4 == 0) {Delay(20); while(P1_4 == 0); Delay(20); keyNumber = 14;}
    28. P1=0xFF;
    29. P1_1 = 0;
    30. if(P1_7 == 0) {Delay(20); while(P1_7 == 0); Delay(20); keyNumber = 3;}
    31. if(P1_6 == 0) {Delay(20); while(P1_6 == 0); Delay(20); keyNumber = 7;}
    32. if(P1_5 == 0) {Delay(20); while(P1_5 == 0); Delay(20); keyNumber = 11;}
    33. if(P1_4 == 0) {Delay(20); while(P1_4 == 0); Delay(20); keyNumber = 15;}
    34. P1=0xFF;
    35. P1_0 = 0;
    36. if(P1_7 == 0) {Delay(20); while(P1_7 == 0); Delay(20); keyNumber = 4;}
    37. if(P1_6 == 0) {Delay(20); while(P1_6 == 0); Delay(20); keyNumber = 8;}
    38. if(P1_5 == 0) {Delay(20); while(P1_5 == 0); Delay(20); keyNumber = 12;}
    39. if(P1_4 == 0) {Delay(20); while(P1_4 == 0); Delay(20); keyNumber = 16;}
    40. return keyNumber;
    41. }

     main.c 

    1. #include
    2. #include
    3. #include "delay.h"
    4. #include "lcd1602.h"
    5. #include "matrix.h"
    6. void main()
    7. {
    8. unsigned char keyNum = 0;
    9. LCD_Init();
    10. //LCD_ShowString(1, 1, "Matrix Key!");
    11. while(1)
    12. {
    13. keyNum = MatrixKey();
    14. if(keyNum)
    15. {
    16. LCD_ShowNum(1, 1, keyNum, 2);
    17. }
    18. }
    19. }

    5. 🚒总结

    • 🍒通过本实验了解了STC51单片机的I/O口准双向口,I/O口的为弱上拉,单片机的I/O口即是输出同时也是输入。因为单片机I/O口是弱上拉,当I/O口输出为1时允许通过外部输入将其下拉为低电平。
    • 🍒STC51单片机的 P1, P2, P3 口为准双向I/O口,弱上拉模式。
    • 🍒STC51单片机的 P0 口默认为开漏输出模式。
    • 🍒当按键较多时,使用矩阵键盘可以节省I/O口资源。
    • 🍒矩阵键盘的检测方式是按照行逐行扫描,或者按照列逐列扫描。
    • 🍒每次扫描之前需要先将所有的矩阵键盘行和列的I/O口置为1,然后给某一行或列低电平,然后按照行或列扫描,检测另一端的输入电平。

     6. 🍎结束

    本文至此结束

  • 相关阅读:
    AdaBoost(上):数据分析 | 数据挖掘 | 十大算法之一
    c++ qt 渐变
    Spring源码分析(十五)循环依赖2:源码分析
    设计模式-命令模式
    第四十三天&jmeter组件及其操作(2)
    C++【特殊类的设计】【单例设计模式】
    Linux 内核页表管理
    Android 8.1 系统锁屏显示流程整理
    opencv 的应用(1)
    高级篇之ENC2-V2编码器的RTSP另一个妙用(长地址转换为短地址)
  • 原文地址:https://blog.csdn.net/weixin_40289409/article/details/139904757