stm32 F103C8T6 4x4矩阵键盘使用
首先感谢 江科大 的stm32入门课程 受益匪浅。推荐有兴趣的朋友去看看。
先看看我用的矩阵键盘是啥样的(很常见的一种)

接线如图(其他型号根据自己需求接上GPIO口)
代码基于stm大善人的代码修改而来,讲的很详细,非常感谢。
直接上代码:
头文件Key4x4.h
#ifndef __KEY4x4_H
#define __KEY4x4_H void KEY_4x4_Init(void);
void KEY_Scan(void);
u16 Key_Read(void); #endif
主体文件Key4x4.c
#include "stm32f10x.h"
#include "Delay.h" u8 anxia = 0;
u8 key = 1;
u16 line[4] = {0x00fe , 0x00fd , 0x00fb ,0x00f7};
u16 off = 0x00ff; // 全部引脚置为1
u16 keys[16] = {
49, 50, 51, 65,
52, 53, 54, 66,
55, 56, 57, 67,
42, 48, 35, 68,
}; void KEY_4x4_Init(void){ GPIO_InitTypeDef GPIO_InitStructre;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // 使能 GPIOA 的时钟 // 第一组
GPIO_InitStructre.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructre.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructre);
GPIO_SetBits(GPIOA , GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
// 第二组数据
GPIO_InitStructre.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructre.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA , &GPIO_InitStructre);
GPIO_SetBits(GPIOA , GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); } void Do_Click(uint16_t gpio_pin_x , u8 num){
anxia = 1;
key = num;
while(!GPIO_ReadInputDataBit(GPIOA , gpio_pin_x));
} void KEY_Click_Listener(u8 num){
if((GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)==0)){
Delay_ms(10);
if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)){
Do_Click(GPIO_Pin_4 , num+0);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)){
Do_Click(GPIO_Pin_5 , num+1);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)){
Do_Click(GPIO_Pin_6 , num+2);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)){
Do_Click(GPIO_Pin_7 , num+3);
}else {
anxia = 0;
GPIO_Write(GPIOA , off);
}
}
} void KEY_Scan(){
// 第一行 1111 1110
GPIO_Write(GPIOA , line[0]);
KEY_Click_Listener(1);
// 第二行
GPIO_Write(GPIOA , line[1]);
KEY_Click_Listener(5);
// 第三行
GPIO_Write(GPIOA , line[2]);
KEY_Click_Listener(9);
// 第四行
GPIO_Write(GPIOA , line[3]);
KEY_Click_Listener(13);
} u16 Key_Read(){
return keys[key-1];
}
主要代码说明:
初始化配置 (KEY_4x4_Init):
- 使能GPIOA模块的时钟。
- 配置GPIOA的前四个引脚(GPIO_Pin_0至GPIO_Pin_3)为推挽输出模式,用于键盘行线的扫描。
- 设置GPIOA的后四个引脚(GPIO_Pin_4至GPIO_Pin_7)为上拉输入模式,用于检测键盘列线的状态。
// 第一组
GPIO_InitStructre.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructre.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructre);
GPIO_SetBits(GPIOA , GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
// 第二组数据
GPIO_InitStructre.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructre.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA , &GPIO_InitStructre);
GPIO_SetBits(GPIOA , GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
按键检测 (KEY_Click_Listener):
- 检测列线状态,如果有键按下,则调用
Do_Click函数记录按键信息并等待按键释放。 - 使用延时函数
Delay_ms来消除抖动。
void KEY_Click_Listener(u8 num){
if((GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)==0)
||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)==0)){
Delay_ms(10);
if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)){
Do_Click(GPIO_Pin_4 , num+0);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)){
Do_Click(GPIO_Pin_5 , num+1);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)){
Do_Click(GPIO_Pin_6 , num+2);
}else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)){
Do_Click(GPIO_Pin_7 , num+3);
}else {
anxia = 0;
GPIO_Write(GPIOA , off);
}
}
}
void Do_Click(uint16_t gpio_pin_x , u8 num){
anxia = 1;
key = num;
while(!GPIO_ReadInputDataBit(GPIOA , gpio_pin_x));
}
扫描过程 (KEY_Scan):
- 循环扫描每一行,通过改变行线的状态来检测是否有键按下。
- 调用
KEY_Click_Listener函数来处理每一行的按键检测。
读取按键值 (Key_Read):
- 返回当前按下的键对应的数值。
补充说明:
u16 line[4] = {0x00fe , 0x00fd , 0x00fb ,0x00f7};
u16 off = 0x00ff; // 全部引脚置为1
u16 keys[16] = {
49, 50, 51, 65,
52, 53, 54, 66,
55, 56, 57, 67,
42, 48, 35, 68,
};
line 定义 了4个16进制的数值分别转成二进制
0000 0000 1111 1110 0x00fe
0000 0000 1111 1101 0x00fd
0000 0000 1111 1011 0x00fb
0000 0000 1111 0111 0x00f7
低4位为行 高四位为列
设置0就是给对应行设置低电平
这样我们在scan的代码就能看出来 扫描的做法就是先给传入的行line[x] 设置低电平
所有列都是高电平当扫描到某一列为低电平时就说明这一列被点击了。

循环从第一列到第四列设置低电平直到检测到某一列也变成低电平
假设1被点击 则1这一列也是低电平
就变成第一行 第一列低电平

