首页 > 编程知识 正文

stm32矩阵键盘介绍,stm32f103r6能实现啥功能

时间:2023-05-03 09:48:27 阅读:233151 作者:3065

基于STM32的按键扫描测试程序(学习记录):

目录:

源码;4x4按键原理;按键扫描逻辑;

Tips:

粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文字符;程序使用嵌套循环实现4x4按键扫描,如果IO口设置过乱时,将循环拆分即可;

key4x4.h源文件

#ifndef __KEY4x4_H#define __KEY4x4_H #include "sys.h" #define KEY_X(X)PEin(X)// 尽量避免使用PD以上GPIO,便于移植;#define KEY_Y(Y)PEout(Y)#define ALL_DOWN_KEY_Y{KEY_Y(11) = 0; KEY_Y(12) = 0; KEY_Y(13) = 0; KEY_Y(14) = 0;} void KEY4x4_Init(void);// IO口初始化u8 KEY4x4_Scan(void); // 矩阵按键反馈函数// 可配置任意矩阵按键使用!!u8 KEY16_Scan(void);/**************其他按键扫描方案:按键使用8个输入IO口, 且所有IO口一端接VCC/VSS;程序框架:扫描检测哪两个IO口输入高/低电平;VCC/VSS根据对应坐标,return对应编号;**************/#endif

key4x4.c源文件

#include "stm32f10x.h"#include "key4x4.h"#include "sys.h" #include "delay.h"#include "usart.h"/*************************X:PEin7-10Y:PEout11-14*************************/// 矩阵按键初始化函数void KEY4x4_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//KEY0-KEY1GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOEGPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14; //LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOE, &GPIO_InitStructure); //根据设定参数初始化GPIOE}// 使所有输出拉低;初始化;// 可以使用define宏定义,执行速度更快,不用跳转函数!!static void KEY_ALL_Pull_Down(void){KEY_Y(11) = 0;KEY_Y(12) = 0;KEY_Y(13) = 0;KEY_Y(14) = 0;}// 4x4按键扫描函数// 使用一个嵌套循环,完成扫描X和Y;// 原理: 通过Y 依次输出高电平,//扫描X 那个IO口输入高电平;// X轴:输入检查、扫描;// Y轴:设置输出状态;// 该函数适合任意排列矩阵按键,只需修改循环中对应编号!!// 注意: 1. 改变IO口时,该函数还需要改变循环中IO口编号;(可以定义好IO口编号,便于修改)//2. 该函数同样有优先级问题! 即同时按下时,只反馈先被扫描到的(0-15标号最小的)//3. 函数同一坐标轴的IO口编号必须相邻或能有 规律递增可寻;(否则无法用循环判断)//4. 暂时未添加功能(模式):按键复用 和 长按;// 2020-11-13返回值调整为:1-16// 11/14 不支持连按;解决重复反馈的问题;u8 KEY4x4_Scan(void){int i,j;u8 IO_Sign = 0;// 很简便的一个IO反馈方式标签!!! 且嵌套循环特有!! // 能返回0-15,适合任意排列矩阵按键static key_up = 1;//KEY_ALL_Pull_Down();// 初始化所有按键输出拉低;for (i = 11; i <= 14; i++)// Y输出IO口编号;for (j = 7; j <= 10; j++,IO_Sign++)// X输出IO口编号; // 递增IO_Sign,反馈对应值(0-15);{KEY_Y(i) = 1;// 使PEout(i)输出高电平;if (KEY_Y(i))// 扫描Y输出高电平, 可以取消此判断; 因为必须输出高电平时,才能正常判断!!{if (KEY_X(j) && key_up)// 当输入检查到高电平时;{key_up = 0;printf("按键扫描反馈: %d rn",IO_Sign);return IO_Sign;}else if (!KEY_X(7)&&!KEY_X(8)&&!KEY_X(9)&&!KEY_X(10))// 当所有输入检测到低电平时,再次使能按键; 防止重复反馈{key_up = 1;KEY_ALL_Pull_Down();// 初始化所有按键输出拉低(低电平);必须在此位置;}}elseprintf("PEout:IO口%d输出异常! rn ", i);}delay_ms(10);// 按键防抖;}/******************************************标准扫描函数*********************************************/// 支持连按u8 KEY16_Scan(void){int i,j;u8 IO_Sign = 0;// 很简便的一个IO反馈方式标签!!! 且嵌套循环特有!! // 能返回0-15,适合任意排列矩阵按键ALL_DOWN_KEY_Y// 初始化所有按键输出拉低;for (i = 11; i <= 14; i++)// Y输出IO口编号;for (j = 7; j <= 10; j++,IO_Sign++)// X输出IO口编号; // 递增IO_Sign,反馈对应值(0-15);{KEY_Y(i) = 1;// 使PEout(i)输出高电平;if (KEY_X(j))// 当输入检查到高电平时;return IO_Sign;}delay_ms(20);// 按键防抖;// 连按延时;}

*4x4按键原理图

按键工作原理:
当按键被按下时,相连的电路导通;即S1按下时,位于0行0列的线短路,使标号4和5对应的IO口相连(导通);
最后通过扫描检测输入输出状态即可判断出对应按键被按下;

程序设计思路:
程序通过依次使标号1、2、3、4(列0-3)输出高电平,判断5/6/7/8(行0-3)状态;完成按键扫描;

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。