首页 > 其他分享 >国产MCU兆易GD32实现矩阵按键扫描

国产MCU兆易GD32实现矩阵按键扫描

时间:2023-06-24 15:45:57浏览次数:36  
标签:兆易 PIN 按键 GPIOB GD32 gpio GPIO MCU bit

一、矩阵键盘
    为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。使用8个io口来进行16个按键的控制读取,可以减小io口的使用,用4条I/O线作为行线,4条I/O线作为列线组成的键盘。矩阵键盘检测方法主要有两种,一种是逐行扫描、一种是行列扫描。

1、逐行扫描
    通过在矩阵按键的每一条行线上轮流输出低(高)电平,检测矩阵按键的列线,当检测到的列线不全为高(低)电平的时候,说明有按键按下。然后,根据当前输出低电平的行号和检测到低电平的列号组合,判断是哪一个按键被按下。

2、行列扫描
    首先,在全部行线上输出低电平,检测矩阵按键的列线,当检测到的列线不全为高电平的时候,说明有按键按下,并判断是哪一列有按键按下。然后,反过来,在全部列线上输出低电平,检测矩阵按键的行线,当检测到的行线不全为高电平的时候,说明有按键按下,并判断是哪一行有按键按下。最后,根据检测到的行号和检测的列号组合,以判断是哪一个按键被按下。

二、程序设计

实现效果:逐行扫描矩阵键盘并打印出键值。
思路:保持一列输出高,重复扫描行。

key.c

#include "key.h"

uint8_t i=0,j=0;//行、列号

/************************************************
*@Function   :key_Init
*@brief      :按键GPIO初始化函数
*@param      :void
*@retval     : void
*************************************************/
void Key_Init(void)
{
    //使能GPIO时钟           
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
        
    //四列 PB1 PB2 PB10 PB11 作为输出 
    gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_1);     
    gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_2); 
    gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_10); 
    gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_11);  
       
    //四行 PA3 PA4 PA5 PA6 下拉输入  默认为低电平
    gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_3);     
    gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_4); 
    gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_5); 
    gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_6); 
    
    //列初始化为低电平
    gpio_bit_reset(GPIOB, GPIO_PIN_1);
    gpio_bit_reset(GPIOB, GPIO_PIN_2);
    gpio_bit_reset(GPIOB, GPIO_PIN_10);
    gpio_bit_reset(GPIOB, GPIO_PIN_11);
}

/************************************************
*@Function   :Rank1_Scan(void)
*@brief      :第一行扫描函数
*@param      :void
*@retval     : 0(可以返回行号i)
*************************************************/
uint8_t Rank1_Scan(void)
{
    //第一列输出高,其它三列输出低
    gpio_bit_set(GPIOB, GPIO_PIN_1);
    gpio_bit_reset(GPIOB, GPIO_PIN_2);
    gpio_bit_reset(GPIOB, GPIO_PIN_10);
    gpio_bit_reset(GPIOB, GPIO_PIN_11);
	
   //检测第一行按键状态,为高则按下
   if(gpio_input_bit_get(GPIOA, GPIO_PIN_3)==1)
   {
	  delay_1ms(10);//消抖
	  while(gpio_input_bit_get(GPIOA, GPIO_PIN_3)==1)
	  delay_1ms(10);
	  printf("KeyNumber:%d\r\n",KEY1);
   }
   //检测第二行按键状态,为高则按下
   if(gpio_input_bit_get(GPIOA, GPIO_PIN_4)==1)
   {	
	  delay_1ms(10);;
	  while(gpio_input_bit_get(GPIOA, GPIO_PIN_4)==1)
	  delay_1ms(10);;
	  printf("KeyNumber:%d\r\n",KEY5);
   }
  //检测第三行按键状态 
  if(gpio_input_bit_get(GPIOA, GPIO_PIN_5)==1)
  {
	  delay_1ms(10);;
	  while(gpio_input_bit_get(GPIOA, GPIO_PIN_5)==1)
	  delay_1ms(10);
	  printf("KeyNumber:%d\r\n",KEY9);
  }
  //检测第四行按键状态 
  if(gpio_input_bit_get(GPIOA, GPIO_PIN_6)==1)
  {
	  delay_1ms(10);
	  while(gpio_input_bit_get(GPIOA, GPIO_PIN_6)==1)
	  delay_1ms(10);
	  printf("KeyNumber:%d\r\n",KEY13);
  } 
  gpio_bit_reset(GPIOB, GPIO_PIN_1);//将第一列拉低回原状态
  return 0;
}

主函数

#include "gd32f10x.h"
#include "gd32f103c_eval.h"
#include "systick.h"
#include "key.h"
#include "usart.h"


int main(void)
{
  systick_config();//系统时钟
  //USART相关配置
  Usart_Init();
  Key_Init();
  printf("Init OK!\r\n");
  
  while(1)
  {
      Rank1_Scan();
  }
}

以上是行扫描实现思路,剩下的按键只需将剩下的三列依次保持一列输出高,重复扫描行即可。

