stm32——3、键盘

2023-05-16

这里用到的是正点原子开发板
在这里插入图片描述
可以看到键盘通过PE2、PE3、PE4、PA0来连接。如果你的开发板不是这个需要改到对应的接口啊。
另外可以看到WK_UP是高电平有效的,并且外部没有上下拉电阻,需要stm32内部设置上下拉。
首先写key.h文件,这里有两种方法库函数或者C51一样直接对io口进行操作。对比两中方法可以更好理解。

1、直接操作型

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"


#define KEY0 PEin(4)   	//PE4
#define KEY1 PEin(3)	//PE3 
#define KEY2 PEin(2)	//PE2
#define KEY3 PAin(0)	//PA0  WK_UP

#define KEY_UP 		4
#define KEY_LEFT	3
#define KEY_DOWN	2
#define KEY_RIGHT	1

void KEY_Init(void);//初始化
u8 KEY_Scan(u8);  	//检查按键是否按下					    
#endif

2、运用库函数型

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"


#define KEY0  GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//定义PINE4对应KEY0
#define KEY1  GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//同理
#define KEY2  GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//
#define KEY3  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//


#define KEY_UP 		4//KEY_UP 
#define KEY_LEFT	3//KEY2		
#define KEY_DOWN	2//KEY1
#define KEY_RIGHT	1//KEY0

void KEY_Init(void);//
u8 KEY_Scan(u8);  	//				    
#endif

其中#define KEY_UP 4//KEY_UP是运用宏定义,当输入KEY_UP,会被当做4。

写key.c文件,同样包括2钟
1、直接操作型

#include "key.h"
#include "delay.h"

								    
//初始化
void KEY_Init(void)
{
	RCC->APB2ENR|=1<<2;     //使能PORTA时钟
	RCC->APB2ENR|=1<<6;     //使能PORTE时钟
	GPIOA->CRL&=0XFFFFFFF0;	//PA0设置成输入,默认下拉

	GPIOA->CRL|=0X00000008; 
	  
	GPIOE->CRL&=0XFFF000FF;	//PE2~4设置成输入
  
	GPIOE->CRL|=0X00088800; 				   
	GPIOE->ODR|=7<<2;	   	//PE2~4 ÉÏÀ­
} 


//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0, 没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3, KEY2按下
//4, KEY3按下WK_ UP
//注意此函数有响应优先级, KEYO>KEY1>KEY2>KEY3!!

u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键松开标志
	if(mode)key_up=1; //这行代表了支持连按,如果mode=0就会跳过		  
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==1))
	{
		delay_ms(10);//去抖动
		key_up=0;
		if(KEY0==0)return 1;
		else if(KEY1==0)return 2;
		else if(KEY2==0)return 3;
		else if(KEY3==1)return 4;
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1; 	    
 	return 0;// 没有按键按下
}

1、调用库函数型

#include "stm32f10x.h"
#include "key.h"
#include "sys.h" 
#include "delay.h"

void KEY_Init(void)   //³õʼ»¯
{
	GPIO_InitTypeDef  GPIO_InitStructure;	//³õʼ»¯key0¡ª¡ªGPIOA.13  KEY--gpio.15   ÉÏÀ­Êä³ö
	//ʹÄÜÁ½¸öʱÖÓ£¬PORTAÓëporteʱÖÓ
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//??PORTA,PORTE??

	
	//ÉèÖÃÒý½Åpe2\pe3\pe4
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//IPU´ú±íÉÏÀ­
	GPIO_Init(GPIOE,&GPIO_InitStructure);//³õʼ»¯GPIOe2.3.4
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//IPD´ú±íÏÂÀ­
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
}


//°´¼ü´¦Àíº¯Êý
//·µ»Ø°´¼üÖµ
//mode:0£¬²»Ö§³ÖÁ¬Ðø°´£»  modeΪ1¡ª¡ªÖ§³ÖÁ¬Ðø°´ÏÂ
//0£¬É¶Ò²Ã»°´
//1£¬key0°´Ï°
//2ͬÀí
//3ͬÀí
//4ͬÀí
//ÏàÓ¦ÓÅÏȼ¶key0>1>2>3

