【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键
这里写目录标题
- 1、矩阵按键
- 2、代码片段分析
1、矩阵按键
通过将4x4矩阵按键的每一行依次设为低电平,同时保持其它行为高电平,然后读取所有列的电平状态,可以检测到哪个按键被按下。如果某列变为低电平,说明对应行和列的按键被按下。这样逐行扫描即可确定按键的位置。
2、代码片段分析
/*********************************************************************@Function : 矩阵键盘行列读写操作@Parameter : ReadIo :读输入的IOWirteIo :写输出的IO@Return : 行列IO输出状态
**********************************************************************/
uint8_t GPIO_KEY_RW(uint16_t ReadIo,uint16_t WirteIo)
{uint16_t Wdata=0,Rdata=0; /* 写操作 */KeyBordSetOut(KEY_ALL); //设置IOif(WirteIo==0x0f00)GPIO_SetBits(GPIOE,KEY_LINE); //写行else GPIO_ResetBits(GPIOE,KEY_LIST); //写列 Wdata = GPIO_ReadOutputData(GPIOE);//读输出 Wdata &= WirteIo; //取有效区域/* 读操作 */KeyBordSetIn(ReadIo); //设置IO Rdata = GPIO_ReadInputData(GPIOE); //读输入Rdata &= ReadIo; //取有效区域/* 状态返回 */Rdata |= Wdata; //合并两次读取的数据return (uint8_t)(Rdata>>8); //移位返回
}
初始化:
Wdata 和 Rdata 初始化为 0。
写操作:
检查 WirteIo 是否为 0x0f00(二进制:0000111100000000):
如果是,则设置 GPIOE 中对应 KEY_LINE 的位(具体位取决于 KEY_LINE 的定义)。
如果不是,则复位 GPIOE 中对应 KEY_LIST 的位(具体位取决于 KEY_LIST 的定义)。
读取 GPIOE 的输出数据到 Wdata。
Wdata 与 WirteIo 进行与操作,保留有效区域的数据。
读操作:
使用 ReadIo 设置IO方向。
读取 GPIOE 的输入数据到 Rdata。
Rdata 与 ReadIo 进行与操作,保留有效区域的数据。
状态返回:
将 Wdata 和 Rdata 进行或操作,合并两次读取的数据。
返回 Rdata 右移8位后的值。
假设按下第一个按键
假设按下的是第一个按键,具体的步骤如下:
初始化:
Wdata = 0
Rdata = 0
写操作:
WirteIo == 0x0f00 假设为真,则设置 GPIOE 对应 KEY_LINE 的位。
读取 GPIOE 输出数据:
假设 GPIOE 输出数据为 0000111100000000(二进制)。
Wdata &= WirteIo:
Wdata = 0000111100000000 & 0000111100000000 = 0000111100000000
读操作:
设置IO方向,具体操作取决于 KeyBordSetIn 函数。
读取 GPIOE 输入数据:
假设按下第一个按键时,GPIOE 输入数据为 0000000100000000(二进制)。
Rdata &= ReadIo:
Rdata = 0000000100000000 & ReadIo(假设 ReadIo 为 0000000100000000),结果 Rdata = 0000000100000000
状态返回:
Rdata |= Wdata:
Rdata = 0000000100000000 | 0000111100000000 = 0000111100000000
返回值:
将 Rdata 右移8位后返回:Rdata >> 8 = 00001111
所以函数返回值为 0x0F(二进制:00001111)
/*********************************************************************@Function : 矩阵键盘键值扫描@Parameter : N/A@Return : 键值
**********************************************************************/
uint8_t KeyBoardScan(void)
{uint8_t KeyValue=0,Key=0;uint8_t a = 0;/* 检测键盘是否有按键按下,0x0f表示所有列都未按下 */if(GPIO_KEY_RW(KEY_LIST,KEY_LINE)!=0x0f){/* 测试列状态 */Key = GPIO_KEY_RW(KEY_LIST,KEY_LINE); // 读取列的状态/* 判断列状态并映射为按键值 */switch(Key){case(0x1F): // 第一列所有行都按下KeyValue = 1; // 对应键值为1break;case(0x2F): // 第二列所有行都按下KeyValue = 2; // 对应键值为2break;case(0x4F): // 第三列所有行都按下KeyValue = 3; // 对应键值为3break;case(0x8F): // 第四列所有行都按下KeyValue = 4; // 对应键值为4break;}/* 测试行状态 */Key = GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 读取行的状态/* 判断行状态并映射为按键值 */switch(Key){case(0x0E): // 第一行所有列都按下KeyValue = KeyValue; // 保持当前列的键值不变break;case(0x0D): // 第二行所有列都按下KeyValue = KeyValue + 4; // 当前列的键值加4,对应第二行break;case(0x0B): // 第三行所有列都按下KeyValue = KeyValue + 8; // 当前列的键值加8,对应第三行break;case(0x07): // 第四行所有列都按下KeyValue = KeyValue + 12; // 当前列的键值加12,对应第四行break;}/* 按键松手检测 */while((a < 50) && (Key != 0x00)) // 循环检测按键是否松手,最多检测50次{delay_ms(5); // 延时5毫秒Key = GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 再次读取行的状态a += 1; // 计数器加1}}/* 返回键值 */return KeyValue;
}
相关文章:

【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键
这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平,同时保持其它行为高电平,然后读取所有列的电平状态,可以检测到哪个按键被按下。如果某列变为低电平,说明对应行和列的按键被按下…...
长期更新方法库推荐pmq-ui
# pmq-ui pmq-ui 好用方法库ui库, 欢迎您的使用 ## 安装 1. 克隆项目库到本地: 2. 进入项目目录:cd pmq-ui 3. 安装依赖:npm install pmq-ui ## 使用 <!-- 1. 启动应用: 2. 访问 [http://localhost:3000](http://localhost:300…...

<数据集>抽烟识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:4860张 标注数量(xml文件个数):4860 标注数量(txt文件个数):4860 标注类别数:1 标注类别名称:[smoking] 使用标注工具:labelImg 标注规则:对…...
SQL Server 端口设置教程
引言 你好,我是悦创。 在配置 SQL Server 的过程中,设置正确的端口非常关键,因为它影响到客户端如何连接到 SQL Server 实例。默认情况下,SQL Server 使用 TCP 端口 1433,但在多实例服务器上或出于安全考虑ÿ…...

【React1】React概述、基本使用、脚手架、JSX、组件
文章目录 1. React基础1.1 React 概述1.1.1 什么是React1.1.2 React 的特点声明式基于组件学习一次,随处使用1.2 React 的基本使用1.2.1 React的安装1.2.2 React的使用1.2.3 React常用方法说明React.createElement()ReactDOM.render()1.3 React 脚手架的使用1.3.1 React 脚手架…...
k8s部署kafka集群
k8s部署kafka集群 kafka(Kafka with KRaft) mkdir -p ~/kafka-ymlkubectl create ns kafkacat > ~/kafka-yml/kafka.yml << EOF apiVersion: v1 kind: Service metadata:name: kafka-headlessnamespace: kafkalabels:app: kafka spec:type: C…...
(C++回溯01) 组合
77、组合 回溯题目三步走 1. 确定参数 2. 确定终止条件 3. for 循环横向遍历,递归纵向遍历 class Solution { public:vector<vector<int>> result;vector<int> path;void backtracking(int n, int k, int startIndex) {if(path.size() k) {…...
k8s学习笔记——安装istio的仪表盘之prometheus安装
接上一篇,继续安装istio的dashboard。 先到istio-1.22.0/samples/addons目录下,把yaml文件中的镜像仓库地址修改了,修改地址参考我之前写的CSDN里的镜像对照表。不然直接执行kubectl apply -f samples/addons这个命令后,依据会出…...

四、GD32 MCU 常见外设介绍 (7) 7.I2C 模块介绍
7.1.I2C 基础知识 I2C(Inter-Integrated Circuit)总线是一种由Philips公司开发的两线式串行总线,用于内部IC控制的具有多端控制能力的双线双向串行数据总线系统,能够用于替代标准的并行总线,连接各种集成 电路和功能模块。I2C器件能够减少电…...

Apollo 配置中心的部署与使用经验
前言 Apollo(阿波罗)是携程开源的分布式配置管理中心。 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验 特点 成熟,稳定支持管理多环境/多集群/多命名空间的配置配置修改发布实时(1s)通知到应用程序支…...
Perl中的设计模式革新:命令模式的实现与应用
Perl中的设计模式革新:命令模式的实现与应用 在面向对象编程中,设计模式是解决特定问题的成熟模板。命令模式作为行为设计模式之一,它将请求封装为对象,从而允许用户根据不同的请求对客户进行参数化。本文将深入探讨如何在Perl中…...
Java8-求两个集合取交集
在Java8中,求两个集合的交集可以使用不同的三种方式:传统的循环遍历、使用Stream API的filter操作和使用Stream API的Collection操作。 方法一:传统的循环遍历 首先,我们创建两个集合list1和list2,并给它们添加一些元…...

爬虫学习4:爬取王者荣耀技能信息
爬虫:爬取王者荣耀技能信息(代码和代码流程) 代码 # 王者荣耀英雄信息获取 import time from selenium import webdriver from selenium.webdriver.common.by import By if __name__ __main__:fp open("./honorKing.txt", "…...
在Ubuntu 14.04上安装和使用Memcache的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 随着您的网站的增长和流量的增加,最快显示压力的组件之一是后端数据库。如果您的数据库没有分布式和配置来处理高负载…...
PCDN技术如何降低运营成本?
PCDN技术通过以下几种方式降低运营商的运营成本: 1.利用用户设备作为缓存节点: PCDN技术将用户设备纳入内容分发网络,利用这些设备的闲置带宽和存储资源来缓存和分发内容。这种方式不需要运营商投入大量的高成本服务器和带宽资源,从而降低了硬件和带宽…...

服务器数据恢复—V7000存储硬盘故障脱机的数据恢复案例
服务器存储数据恢复环境: 某品牌P740小型机AIXSybaseV7000磁盘阵列柜,磁盘阵列柜中有12块SAS机械硬盘(其中包括一块热备盘)。 服务器存储故障: 磁盘阵列柜中有一块磁盘出现故障,运维人员用新硬盘替换掉故障…...

BSV区块链在人工智能时代的数字化转型中的角色
发表时间:2024年6月13日 企业数字化转型已有约30年的历史,而人工智能(以下简称AI)将这种转型提升到了一个全新的高度。这并不难理解,因为AI终于使企业能够发挥其潜力,实现更宏大的目标。然而࿰…...
android audio 相机按键音:(二)加载与修改
相机按键音资源,加载文件路径: frameworks/av/services/camera/libcameraservice/CameraService.cpp 按键音,加载函数: void CameraService::loadSoundLocked(sound_kind kind) { ATRACE_CALL(); LOG1("Cam…...
Linux grep技巧 提取log中的json数据
目录 一. 前提1.1 数据准备1.2 需求1.3 分析 二. 数据提取2.1 提取所有的json数据2.2 提取子项目的全部json数据2.3 提取指定项目的json数据 一. 前提 1.1 数据准备 545-1 2024/07/20 18:20:21 [ERROR] MPX001 eventControlleraupay transactionIdA545 {"event":&q…...
HDShredder 7 企业版案例分享: 依照国际权威标准,安全清除企业数据
HDShredder 7 企业版用户案例 天津鸿萌科贸发展有限公司是德国 Miray 公司 HDShredder 数据清除软件的授权代理商。近日,上海某网络科技有限公司采购 HDShredder 7 企业版x4,为公司数据存储资产的安全清除工作流程配备高效的执行工具。HDShredder 7 企业…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...