这样就能确定1被点击。给对应参数赋值1即可
再根据定义的keys (askII 码表对应数值 )
主要代码就是上面这些,其他代码只要复制 江科大OLED的课件源码即可
使用方式 man.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key4x4.h" int main(void)
{ /*模块初始化*/
OLED_Init(); //OLED初始化
KEY_4x4_Init(); /*OLED显示*/
OLED_ShowString(1, 1, "in put:"); //1行1列显示字符A
u8 num = 0;
while (1)
{
KEY_Scan();
num = Key_Read();
OLED_ShowChar(1 ,8 ,num);
}
}
stm32 F103C8T6 4x4矩阵键盘使用的更多相关文章
- Win10 IoT C#开发 6 - 4x4矩阵键盘扫描
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...
- 4x4矩阵键盘扫描
4x4矩阵键盘扫描 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架 ...
- 基于FPGA的4x4矩阵键盘驱动调试
好久不见,因为博主最近两个月有点事情,加上接着考试,考完试也有点事情要处理,最近才稍微闲了一些,这才赶紧记录分享一篇博文.FPGA驱动4x4矩阵键盘.这个其实原理是十分简单,但是由于博主做的时候遇到了 ...
- 4X4矩阵键盘扫描程序
4X4矩阵键盘扫描: 1. 4根行线的GIO均设为Output,根列线的GIO均设为Input: 2. 4根行线的GIO分别置为0111.1011.1101.1110,读逐一读取列线GIO的值,可确定 ...
- 「雕爷学编程」Arduino动手做(26)——4X4矩阵键盘模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...
- 4x4矩阵键盘 扫描程序
一:不排除第四位异常处理 uchar JuzhenkeyScan() { // P3=0xfe; // temp=P3; // while(temp!=0xfe) // { // temp=P3; / ...
- MCU软件最佳实践——矩阵键盘驱动
1.矩阵键盘vs独立按键 在mcu应用开发过程中,独立按键比较常见,但是在需要的按键数比较多时,使用矩阵键盘则可以减少io占用,提高系统资源利用率.例如,某mcu项目要求有16个按钮,如果采用独立按键 ...
- 【STM32学习笔记】STM32f407 使用4*4矩阵键盘
作者:李剀 出处:https://www.cnblogs.com/kevin-nancy/ 欢迎转载,但也请保留上面这段声明.谢谢! 写在前面: 这是本人第一次开始写博客,可能写的不是很好,也请大家谅 ...
- STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)
本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可. 1.键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样 ...
- ARM开发(3)基于STM32的矩阵键盘控制蜂鸣器
一 矩阵键盘控制蜂鸣器原理: 1.1 本实验实现8*7矩阵键盘上按键控制蜂鸣器响. 1.2 实验思路:根据电路图原理,找出矩阵键盘行列所对应的引脚,赋予对应的按键值,然后控制蜂鸣器响. 1.3 ...
随机推荐
- Blender练习——SciFi枪械.md
Blender练习--SciFi枪械 一.基本操作 常用快捷键 E 挤出 B 倒角,中途可通过滚轮或S来调整细分 Alt+点选 循环选择 Ctrl Alt+点选 并排选择 F 补面,比如一个碗口,将碗 ...
- 数据分析---matplotlib模块的使用
1.摘要 在数据可视化.统计绘图和图表生成领域,Python 被广泛使用,其中 Matplotlib 是一个极其重要的基础三方库.本博客旨在介绍 Python 及其三方库 Matplotlib 的详细 ...
- 开源云同步的markdown写作软件——Yosoro
文章目录 前言 简便的项目管理 舒服的写作体验 支持one driver 存在缺点 前言 Yosoro是一款支持在Win.Linux.macOS上使用的写作软件.它的界面设计以及交互上表达出的极简主义 ...
- ZYNQ:Linux添加I2C-RTC驱动
硬件情况 使用的是DS1338这款RTC时钟芯片,I2C总线对应到PS端的I2C1. 配置 内核 添加有关的驱动: 因为DS1338用的驱动与DS13307相似,一找发现是同一个配置. CONFIG_ ...
- Apline部署K3s的Agent
之前我们在Ubuntu上部署了K3s的Server节点(传送门),这次我们加入两台K3s的Agent节点搭建一个K3s的3节点工作环境. 需要准备好网络环境,确保三台VM之间是可以ping通的,设置好 ...
- 牛客小白月赛97 A-D题解
AAAAAAAAAAAAAAAAAAAAA -----------------------------题解------------------------------------------- 统计数 ...
- 【ClickHouse】5:clickhouse集群部署
背景介绍: 有三台CentOS7服务器安装了ClickHouse HostName IP 安装程序 程序端口 centf8118.sharding1.db 192.168.81.18 clickhou ...
- Windows部署语音转文字项目_Whisper
Windows部署语音转文字项目_Whisper Windows部署语音转文字项目_Whisper 一.前置安装准备 Github源仓库,Whisper 下载安装whisper及其依赖项 官方有两种部 ...
- MyBatis xml文件头
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC & ...
- [大数据][机器学习]之Model Card(模型卡片)介绍
每当我们在公有云或者私有云发布训练好的大数据模型,为了方便大家辨识.理解和运用,参照huggingface所制定的标准制作一个Model Card展示页,是种非常好的模型展示和组织形式. 下面就是一个 ...