#学习笔记二:GPIO的探索与矩阵按键
##1.在配置cubemx时,对gpio的配置有开漏输出和推挽输出两种方式,
###这里有一篇文章(别人的文章)讲的很详细link戳这里跳转

通俗来讲,推挽输出,可以输出高电平,也可以输出低电平。

而开漏输出,输出低电平,在有上拉电阻时,可以正常工作,他可以有多个上拉电阻,并且是与关系。
开漏输出
所谓的推挽输出模式,是根据这两个 MOS 管的工作方式来命名的。在该结构中输入高电平时,经过反向后,上方的 P-MOS 导通,下方的 N-MOS 关闭,对外输出高电平;而在该结构中输入低电平时,经过反向后,N-MOS 管导通,P-MOS 关闭,对外输出低电平。当引脚高低电平切换时,两个管子轮流导通,P 管负责灌电流,N 管负责拉电流,使其负载能力和开关速度都比普通的方式有很大的提高。推挽输出的低电平为 0 伏,高电平为 3.3 伏,具体参考图 7_2,它是推挽输出模式时的等效电路。


开漏输出
开漏输出模式时,上方的 P-MOS 管完全不工作。如果我们控制输出为 0,低电平,则 P-MOS管关闭,N-MOS 管导通,使输出接地,若控制输出为 1 (它无法直接输出高电平) 时,则 P-MOS管和 N-MOS 管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须外部接上拉电阻,参考图 7_3 中等效电路。它具有“线与”特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接的电源的电压。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0 伏。

##2.还有就是对IO口拉高还是拉低的问题。
这里有三种情况,pull down(拉低),pull up(拉高),no pull down no pull up(什么也不干),这是对IO口初始状态的设定。后面结合实例进行讲解。
##3.GPIO的函数
1.void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
功能: GPIO初始化
实例:HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);

2.void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值

实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:读取引脚的电平状态、函数返回值为0或1

实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
功能:引脚输入高低电平

实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
翻转引脚的电平状态

实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4); 常用在LED上

HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:锁住引脚电平,比如说一个管脚的当前状态是1,当这个管脚电平变化时保持锁定时的值。

实例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
功能: 外部中断服务函数,清除中断标志位

实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能: 中断回调函数,可以理解为中断函数具体要响应的动作。

实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);
这些函数可以在下图这个.h文件找到。

下面贴上一段矩阵按键的扫描,帮助理解。

 HAL_GPIO_WritePin (R1_PORT, R1_PIN, GPIO_PIN_RESET);//在MX中设为output,只有这个函数能改变引脚电平状态,拉低一个,剩下的拉高HAL_GPIO_WritePin (R2_PORT, R2_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R3_PORT, R3_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R4_PORT, R4_PIN, GPIO_PIN_SET);if (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN)))         //在MX中设置为input型,pull up拉高电平,这个函数读取io口电平,不是高即为按下,就锁定了一行中所在的一列{while (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN))); return 13;                                          //S13   1}if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN))){while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));   return 9;               //S9 2}if (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN))){while (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN)));   return 5;                                                      //S5    3}if (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN))){while (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)));   return 1;              //S1       4}

以这段代码为例(4*4矩阵按键),在cubemx中设置引脚状态为output,用HAL_GPIO_WritePin这个函数改变引脚电平,将第一行四列的引脚电平分别写为低,高高高,接下来扫描行,
if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)))
{
while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));
return 9; //S9 2
}
我们知道按键按下,电路接通,即低电平按键生效,当读到的电平不是高电平,就锁定了行和列。
下面给出完整代码

uint8_t read_key(void)             //矩阵键盘扫描作用函数
{HAL_GPIO_WritePin (R1_PORT, R1_PIN, GPIO_PIN_RESET);//在MX中设为output,只有这个函数能改变引脚电平状态,拉低一个,剩下的拉高HAL_GPIO_WritePin (R2_PORT, R2_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R3_PORT, R3_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R4_PORT, R4_PIN, GPIO_PIN_SET);if (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN)))        //在MX中设置为input型,pull up拉高电平,这个函数读取io口电平,不是高即为按下,就锁定了一行中所在的一列{while (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN))); return 13;                                          //S13   1}if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN))){while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));   return 9;               //S9 2}if (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN))){while (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN)));   return 5;                                                      //S5    3}if (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN))){while (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)));   return 1;              //S1       4}HAL_GPIO_WritePin (R1_PORT, R1_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R2_PORT, R2_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin (R3_PORT, R3_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R4_PORT, R4_PIN, GPIO_PIN_SET);if (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN))){while (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN)));   //S14    5return 14;              }if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN))){while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));   //S10    6return 10; }if (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN))){while (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN)));    //S6   7return 6;  }if (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN))){while (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)));   //S2   8
return 2; }HAL_GPIO_WritePin (R1_PORT, R1_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R2_PORT, R2_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R3_PORT, R3_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin (R4_PORT, R4_PIN, GPIO_PIN_SET);if (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN))){while (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN)));    //S15  9
return 15; }if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN))){while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));   //S11  0
return 11;  }if (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN))){while (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN)));   //S7  K1return 7;}if (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)))             //S3   K2{while (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)));   return 3;}HAL_GPIO_WritePin (R1_PORT, R1_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R2_PORT, R2_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R3_PORT, R3_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin (R4_PORT, R4_PIN, GPIO_PIN_RESET);if (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN))){while (!(HAL_GPIO_ReadPin (C1_PORT, C1_PIN)));   //S16  K3return 16;}if (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN))){while (!(HAL_GPIO_ReadPin (C2_PORT, C2_PIN)));   //S12  K4return 12;}if (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN))){while (!(HAL_GPIO_ReadPin (C3_PORT, C3_PIN)));   //S8     K5return 8; }if (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN))){while (!(HAL_GPIO_ReadPin (C4_PORT, C4_PIN)));   //S4      K6return 4;}return 0;
}