u8 KEY_Scan(u8 mode)
{
	//statiΪÐÞÊξ²Ì¬±äÁ¿£¬Ï´ε÷Óô˰´¼üº¯Êýʱkey_upµÄÖµ²»±ä£¬¿ÉÒÔ±ÜÃâÿ´Îµ÷ÓÃÖظ´¸³Öµ
	static u8 key_up=1;//°´¼üËÉ¿ª±êÖ¾
	if(mode)key_up=1;	//´ú±íģʽΪ֧³ÖÁ¬°´Ä£Ê½
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==1))
	{
		delay_ms(10);//È¥¶¶¶¯
		key_up=0;
		if(KEY0==0) return KEY_RIGHT;
		else if (KEY1==0)return KEY_DOWN;
		else if (KEY2==0)return KEY_LEFT;
		else if (KEY3==1) return KEY_UP;
		
	}
	else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1;
	return 0; //ûÓа´¼ü°´ÏÂ
}

在这里插入图片描述
在这里插入图片描述
因为代码到这里会乱码,打汉字太麻烦,所以就是图片了。
其中
static u8 key_up=1;static是修饰静态变量,可以避免每次调用函数重新赋值。

if(mode)key_up=1;

这里对应主函数的调用KEY_Scan(1);你可以输入0/1

最后是主函数main.c

#include "sys.h"	
#include "delay.h"	
#include "led.h" 
#include "beep.h" 
#include "key.h"

 int main(void)
 {
	 u8 t;
	delay_init();	    	 //ÑÓʱº¯Êý³õʼ»¯	  
	LED_Init();		  	 	//³õʼ»¯ÓëLEDÁ¬½ÓµÄÓ²¼þ½Ó¿Ú
	BEEP_Init();         	//³õʼ»¯·äÃùÆ÷¶Ë¿Ú
	LED0=0;					//µãÁÁºìµÆ±íʾÔËÐÐ
	 while(1)
	{
		t=KEY_Scan(1);  //°´¼üɨÃ躯Êý½øÐÐɨÃ裬ɨÃèµÄÖµ¸³¸øt
		if(t)
		{
			switch(t)
			{
				case KEY_UP:	BEEP=£¡BEEP;
				break;
				case KEY_LEFT:	LED0=!LED0;
				break;
				case KEY_DOWN: LED1=!LED1;
				break;
				case KEY_RIGHT: LED0=!LED0; LED1=!LED1;
				break;
			}
		}else delay_ms(300);
	}
 }

在这里插入图片描述

最后需要注意的是,库函数和直接写对应配套的h文件不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32——3、键盘 的相关文章

  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • c项目makefile多重定义错误

    这个问题是一个对应于创建的repexthis问题 在我的嵌入式 C 项目中 我有两个独立的板 我想为每个板创建两个 c 文件 master c 和 Slave c 其中包含自己的特定main 功能 我使用 stm32cumbemx 生成带有
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • STM32F4 定时器 - 计算周期和预分频,以生成 1 ms 延迟

    我在用STM32F407VGT6 with CubeMX 因此 我从通用定时器开始 但我被预分频值和周期值所困扰 基本上我想每隔一段时间生成一个定时器中断n 其中 n 1 2 3 ms 并执行一些任务 计算周期和预分频值的公式有很多变化 公