三、实验现象

实际测试均能准确打印出键值。

四、程序优化

     行扫描程序有大量重复代码,可以使用循环语句嵌套条件选择语句将四列依次置高,这样就只需要一段通用的行扫描语句,降低重复率。

标签:兆易,PIN,按键,GPIOB,GD32,gpio,GPIO,MCU,bit
From: https://www.cnblogs.com/xiaohuzaixue/p/17494667.html

相关文章

  • CH583,CH582,CH581 国产蓝牙芯片RISC-V内核BLE 5.3无线MCU
    概述CH583是集成BLE无线通讯的32位RISC微控制器。片上集成2Mbps低功耗蓝牙BLE通讯模块、2个全速USB主机和设备控制器及收发器、2个SPI、4个串口、ADC、触摸按键检测模块、RTC等丰富的外设资源。CH583相比CH582多了SP11主机,支持最低1.7V电源电压。CH581基于CH582简化,去掉了-......
  • 华大电子MCU CIU32M010、CIU32M030嵌入式闪存及中断和事件
    1.嵌入式闪存1.1模块介绍CIU32M010、CIU32M030集成了嵌入式FLASH控制模块,该模块控制FLASH的擦除、编程以及读取数据。上电时会从FLASH中读取相关数据进行校验以及初始化配置,保证芯片程序在正确且安全的情况下运行。1.2功能特点•支持高达64K主闪存空间的FLASH•......
  • 国产MCU-CW32F030开发学习--按键检测
    国产MCU-CW32F030开发学习--按键检测bsp_key按键驱动程序用于扫描独立按键,具有软件滤波机制,采用FIFO机制保存键值。可以检测如下事件:按键按下。按键弹起。长按键。长按时自动连发。我们将按键驱动分为两个部分来介绍,一部分是FIFO的实现,一部分是按键检测的实现......
  • 可节省40%MCU开发成本的音乐睡眠灯语音扩展芯片方案N9300-S16
    随着社会节奏的加快,人们每天的生活节奏也在不断的加快,工作压力也在不断的加大,越来越多的人都面临着失眠的痛苦,当拖着疲惫不堪的身体躺到床上时,却发现由于担忧每天的工作或月底需要交房租等问题,久久无法入眠;这时打开睡眠音乐灯,在舒缓的音乐中、在渐变的灯光中慢慢忘却工作中的压力,慢......
  • MCU晶振负载电容的计算方法
    MCU晶振谐振电容的计算方法在实际应用中使用外置晶振(HSE)作为单片机时钟源时,经常会有工程师遇到定时精度误差较大,或者上电后系统不工作,需要手动复位一次才能正常工作的情况,此类现象多数都是外置晶振(HSE)的谐振电容选择不当导致。单片机的晶振电路经常使用的是皮尔斯振荡电路,具体电......
  • LKT6830C安全MCU(一):资源介绍
    LKT6830C是以32位高安全CPU为基础开发的高性能、高安全性的MCU主控。LKT6830C除了具有SPI、IIC、UART、GPIO等常用外设接口外同时芯片内置定时器、看门狗、PWM、DMA等功能。在充分保证芯片内部程序存储和运行安全的前提下,满足客户各种基本应用开发的要求。LKT6830C支持多种国际......
  • RT-Thread学习(一)-基于GD32移植
    1前言啊啊啊,纠结了很久,一直在纠结学哪种rtos,在freertos和rt之间反复横跳,一直在想以后工作了会用什么,但是因为现在自己的项目用了GD32,既然国产了,那就继续国产吧,认真好好学rt2参考资料PS:因为我很懒,不想自己配置,所以就想用keil直接解决https://aijishu.com/a/106000000036744......
  • 国产MCU-CW32F030开发学习
    国产MCU-CW32F030开发学习1.相关资料下载1.1武汉芯源半导体武汉芯源半导体官网https://www.whxy.com/武汉芯源21ic电子论坛https://bbs.21ic.com/iclist-1116-1.html1.2CW32F030系列资料•内核:ARM®Cortex®-M0+–最高主频64MHz•工作温度:-40℃至105......
  • 痞子衡嵌入式:MCUBootUtility v5.0发布,初步支持i.MXRT1180
    --痞子衡维护的NXP-MCUBootUtility工具距离上一个大版本(v4.0.0)发布过去4个多月了,期间痞子衡也做过两个小版本更新,但不足以单独介绍。这一次痞子衡为大家带来了全新大版本v5.0.0,这次更新主要是想和大家特别聊聊恩智浦新一代i.MXRT旗舰RT1180。一、v4.1-v5.0更新记录-......
  • LKT6850安全MCU(二):系统架构
    LKT6850主系统由以下部分构成:两个驱动单元ARMCortexM0内核和系统总线(S-bus)DMA总线三个被动单元内部内部闪存存储器AHB到APB的桥(AHB2APBx),它连接所有的APB设备这些都是通过一个多级的AHB总线构架相互连接的。系统结构系统总线该总线连接ARMCortexM0内核的系统总线到总线矩阵......