下面是.h文件

#ifndef _key_H_
#define _key_H_#include "main.h"#define R3_PORT GPIOC
#define R3_PIN GPIO_PIN_10#define R2_PORT GPIOC
#define R2_PIN GPIO_PIN_9#define R1_PORT GPIOC
#define R1_PIN GPIO_PIN_8#define C2_PORT GPIOC
#define C2_PIN GPIO_PIN_12#define C4_PORT GPIOC
#define C4_PIN GPIO_PIN_7#define C3_PORT GPIOC
#define C3_PIN GPIO_PIN_6#define C1_PORT GPIOD
#define C1_PIN GPIO_PIN_2#define R4_PORT GPIOC
#define R4_PIN GPIO_PIN_11
uint8_t OLED_change(uint8_t SS);
uint8_t  read_key(void);
unsigned int call(unsigned int  high_time);#endif

欢迎指正

学习笔记二.矩阵按键相关推荐

  1. MATLAB学习笔记(二) -- 矩阵和数组

    一.矩阵和数组的创建 函数法主要用于一些具有特许规律的矩阵. (1)zeros() -- 全零矩阵生成,ones() -- 全1矩阵 (2)eye() -- 单位矩阵,不支持二维以上的矩阵生成 (3) ...

  2. Vue3学习笔记(二)——事件按键表单修饰符与表单

    点击查看上一篇文章

  3. MATLAB学习笔记——二维和三维绘图

    MATLAB学习笔记--二维和三维绘图 近期练习matlab的二维和三维绘图,整理一下,以防忘记. 文章目录 MATLAB学习笔记--二维和三维绘图 一.二维绘图 1.plot命令 2.fplot 命 ...

  4. 二维码学习笔记(二) | 数据分析与数据编码

    唠唠闲话 二维码笔记系列(原文地址): 『二维码学习笔记(一) | 二维码概述』 『二维码学习笔记(二) | 数据分析与数据编码』 『二维码学习笔记(三) | 纠错编码』 『二维码学习笔记(四) | ...

  5. 【台大郭彦甫】Matlab入门教程超详细学习笔记二:基本操作与矩阵运算(附PPT链接)

    Matlab入门教程超详细学习笔记二:基本操作与矩阵运算 前言 一.基本操作 1.把matlab当作计算器使用 2.变量 3.控制格式输出 二.矩阵运算 1.矩阵 2.矩阵索引 3.使用:创建向量 4 ...

  6. 计算鬼成像学习笔记二:二阶关联函数探究

    计算鬼成像学习笔记二:二阶关联函数探究 1 一阶关联函数 2 二阶关联函数 3 二阶关联如何重构物体 4 差分鬼成像关联公式 5 归一化鬼成像关联公式 1 一阶关联函数 一阶关联函数是光场的电场强度之 ...

  7. Polyworks脚本开发学习笔记(二十)-补充几个常见操作指令的使用

    Polyworks脚本开发学习笔记(二十)-补充几个常见操作指令的使用 大概要写到结尾了,最后几篇就将手册的各常用命令再看一遍,组合一下,并列举出常见的一些有用的操作. DATA_COLOR_MAP数 ...

  8. GEE(Google Earth Engine) 最基础代码学习笔记二 —— JavaScript 语言

    GEE(Google Earth Engine) 学习笔记二 Javascript 语言 1. 注释 print('Hello World!'); 如果要注释,则在代码前面加//,比如: // pri ...

  9. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

最新文章

  1. 使用php开发,基于swoole扩展开发的工具 swoole-crontab
  2. IntelliJ IDEA中日志分类显示设置
  3. 防止Linux库so中的接口冲突
  4. 谈身份管理之基础篇 - 保障云上安全,从[规范账号使用]开始
  5. 字符串——垂直柱状图(洛谷 P1598)
  6. 为了做服务注册迁移,我提前准备了这些东西,来看看对你有没有用!
  7. 前端开发工具介绍----合成雪碧图工具(css sprite)
  8. linux 串口内核加载,linux对串口编程的详解(从应用层到内核驱动,包括232,485)
  9. error LNK2019: 无法解析的外部符号 _WinMain,在函数_tmainCRTStartup中被引用
  10. 傅里叶变换进行图像变换Matlab实现
  11. SMOTE算法及其Python实现
  12. sony z及泛泰a870 安装optware记录
  13. 用计算机如何打对数,怎样使用科学计算器计算对数?
  14. getch方法_linux 下getch()函数实现
  15. 六、模块实现:用户管理模块(1)
  16. 斯蒂夫乔布斯传札记:第六波
  17. 【C语言基础】printf函数
  18. Istio服务网格详解
  19. 【已解决】IE无法上网、有道云PC客户端无连接
  20. A 产品基础知识 mrd crd

热门文章

  1. 求长方形的周长和面积c语言两个函数_「长方形的周长」C语言初级-输入长方形的两边长a和b,求长方形的周长和面积 - 金橙教程网...
  2. linux下查看bios命令,Linux/centos/ubuntu下查看主板BIOS信息
  3. 苹果字体怎么改_苹果手机的APPLE ID密码忘了怎么改?
  4. python编写关不掉的流氓表白软件
  5. 【Nav2中文网】七、配置指南(三)行为树XML节点 之 控制插件--RoundRobin
  6. 【WebLogic】Windows系统下WebLogic 12.1.3.0的安装和补丁
  7. idea 实现抽象类中的方法 快捷键
  8. 【STM32小案例 04 】STM32简单使用L298N电机驱动模块 控制直流电机正反转
  9. nuclei程序运行时的过程解决
  10. can报文信号矩阵分析