STM32的矩阵按键程序思路

一:开个头

之前学52的时候学过矩阵按键的程序,但是当我第一次拿到32板子写程序的时候还是有一点懵,不过还来理理思路,感觉想一想还是可以写出来的,我这次是没有自己去焊矩阵按键,而是买了一个薄膜按键,省去了焊接的麻烦//手动狗头//

二:操作实物图

就是这个啦!!!应该可以看出来黄色的线连着的是矩阵按键的行,橙色线连着的事矩阵按键的列,下面解释的时候我会用行和列来说

三:程序思路

1、首先一个大思路,我们用矩阵按键的时候,首先是先确定哪一行,接着是哪一列
(1)我让行作输出,并输出低电平,列作输入,并读取电平,当有按键按下的时候就会有电平变化–>这个是用来判断是哪一行

void KEY_L_Init(void)
{
   
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);
//	 RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);
   //列
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//输入上拉  
   GPIO_InitStructure.GPIO_Pin=KEY_L0_GPIO_PIN|KEY_L1_GPIO_PIN|KEY_L2_GPIO_PIN|KEY_L3_GPIO_PIN;
   GPIO_Init(GPIOA,&GPIO_InitStructure);
   //行
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      
   GPIO_InitStructure.GPIO_Pin=KEY_R0_GPIO_PIN|KEY_R1_GPIO_PIN|KEY_R2_GPIO_PIN|KEY_R3_GPIO_PIN;
   GPIO_Init(GPIOA,&GPIO_InitStructure);       
   GPIO_ResetBits(GPIOA,KEY_R0_GPIO_PIN|KEY_R1_GPIO_PIN|KEY_R2_GPIO_PIN|KEY_R3_GPIO_PIN);
}

(2)下面确定哪一列,因为我们刚刚确定了哪一行,只要确定哪一列,就可以找出按下的位置,这次思路是让列输出并输出高电平,让行作输入并读取电平变化

void KEY_R_Init(void)
{
   
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);
//	 RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);	 //列
	
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin=KEY_L0_GPIO_PIN|KEY_L1_GPIO_PIN|KEY_L2_GPIO_PIN|KEY_L3_GPIO_PIN;
   GPIO_Init(GPIOA,&GPIO_InitStructure);
	 GPIO_SetBits(GPIOA,KEY_L0_GPIO_PIN|KEY_L1_GPIO_PIN|KEY_L2_GPIO_PIN|KEY_L3_GPIO_PIN);
   //行
   GPI
  • 13
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
抱歉,我作为AI语言模型并不具备编写代码的能力,但我可以提供一个基本框架和思路供参考。 矩阵按键是一种常见的按键扫描方式,可以通过少量的IO口来读取多个按键的状态。以下是一个可能的实现方法: 1. 确定矩阵按键的行列数,假设为4行4列,需要使用4个行IO口和4个列IO口。 2. 初始化行IO口为输出模式,列IO口为输入模式,使得行IO口输出高电平,列IO口输入低电平。 3. 循环扫描每一行,将当前行IO口输出低电平,读取每一列IO口的状态,如果有按键按下则状态为低电平,否则为高电平。 4. 将读取到的按键状态存储到一个数组中,例如按键矩阵为keys[4][4],则可以使用一个uint16_t类型的变量存储所有按键状态。 5. 等待一段时间后,再次循环扫描按键状态,判断哪些按键发生了变化,如果按键状态从高电平变为低电平,则表示按键被按下,如果从低电平变为高电平,则表示按键被释放。 6. 根据按键的状态做出相应的处理,例如发送按键码到PC或者执行相应的功能。 以下是一个可能的代码框架: ```c #include "stm32f10x.h" #define ROW_NUM 4 #define COL_NUM 4 GPIO_TypeDef* ROW_PORT[ROW_NUM] = {GPIOA, GPIOA, GPIOA, GPIOA}; uint16_t ROW_PIN[ROW_NUM] = {GPIO_Pin_0, GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3}; GPIO_TypeDef* COL_PORT[COL_NUM] = {GPIOB, GPIOB, GPIOB, GPIOB}; uint16_t COL_PIN[COL_NUM] = {GPIO_Pin_0, GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3}; uint16_t keys = 0xFFFF; void GPIO_Init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // 初始化行IO口为输出模式,列IO口为输入模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; for (int i = 0; i < ROW_NUM; i++) { GPIO_InitStructure.GPIO_Pin = ROW_PIN[i]; GPIO_Init(ROW_PORT[i], &GPIO_InitStructure); } GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; for (int i = 0; i < COL_NUM; i++) { GPIO_InitStructure.GPIO_Pin = COL_PIN[i]; GPIO_Init(COL_PORT[i], &GPIO_InitStructure); } } void ScanKeys() { // 循环扫描每一行 for (int row = 0; row < ROW_NUM; row++) { // 将当前行IO口输出低电平 GPIO_ResetBits(ROW_PORT[row], ROW_PIN[row]); // 读取每一列IO口的状态 for (int col = 0; col < COL_NUM; col++) { uint16_t bit = (1 << (row * COL_NUM + col)); if (GPIO_ReadInputDataBit(COL_PORT[col], COL_PIN[col]) == Bit_RESET) { // 如果有按键按下则状态为低电平 keys &= ~bit; } else { // 否则为高电平 keys |= bit; } } // 将当前行IO口恢复为高电平 GPIO_SetBits(ROW_PORT[row], ROW_PIN[row]); } } void ProcessKeys() { static uint16_t last_keys = 0xFFFF; // 判断哪些按键发生了变化 uint16_t changed_keys = (keys ^ last_keys); last_keys = keys; // 处理按键变化 for (int row = 0; row < ROW_NUM; row++) { for (int col = 0; col < COL_NUM; col++) { uint16_t bit = (1 << (row * COL_NUM + col)); if (changed_keys & bit) { if (keys & bit) { // 按键被释放 } else { // 按键被按下 } } } } } int main(void) { GPIO_Init(); while (1) { ScanKeys(); ProcessKeys(); // 等待一段时间后再次扫描按键状态 for (int i = 0; i < 10000; i++); } } ``` 注意:以上代码仅提供一个思路和框架,实际应用时需要根据具体需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值