随机推荐

  • C语言基础-猜拳问题

    题目描述 石头剪刀布是常见的猜拳游戏 石头胜剪刀 xff0c 剪刀胜布 xff0c 布胜石头 如果两个人出拳一样 xff0c 则不分胜负 一天 xff0c 小A和小B正好在玩石头剪刀布 已知他们的出拳都是有周期性规律的 xff0c 比如 石
  • 运算符左移与右移(点进来看看很有用,不只是说一下左移和右移,还有他们的有趣的应用)

    1 左移和右移 左移和右移这一对运算符 不知道有多少人可以很清楚它们 xff0c 并且可以很好的应用 xff0c 反正我是不可以 xff0c 于是就打算总结一下 左移 xff1a 左移就是把一个数的所有位都向左移动若干位 符号表示 xff1
  • Python中的if语句

    Python中的if语句 1 条件测试 每个if语句的核心都是一个值为True或False的表达式 xff0c 这种表达式被称为条件测试 当条件测试的结果为True时 xff0c if语句会执行后面的代码 xff1b 如果为False则不会
  • Ubuntu系统下的gcc升降版本 保姆级教程

    安装cuda出错Failed to verify gcc version See log at var log cuda installer log for details 在安装cuda xff0c 使用如下命令 xff1a sudo s
  • ubuntu16.04 --- ROS智能车定位导航仿真

    ubuntu16 04 ROS智能车定位导航 一 准备阶段1 下载智能车源码包2 安装相应插件3 编译 二 仿真1 运行小车模型2 运行赛道3 自主定位导航4 搭建自己的地图5 导航 一 准备阶段 1 下载智能车源码包 进入ROS工作区 c
  • cloudreve-自建云盘

    目前已经实现的特性 xff1a 1 快速对接多家云存储 xff0c 支持七牛 又拍云 阿里云OSS AWS S3 Onedrive 自建远程服务器 xff0c 当然 xff0c 还有本地存储 2 可限制单文件最大大小 MIMEType 文件
  • intel cpu core/“酷睿”系列发展史,供组装机的朋友们参考

    一 intel cpu系列分类 酷睿 xff08 Core xff09 系列 xff0c 主要应用于管理 3D 高级视频和照片编辑 xff0c 玩复杂游戏 xff0c 享受高分辨率 4K 显示 奔腾 xff08 PenTIum xff09
  • PostgreSQL11 | 插入、更新与删除数据

    上一篇总结了原著的第六章有关pgsql的函数的用法 xff0c 本篇将总结pgsql的增删改功能以及相关的sql语句 插入 更新与删除数据 存储在系统中的数据是数据库管理系统的核心 数据库被设计用来管理数据的存储 访问 xff0c 维护数据
  • AlibabaProtect无法删除?无法禁用?

    转载自 xff1a https blog csdn net becooner article details 99833665 AlibabaProtect xff0c 与优酷捆绑并强行安装的软件 xff08 或许阿里系软件都有 xff09
  • 树莓派 docker Nextcloud 登录后提示”服务器内部错误”

    image jsurf rpi mariadb docker pull jsurf rpi mariadb 换mariadb后 正常使用
  • 使用dpkg时,提示:dpkg:处理软件包XXX时出错

    文章目录 前言一 发生了什么问题呢 xff1f 二 解决办法1 解决过程1 分析apt get2 安装需要的安装包3 安装fcitx4 对fcitx 进行配置5 重启 前言 kali安装中文输入法 linux安装中文输入法 这次的内容主要是
  • 算术左移、逻辑左移、算术右移、逻辑右移有什么不同?

    算术左移 61 逻辑左移 xff1a 都是整体左移 xff0c 低位补0 算术右移 61 逻辑右移 xff0c 这两者主要的区别就在于 算术右移 gt 整体右移 xff0c 高位补符号位 逻辑右移 gt 整体右移 xff0c 高位补0
  • 使用docker安装nextcloud

    使用docker安装nextcloud 记录在CentOS 8中使用docker安装nextcloud的教程 安装步骤 使用docker安装nextcloud在CentOS 8中安装docker安装docker网络在docker中安装nex
  • HC-06蓝牙模块使用AT指令设置和使用

    HC 06蓝牙模块使用AT指令设置和使用 学习内容 xff1a HC 06 步骤一接线 xff1a HC 06的Rx和Tx 接到 USB转TTL的 Tx和 Rx xff0c VCC接5V xff0c GND接GND 步骤二 xff1a 上电
  • keil5,C文件下的h文件有感叹号

    1 有感叹号可能的原因是因为文件路径中包含汉字 xff0c 重新设置不包含汉字的路径 xff0c 在进行编译就没有感叹号了
  • keil5,定义了变量但还是报错。test.c(33): error: #268: declaration may not appear after executable statement in

    declaration may not appear after executable statement in block 1 点击魔术棒 xff0c 进入设置 2 点击c c 43 43 检查你的C99 Mode有没有打对勾 如果没有就
  • stm32——2.蜂鸣器

    beep h文件 span class token macro property span class token directive hash span span class token directive keyword ifndef
  • 设计模式详解:单例模式

    本篇来看一下创建型模式中最常用的第三种模式 xff1a 单例模式 仍然是先看两张图 xff0c 复习模式类型 xff0c 加深记忆 定义 xff1a 单例模式 xff1a 确保一个类 只有一个实例 xff0c 并提供一个 全局访问点 来访问
  • React 中的副作用函数 useEffect 使用说明

    React 中的函数式组件为了能够Hook相应的阶段 xff0c 采用 useEffect函数 xff0c 以实现类 xff08 class xff09 组件的componentDidMount xff0c componentDidUpda
  • stm32——3、键盘

    这里用到的是正点原子开发板 可以看到键盘通过PE2 PE3 PE4 PA0来连接 如果你的开发板不是这个需要改到对应的接口啊 另外可以看到WK UP是高电平有效的 xff0c 并且外部没有上下拉电阻 xff0c 需要stm32内部设置上下拉