精华内容
下载资源
问答
  • stm32f4矩阵键盘.rar

    2019-08-12 13:03:49
    本代码为stm32f4驱动矩阵键盘的代码,也可以移植到stm32f1等,下载即可用
  • 将51单片机的矩阵键盘程序移植到stm32F4系列板子上,学习轮询并减少IO口的使用。在硬件上,通过4*4矩阵键盘控制1位数码管的显示。软件上,通过串口调试助手观察4*4键盘的输出
  • STM32F4实现矩阵键盘

    千次阅读 2017-09-11 14:56:09
    程序中所使用的矩阵键盘所接的引脚为PC4-PC5、PF11-PF15和PG0,接线方法为常规矩阵键盘的接法,PC4、PC5、PF11、PF12为行线PF13、PF14、PF15、PG0为列线。 u8 check_Key(void) { GPIO_InitTypeDef GPIO_...

    程序中所使用的矩阵键盘所接的引脚为PC4-PC5、PF11-PF15和PG0,接线方法为常规矩阵键盘的接法,PC4、PC5、PF11、PF12为行线PF13、PF14、PF15、PG0为列线。


    矩阵键盘IO口


    u8 check_Key(void)
    {
            GPIO_InitTypeDef GPIO_InitStructure;
            u8 cord_h=0XFF,cord_l=0XFF;  //h为行线 l为列线
            u8 Val = 0xFF;
    
            /* 行线 推挽输出 */
            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
            GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
            GPIO_Init(GPIOC,&GPIO_InitStructure);
    
            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12;
            GPIO_Init(GPIOF,&GPIO_InitStructure);
    
            /* 列线 上拉输入 */
            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
            GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
            GPIO_Init(GPIOG,&GPIO_InitStructure);
    
            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
            GPIO_Init(GPIOF,&GPIO_InitStructure);
    
            /* 行线输出全部设置为0 */
            GPIO_WriteBit(GPIOC, GPIO_Pin_4|GPIO_Pin_5, Bit_RESET);
            GPIO_WriteBit(GPIOF, GPIO_Pin_11|GPIO_Pin_12, Bit_RESET);
            delay_us(1);
    
            /* 读入列线值 读入的值分别存入低四位 高四位全部为0 */
            cord_l&=(u8)((GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_13)<<0)|
                         (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_14)<<1)|
                         (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_15)<<2)|
                         (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_0)<<3));
            if(cord_l!=0X0F)
            {
                delay_ms(10);       //消抖 延时后再读一次
                cord_l&=(u8)((GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_13)<<0)|
                             (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_14)<<1)|
                             (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_15)<<2)|
                             (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_0)<<3));
                if(cord_l!=0X0F)
                {
                        /* 交换输入信号读取行线值 */
    
                        /* 列线 推挽输出 */
                        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
    
                        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
                        GPIO_Init(GPIOG,&GPIO_InitStructure);
    
                        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
                        GPIO_Init(GPIOF,&GPIO_InitStructure);
    
                            /* 行线 上拉输入 */                   
                        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
                        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
    
                        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
                        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
                        GPIO_Init(GPIOC,&GPIO_InitStructure);
    
                        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12;
                        GPIO_Init(GPIOF,&GPIO_InitStructure);
    
                        /* 列线输出全部设置为0 */
                        GPIO_WriteBit(GPIOG, GPIO_Pin_0, Bit_RESET);
                        GPIO_WriteBit(GPIOF, GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15, Bit_RESET);
                        delay_ms(2);
                        /* 读入行线值 */
                        cord_h&=(u8)((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4)<<3)| 
                                     (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5)<<2)|
                                     (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_11)<<1)|
                                     (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_12)<<0));
    
                        Val=~(cord_h<<4|cord_l); //取反 便于分析Val对应的按键
                        return Val;
                }
    
            }
            return ~Val;
    }
    展开全文
  • STM32-MatrixKey 基于STM32F4矩阵键盘程序, 带按键抖动检测, 带按键松手检测.
  • 矩阵键盘 在其中3列加上低电平,第x列加上高电平,当检测到第y行出现低电平,说明x行y列有按键按下 执行上述步骤四次,就可以准确知道那个键位按下 中断原理 行的GPIO设置输入,上拉(不输入时默认高电平) ...

    原理

    矩阵键盘

    在其中3列加上低电平,第x列加上高电平,当检测到第y行出现低电平,说明x行y列有按键按下

    执行上述步骤四次,就可以准确知道那个键位按下

    中断原理

    行的GPIO设置输入,上拉(不输入时默认高电平)

    列的GPIO设置推挽输出,初始化低电平

    行GPIO对应LINE5~8,使用中断服务函数 EXTI9_5_IRQHandler

    当中断产生,先进入中断服务函数,再去判断是哪一根中断线,再开始逐列扫描

    注意:不要把多个GPIO映射到同一个中断线上,但多条中断线可以对应一个中断服务函数

    实现

    GPIO管脚定义

    行:F5~F8

    列:F1~F4

    // Row:F5~F8
    #define R1_PIN             GPIO_Pin_5
    #define R1_GPIO_PORT       GPIOF
    #define R1_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define R2_PIN             GPIO_Pin_6
    #define R2_GPIO_PORT       GPIOF
    #define R2_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define R3_PIN             GPIO_Pin_7
    #define R3_GPIO_PORT       GPIOF
    #define R3_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define R4_PIN             GPIO_Pin_8
    #define R4_GPIO_PORT       GPIOF
    #define R4_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    // Column:F1~F4
    #define C1_PIN             GPIO_Pin_1    
    #define C1_GPIO_PORT       GPIOF
    #define C1_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define C2_PIN             GPIO_Pin_2
    #define C2_GPIO_PORT       GPIOF
    #define C2_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define C3_PIN             GPIO_Pin_3
    #define C3_GPIO_PORT       GPIOF
    #define C3_GPIO_CLK        RCC_AHB1Periph_GPIOF
    
    #define C4_PIN             GPIO_Pin_4
    #define C4_GPIO_PORT       GPIOF
    #define C4_GPIO_CLK        RCC_AHB1Periph_GPIOF

    代码实现

    #include "delay.h"
    #include "led.h"
    #include "key.h"
    #include "beep.h"
    
    u8 flag_key = 0;
    int key_code = 0;
    
    void GPIO_GIVE() {  //全部置为低电平,中断检测
        GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
        GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
        GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
        GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
    }
    
    void EXTI9_5_IRQHandler(void) {  //中断服务函数
        delay_ms(10);
        if (EXTI_GetFlagStatus(EXTI_Line5) != RESET) {
            delay_ms(10);
            GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0));
                flag_key = 1;
                key_code = 1;
                EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0));
                flag_key = 1;
                key_code = 2;
                EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0));
                flag_key = 1;
                key_code = 3;
                EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN) == 0));
                flag_key = 1;
                key_code = 4;
                EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
        }
        else if (EXTI_GetFlagStatus(EXTI_Line6) != RESET) {
            delay_ms(10);
            GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0) {
                delay_ms(10);
                while (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0);
                flag_key = 1;
                key_code = 5;
                EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0) {
                delay_ms(10);
                while (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0);
                flag_key = 1;
                key_code = 6;
                EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0));
                flag_key = 1;
                key_code = 7;
                EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN) == 0));
                flag_key = 1;
                key_code = 8;
                EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
        }
        else if (EXTI_GetFlagStatus(EXTI_Line7) != RESET) {
            delay_ms(10);
            GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0) {
                delay_ms(10);
                while (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0);
                flag_key = 1;
                key_code = 9;
                EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0) {
                delay_ms(10);
                while (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0);
                flag_key = 1;
                key_code = 10;
                EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0));
                flag_key = 1;
                key_code = 11;
                EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN) == 0));
                flag_key = 1;
                key_code = 12;
                EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
        }
        else if (EXTI_GetFlagStatus(EXTI_Line8) != RESET) {
            delay_ms(10);
    
            GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0));
                flag_key = 1;
                key_code = 13;
                EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0) {
    
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0));
                flag_key = 1;
                key_code = 14;
                EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
    
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_SetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0));
                flag_key = 1;
                key_code = 15;
                EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
    
            GPIO_SetBits(C1_GPIO_PORT, C1_PIN);
            GPIO_SetBits(C2_GPIO_PORT, C2_PIN);
            GPIO_SetBits(C3_GPIO_PORT, C3_PIN);
            GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
            if (GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0) {
                delay_ms(10);
                while ((GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN) == 0));
                flag_key = 1;
                key_code = 16;
                EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE0上的中断标志位
                GPIO_GIVE();
                return;
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中断标志位
        EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE6上的中断标志位
        EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE7上的中断标志位
        EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE8上的中断标志位
        GPIO_GIVE();
    }
    
    
    
    //GPIO初始化程序
    void GPIO_SET(void) {             
        RCC_AHB1PeriphClockCmd(C1_GPIO_CLK | C2_GPIO_CLK | C3_GPIO_CLK | C4_GPIO_CLK, ENABLE);
        RCC_AHB1PeriphClockCmd(R1_GPIO_CLK | R2_GPIO_CLK | R3_GPIO_CLK | R4_GPIO_CLK, ENABLE);
    
        GPIO_InitTypeDef GPIO_InitStructure;
    
        GPIO_InitStructure.GPIO_Pin = C1_PIN;//列输出
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
        GPIO_Init(C1_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = C2_PIN;//C2列输出
        GPIO_Init(C2_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = C3_PIN;//C3列输出
        GPIO_Init(C3_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = C4_PIN;//C4列输出
        GPIO_Init(C4_GPIO_PORT, &GPIO_InitStructure);
    
        GPIO_InitStructure.GPIO_Pin = R1_PIN;//R1_PIN 行输入
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
        GPIO_Init(R1_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = R2_PIN;//R2_PIN 行输入
        GPIO_Init(R2_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = R3_PIN;//R3_PIN 行输入
        GPIO_Init(R3_GPIO_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = R4_PIN;//R4_PIN 行输入
        GPIO_Init(R4_GPIO_PORT, &GPIO_InitStructure);
    
        GPIO_GIVE();
    }
    
    void EXTIX_Init(void) {          
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
        GPIO_SET(); //按键对应的IO口初始化
    
        /* 配置EXTI_Line5~8 */
        EXTI_InitTypeDef EXTI_InitStructure;
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource5);//PF5 连接到中断线5
        EXTI_InitStructure.EXTI_Line = EXTI_Line5;//LINE5
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
        EXTI_Init(&EXTI_InitStructure);//配置
    
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource6);//PF6 连接到中断线6
        EXTI_InitStructure.EXTI_Line = EXTI_Line6;//LINE6
        EXTI_Init(&EXTI_InitStructure);//配置
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource7);//PF7 连接到中断线7
        EXTI_InitStructure.EXTI_Line = EXTI_Line7;//LINE7
        EXTI_Init(&EXTI_InitStructure);//配置
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource8);//PF8 连接到中断线8
        EXTI_InitStructure.EXTI_Line = EXTI_Line8;//LINE8
        EXTI_Init(&EXTI_InitStructure);//配置
    
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//外部中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;//子优先级2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
        NVIC_Init(&NVIC_InitStructure);//配置
    
    }
    
    
    
    
    
    
    
    
    

     

     

     

     

    展开全文
  • 由于中断方式去抖时需要采用定时器,且HAL下中断5-9为同一个中断处理函数,没有现成的获取当前中断源接口...基于STM32F429,正点原子基础上移植 keypad.h #ifndef _KEYPAD_H #define _KEYPAD_H #ifdef __cp...

    由于中断方式去抖时需要采用定时器,且HAL下中断5-9为同一个中断处理函数,没有现成的获取当前中断源接口(也许是没有找到),需要读取寄存器获取当前中断源。所以采用使用比较广泛的轮询方式实现。
    基于方便移植等,做了多个封装及注释;
    源码如下:

    基于STM32F429,正点原子基础上移植
    keypad.h

    #ifndef _KEYPAD_H
    #define _KEYPAD_H
    
    #ifdef __cplusplus
     extern "C" {
    #endif
    	 
    #include "sys.h"
    
    
    #define	KEY_ROW_NUM		3
    #define	KEY_COL_NUM		3
    	
    typedef struct _STRUCT_GPIO_ 
    {
    	GPIO_TypeDef* GPIOx;
    	uint16_t GPIO_Pin;
    }GpioStruct, *pGpioStruct;
    
    	 
    typedef struct _STRUCT_KEYPAD_
    {
    	GpioStruct rowNum[KEY_ROW_NUM];
    	GpioStruct colNum[KEY_COL_NUM];
    	
    }KeypadGpioStruct, *pKeypadGpioStruct;
    
    void KEY_Init(void);//IO³õʼ»¯
    int key_scan(void);  	//°´¼üɨÃ躯Êý					    
    	 
    #ifdef __cplusplus
    }
    #endif
    	 
    #endif
    
    

    keypad.c

    //#include "exti.h"
    #include "delay.h"
    #include "led.h"
    #include "keypad.h"
    
    //ÐÐÁмüÖµ²ÉÓöþάÊý×鷽ʽ£¬¸ù¾ÝÐèÒªÐ޸ĶÔÓ¦¼üÖµ£»
    u32 keyVal[KEY_COL_NUM][KEY_ROW_NUM] = 
    {
    	//col0
    	1,			//row0
    	2,			//row1
    	3,			//row2
    	
    	//col1
    	4,			//row0
    	5,			//row1
    	6,			//row2
    	
    	//col2
    	7,			//row0
    	8,			//row1
    	9,			//row2
    };
    //ÐÐÁжÔÓ¦Ó²¼þIO£¬²ÉÓýṹÌ帳ֵ·½Ê½£¬·½±ãÒÆÖ²£»
    KeypadGpioStruct keypadio = 
    { 
    	{{GPIOC, GPIO_PIN_1}, {GPIOH, GPIO_PIN_2}, {GPIOH, GPIO_PIN_3}},  	//rowNum[KEY_ROW_NUM]
    	{{GPIOC, GPIO_PIN_4}, {GPIOC, GPIO_PIN_5}, {GPIOC, GPIO_PIN_6}} 		//colNum[KEY_COL_NUM]
    };
    
    //°´¼ü³õʼ»¯º¯Êý 
    //PA15ºÍPC5 ÉèÖóÉÊäÈë
    void KEY_Init(void)
    {
        GPIO_InitTypeDef GPIO_Initure;
    
        __HAL_RCC_GPIOC_CLK_ENABLE();           //¿ªÆôGPIOBʱÖÓ
        __HAL_RCC_GPIOH_CLK_ENABLE();           //¿ªÆôGPIOBʱÖÓ
    
    		GPIO_Initure.Pin=GPIO_PIN_1; //PC1
        GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; 		//ÍÆÍìÊä³ö
        GPIO_Initure.Pull=GPIO_PULLUP;       			//ÉÏÀ­
        GPIO_Initure.Speed=GPIO_SPEED_HIGH;		    //¸ßËÙ
        HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    
    		GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2£¬PH3
        HAL_GPIO_Init(GPIOH,&GPIO_Initure);
    
    		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);	//PH7ÖÃ1 
    		HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET);	//PH7ÖÃ1 
    
    	
    		GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6; //PC4.PC5£¬PC6
        GPIO_Initure.Mode=GPIO_MODE_INPUT;   		//ÊäÈë
        GPIO_Initure.Pull=GPIO_PULLDOWN;        //ÏÂÀ­		Ó²¼þµç·ÓÐÉÏÀ­
        HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    
    	
    } 
    //°´¼ü´¦Àíº¯Êý
    
    
    
    int key_scan(void)
    {
    	static u8 key_up=1;
    	u8 keyUpFlag = 0;
    	u32 key_num=0;
    	u8 valValid = 0;
    	u8 icol, irow;
    	GPIO_PinState val_col[KEY_COL_NUM] = {0};		//ÓÃÓÚ´æ´¢ÁжÔÓ¦IOÖµ£¨0 or 1£©
    	
    	//ÅäÖÃÐÐÊä³öΪ¸ß
    	for(irow = 0; irow < KEY_ROW_NUM; irow++)
    	{
    		HAL_GPIO_WritePin(keypadio.rowNum[irow].GPIOx, keypadio.rowNum[irow].GPIO_Pin, GPIO_PIN_SET);	//PH7ÖÃ1 
    	}
    //	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);	//PH7ÖÃ1 
    //	HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET);	//PH7ÖÃ1 
    	delay_us(10);
    	//ÒÀ´Î¶ÁÈ¡ÁжÔÓ¦IOÖµ
    	for(icol = 0; icol < KEY_COL_NUM; icol++)
    	{
    		val_col[icol] = HAL_GPIO_ReadPin(keypadio.colNum[icol].GPIOx, keypadio.colNum[icol].GPIO_Pin);
    		if(key_up && val_col[icol])		//Èç¹ûÈ·¶¨Îªµ±Ç°ÁУ¬Ôò²éÕÒÄÄÒ»ÐÐ	COL0
    		{
    			delay_ms(10);	//keyVal
    			for(irow = 0; irow < KEY_ROW_NUM; irow++)
    			{
    				//ÒÀ´ÎÖÃλÐÐIOΪµÍ£¬Èç¹ûÐжÁȡΪµÍ£¬Ôò±íʾΪµ±Ç°ÐÐ
    				HAL_GPIO_WritePin(keypadio.rowNum[irow].GPIOx, keypadio.rowNum[irow].GPIO_Pin, GPIO_PIN_RESET);	//ÖÃ0
    				delay_us(10);
    				if(!HAL_GPIO_ReadPin(keypadio.colNum[icol].GPIOx, keypadio.colNum[icol].GPIO_Pin))		//Èç¹ûµ±Ç°¶Áµ½Îª0£¬Ôò±íʾÊÇ´ËÖµ£»
    				{
    					key_up = 0;
    					key_num = keyVal[icol][irow];		//¸ù¾ÝÐÐÁÐÖµ£¬»ñÈ¡¶ÔÓ¦¼üÖµ
    					valValid = 1;			//¼¦Àß
    					break;
    				}
    			}
    			if(valValid)
    				break;
    		}
    	}
    	//Èç¹ûÈ«²¿ÎªµÍ£¬Ôò±íʾ°´¼ü̧Æ𣻷Àֹ̧ÆðÇ°Öظ´·¢ËͼüÖµ
    	for(icol = 0; icol < KEY_COL_NUM; icol++)
    	{
    		keyUpFlag |= val_col[icol];
    	}
    	if(!keyUpFlag)		//ûÓмüÖµ£¬Ôò±íʾ̧Æð
    			key_up = 1;
    		
    	return key_num;	
    }
    /*************************************************˵Ã÷**********************************************************/
    /*   
    	1¡¢¾ØÕó¼üÅÌ£¨µ¥¸ö¼üÖµ£©£ºÁÐ×÷ΪÊäÈ루ÏÂÀ­£©£¬ÐÐ×öÊä³ö£»
    			ÐÐÊ×ÏÈÊä³öΪ¸ß£¬ÂÖѯ¶ÁÿһÁжÔÓ¦µÄIO£¬Èç¹ûΪ¸ß£¬Ôò±íʾ´ËÁÐÓа´¼ü°´Ï£¬·ñÔò²éѯÏÂÒ»ÁУ»
    			È·Èϵ±Ç°ÁÐÓа´¼ü°´ÏÂʱ£¬ÐÐÒÀ´ÎÊä³öΪµÍ£¬µ±»ñȡΪµÍʱ£¬±íʾµ±Ç°Ðа´Ï£¬·ñÔò¼ÌÐøÏÂÒ»ÐУ»
    			µ±Ç°ÐÐÁоùÈ·ÈϺ󣬼´¿ÉÊä³ö¶ÔÓ¦¼üÖµ£»
    
    	2¡¢ÎªÁË·½ÃæÐÞ¸ÄÒÆÖ²£¬ÐÐÁÐÊýÁ¿¾ù²ÉÓú궨Ò巽ʽ£»ÐÐÁжÔÓ¦IO²ÉÓýṹÌ帳ֵ·½Ê½£»¶ÔÓ¦¼üÖµ²ÉÓöþάÊý×鷽ʽ£»
    
    */
    
    
    

    注释为乱码,不知道怎么整,可以下载资源(不知道这里怎么上传),文件源码,搜索“STM32矩阵键盘HAL库实现,轮询方式,方便移植”(不知道怎么设置免费下载,哈哈)

    展开全文
  • 基于STM32F4的智能门锁超详细解析(矩阵键盘、OLED、舵机、HC-05蓝牙、F407ZG最小系统)可用于毕业设计
  • 本程序实现4*5键盘的扫描 从左到右,从上到下,键值 依次为1-20 中断扫描模式 ,要在NVIC在中打开对应中断 /*可以自己定义其它扫描方式
  • 最近做了个小项目,需要读取按键输入,由于条件限制只能用不带电源的4x4矩阵键盘。于是根据在淘宝上买的键盘电路,设计了键盘按钮的读入代码。 键盘电路如下: 思路介绍: 当某个按钮按下时,MCU首先是让...

    简介:

    最近做了个小项目,需要读取按键输入,由于条件限制只能用不带电源的4x4矩阵键盘。于是根据在淘宝上买的键盘电路,设计了键盘按钮的读入代码。

    键盘电路如下:

     

    思路介绍:

    当某个按钮按下时,MCU首先是让GPIOx1、2、3、4引脚置输出模式高电平,GPIOx5、6、7、8引脚置输入模式并读取这四个引脚的电平并保存(这其实相当于对这个键盘矩阵的四行进行扫描),看5678中哪个引脚读出来是高电平。接下来,相反操作,让GPIOx5、6、7、8引脚置输出模式高电平,GPIOx1、2、3、4引脚输入模式并读取这四个引脚的电平并保存(这其实相当于对这键盘矩阵四列进行扫描),看1234哪个引脚读出来是高电平。比如S1按下,5678引脚读出来分别就是“0001”(LSB代表引脚5),然后1234引脚读出来分别是“1000”(LSB代表引脚1),那么S1的按钮代码就是00011000=0x18,那么当程序检测到0x18就说明S1按下了。

    示例代码

    
    /****************bsp_key.h头文件内容*************************/
    #ifndef __BSP_KEY_H
    #define __BSP_KEY_H
    #include "stm32f4xx.h"
    
    /*定义需要的GPIO引脚,KEY1代表电路图中的引脚1,依此类推*/
    #define KEY1_PORT 			GPIOI 
    #define KEY1_GPIO_Pin		GPIO_Pin_2
    #define KEY1_GPIO_CLK		RCC_AHB1Periph_GPIOI
    
    #define KEY2_PORT 			GPIOI 
    #define KEY2_GPIO_Pin		GPIO_Pin_0
    #define KEY2_GPIO_CLK		RCC_AHB1Periph_GPIOI
    
    #define KEY3_PORT 			GPIOG 
    #define KEY3_GPIO_Pin		GPIO_Pin_10
    #define KEY3_GPIO_CLK		RCC_AHB1Periph_GPIOG
    
    #define KEY4_PORT 			GPIOE 
    #define KEY4_GPIO_Pin		GPIO_Pin_6
    #define KEY4_GPIO_CLK		RCC_AHB1Periph_GPIOE
    
    #define KEY5_PORT 			GPIOG 
    #define KEY5_GPIO_Pin		GPIO_Pin_6
    #define KEY5_GPIO_CLK		RCC_AHB1Periph_GPIOG
    
    #define KEY6_PORT 			GPIOA 
    #define KEY6_GPIO_Pin		GPIO_Pin_12
    #define KEY6_GPIO_CLK		RCC_AHB1Periph_GPIOA
    
    #define KEY7_PORT 			GPIOB 
    #define KEY7_GPIO_Pin		GPIO_Pin_0
    #define KEY7_GPIO_CLK		RCC_AHB1Periph_GPIOB
    
    #define KEY8_PORT 			GPIOH 
    #define KEY8_GPIO_Pin		GPIO_Pin_3
    #define KEY8_GPIO_CLK		RCC_AHB1Periph_GPIOH
    
    #define KEY_ON 1
    #define KEY_OFF 0
    
    /*所有按键的代码值*/
    #define KS1_CODE	0x18
    #define KS2_CODE	0x14
    #define KS3_CODE	0x12
    #define KS4_CODE	0x11
    #define KS5_CODE	0x28
    #define KS6_CODE	0x24
    #define KS7_CODE	0x22
    #define KS8_CODE	0x21
    #define KS9_CODE	0x48
    #define KS10_CODE	0x44
    #define KS11_CODE	0x42
    #define KS12_CODE	0x41
    #define KS13_CODE	0x88
    #define KS14_CODE	0x84
    #define KS15_CODE	0x82
    #define KS16_CODE	0x81
    
    uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin);
    u8 get_button_value(void);
    
    #endif
    /*********************************************************/
    
    /*****************bsp_key.c源文件内容**********************/
    #include "bsp_key.h"
    /**
    	* @brief 初始化控制KEY的GPIO引脚配置
    	* @param 无
    	* @retval 无
    	*/
    void KEY1_4_GPIO_Input_Config(void)
    {
    	GPIO_InitTypeDef Init_Structure;
        RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK
        |KEY3_GPIO_CLK|KEY4_GPIO_CLK,ENABLE);
    	
    	Init_Structure.GPIO_Mode = GPIO_Mode_IN;
    	Init_Structure.GPIO_Pin = KEY1_GPIO_Pin;
    	Init_Structure.GPIO_PuPd = GPIO_PuPd_DOWN;	//这里务必设置成下拉模式
    
    	GPIO_Init(KEY1_PORT,&Init_Structure);
    	
    	Init_Structure.GPIO_Pin = KEY2_GPIO_Pin;
    	GPIO_Init(KEY2_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY3_GPIO_Pin;
    	GPIO_Init(KEY3_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY4_GPIO_Pin;
    	GPIO_Init(KEY4_PORT,&Init_Structure);
    }
    
    void KEY5_8_GPIO_Input_Config(void)
    {
    	GPIO_InitTypeDef Init_Structure;
    	RCC_AHB1PeriphClockCmd(KEY5_GPIO_CLK|KEY6_GPIO_CLK|KEY7_GPIO_CLK|KEY8_GPIO_CLK,ENABLE);
    	
    	Init_Structure.GPIO_Mode = GPIO_Mode_IN;
    	Init_Structure.GPIO_Pin = KEY5_GPIO_Pin;
    	Init_Structure.GPIO_PuPd = GPIO_PuPd_DOWN; //这里务必设置成下拉模式
    
    	GPIO_Init(KEY5_PORT,&Init_Structure);
    	
    	Init_Structure.GPIO_Pin = KEY6_GPIO_Pin;
    	GPIO_Init(KEY6_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY7_GPIO_Pin;
    	GPIO_Init(KEY7_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY8_GPIO_Pin;
    	GPIO_Init(KEY8_PORT,&Init_Structure);
    }
    
    void KEY1_4_GPIO_Output_Config(void)
    {
    	GPIO_InitTypeDef Init_Structure;
    	RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK|KEY3_GPIO_CLK|KEY4_GPIO_CLK,ENABLE);
    	
    	Init_Structure.GPIO_Mode = GPIO_Mode_OUT;
    	Init_Structure.GPIO_OType = GPIO_OType_PP;
    	Init_Structure.GPIO_PuPd = GPIO_PuPd_UP;
    	Init_Structure.GPIO_Speed = GPIO_Speed_25MHz;
    	Init_Structure.GPIO_Pin = KEY1_GPIO_Pin;
    
    	GPIO_Init(KEY1_PORT,&Init_Structure);
    	
    	Init_Structure.GPIO_Pin = KEY2_GPIO_Pin;
    	GPIO_Init(KEY2_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY3_GPIO_Pin;
    	GPIO_Init(KEY3_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY4_GPIO_Pin;
    	GPIO_Init(KEY4_PORT,&Init_Structure);
    }
    
    void KEY5_8_GPIO_Output_Config(void)
    {
    	GPIO_InitTypeDef Init_Structure;
    	RCC_AHB1PeriphClockCmd(KEY5_GPIO_CLK|KEY6_GPIO_CLK|KEY7_GPIO_CLK|KEY8_GPIO_CLK,ENABLE);
    	
    	Init_Structure.GPIO_Mode = GPIO_Mode_OUT;
    	Init_Structure.GPIO_OType = GPIO_OType_PP;
    	Init_Structure.GPIO_PuPd = GPIO_PuPd_UP;
    	Init_Structure.GPIO_Speed = GPIO_Speed_25MHz;
    	Init_Structure.GPIO_Pin = KEY5_GPIO_Pin;
    
    	GPIO_Init(KEY5_PORT,&Init_Structure);
    	
    	Init_Structure.GPIO_Pin = KEY6_GPIO_Pin;
    	GPIO_Init(KEY6_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY7_GPIO_Pin;
    	GPIO_Init(KEY7_PORT,&Init_Structure);
    
    	Init_Structure.GPIO_Pin = KEY8_GPIO_Pin;
    	GPIO_Init(KEY8_PORT,&Init_Structure);
    }
    
    /**
      * @brief 读取KEY的GPIO引脚状态(这个函数这里没用到,但为了保持完整性还是贴出来)
      * @param GPIO,Pin
      * @retval 引脚状态
      */
    uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
    {
    	if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)== KEY_ON)
    	{
    		while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)== KEY_ON)
    			return KEY_ON;
    	}
    	return KEY_OFF;
    }
    /**
      * @brief 给1234引脚置高电平
      * @param void
      * @retval void
      */
    void set_key1_4_Bits(void)
    {
    	GPIO_SetBits(KEY1_PORT,KEY1_GPIO_Pin);
    	GPIO_SetBits(KEY2_PORT,KEY2_GPIO_Pin);
    	GPIO_SetBits(KEY3_PORT,KEY3_GPIO_Pin);
    	GPIO_SetBits(KEY4_PORT,KEY4_GPIO_Pin);
    }
    
    /**
      * @brief 读取1234引脚电平并存到temp低四位
      * @param void
      * @retval 返回4个引脚电平状态
      */
    u8 read_key1_4_Bits(void)
    {
    	u8 k1=0,k2=0,k3=0,k4=0,temp = 0;
    	k1 = GPIO_ReadInputDataBit(KEY1_PORT,KEY1_GPIO_Pin);
    	temp |= k1;
    	
    	k2 = GPIO_ReadInputDataBit(KEY2_PORT,KEY2_GPIO_Pin);
    	k2<<=1;
    	temp |= k2;
    	
    	k3 = GPIO_ReadInputDataBit(KEY3_PORT,KEY3_GPIO_Pin);
    	k3<<=2;
    	temp |= k3;
    	
    	k4 = GPIO_ReadInputDataBit(KEY4_PORT,KEY4_GPIO_Pin);
    	k4<<=3;
    	temp |= k4;
    	return temp;
    }
    
    /**
      * @brief 给5678引脚置高电平
      * @param void
      * @retval void
      */
    void set_key5_8_Bits(void)
    {
    	GPIO_SetBits(KEY5_PORT,KEY5_GPIO_Pin);
    	GPIO_SetBits(KEY6_PORT,KEY6_GPIO_Pin);
    	GPIO_SetBits(KEY7_PORT,KEY7_GPIO_Pin);
    	GPIO_SetBits(KEY8_PORT,KEY8_GPIO_Pin);
    }
    
    /**
      * @brief 读取5678引脚电平并存到temp高四位
      * @param void
      * @retval 返回4个引脚电平状态
      */
    u8 read_key5_8_Bits(void)
    {
    	u8 k5=0,k6=0,k7=0,k8=0,temp = 0;
    	k5 = GPIO_ReadInputDataBit(KEY5_PORT,KEY5_GPIO_Pin);
    	k5<<=4;
    	temp |= k5;
    	
    	k6 = GPIO_ReadInputDataBit(KEY6_PORT,KEY6_GPIO_Pin);
    	k6<<=5;
    	temp |= k6;
    	
    	k7 = GPIO_ReadInputDataBit(KEY7_PORT,KEY7_GPIO_Pin);
    	k7<<=6;
    	temp |= k7;
    	
    	k8 = GPIO_ReadInputDataBit(KEY8_PORT,KEY8_GPIO_Pin);
    	k8<<=7;
    	temp |= k8;
    	
    	return temp;
    }
    
    /**
      * @description 获取按键的值以确定是哪个按钮被按下
      * @param void
      *
      * @retval 0代表未被按下,非0表示被按下的按钮的值
      *
      *
      */
    u8 get_button_value(void)
    {
    	u8 button_value = 0;
    	u8 k1_4=0,k5_8=0;
    	KEY1_4_GPIO_Output_Config();    //设置输出模式
    	KEY5_8_GPIO_Input_Config();     //设置输入模式
    
    	set_key1_4_Bits();		            //1234引脚置高电平
    	delay(1);                           //延时1ms确保电平稳定	
    	k5_8 = read_key5_8_Bits();          //读取5678引脚电平
    	
    	/*如果不等于0说明有按键按下*/
    	if(k5_8!=0)					
    	{
    		delay(5);	                    //延时消抖动,再次予以确认
    		k5_8 = read_key5_8_Bits();
    		
    		if(k5_8!=0)
    		{
    			KEY1_4_GPIO_Input_Config(); //设置输入模式
    			KEY5_8_GPIO_Output_Config();//设置输出模式
    			delay(1);	                //延时1ms确保电平稳定	
    			set_key5_8_Bits();
    
    			k1_4=read_key1_4_Bits();			
    			delay(5);                  //延时消抖动,再次予以确认			
    			k1_4=read_key1_4_Bits();
    			///生成按键值
    			button_value |= k5_8;      //实际上只取了k5_8高四位
    			button_value |= k1_4;      //实际上只取了k1_4低四位
    			return button_value;
    		}
    	}
    	return 0;
    }
    /*********************************************************/
    
    /********************测试main.c*******************************/
    
    int main(void)
    {
    	u8 button_value=0;
    	while(1)
    	{
    		button_value=0;
    		button_value=get_button_value();
    		if(button_value!=0)
    			printf("button value=0x%2x\r\n",button_value);
    		delay(150);    //150ms检测一次,防止连续读取重复值(人按下按钮会持续一段时间才松开)。
    	}
    
    }
    
    /*********************************************************/
    
    
    
    

     

    展开全文
  • stm32 4*4矩阵键盘程序

    2017-03-25 10:57:51
    stm32 4*4矩阵键盘程序
  • 湖北省2016年电子设计大赛,亲测可用
  • STM32矩阵键盘 一、实现效果   同时可实现 按键消抖 松手 二、使用方法  ① 包含正点原子的sys.h  ② 制作.h .c文件 -源码见 “二”  ③ 把 key_scan 函数 放入 5ms 的定时器中断,可自实现 按键消抖  ④ 按...
  • STM32F407ZG实现4*4矩阵键盘
  • 基于 STM32F407 使用 4*4 矩阵键盘(附完整程序)

    万次阅读 多人点赞 2019-03-03 08:56:16
    STM32F407使用4*4矩阵键盘
  • //F4 case 0x7f1000: return 0x003F; //F5 case 0xf70020: return 0x0040; //F6 case 0xfb0200: return 0xE053; //Delete case 0xfe2000: return 0xE047; //CW case 0xf72000: return 0xE049; //PW ...
  • stm32f4开发笔记

    2018-04-04 12:01:50
    stm32f4为例: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); { /* 可能TIM1 有不同的默认值,但是结构体的默认值一定是0呀.. */ TIM_TimeBaseInitTypeDef r1 = { .TIM_Pres...
  • 是基于正点原子的TFTLCD显示和触摸屏的历程改的,在本篇就不再叙述TFTLCD屏的成像原理和触摸原理了。直接上应用,可能有些地方理解的不到位,欢迎各位大佬指正。... //这十条语句用来在屏幕上画一个九格的矩阵键盘
  • stm32f4xx.h> #include <bsp_systick.h> #include <bsp_usart.h> // Column1, Column2, Column3, Column4 #define C1_PIN GPIO_Pin_2 #define C1_GPIO_PORT GPIOE #define C1_GPIO_CLK RCC_AHB1...
  • 采用方案是手表+Android Phone进行协同工作,硬件手表端使用基于ARM Cortex-M4的STM32F4处理器,通过Bluetooth与Android Phone进行数据交互与控制。传感器包括心率传感器PulseSenor、MPU6050运动姿态传感器以及温...
  • 欢迎转载,但也请保留上面这段...本人现在大三,以前在学习过程中遇到过各种各样的问题,关于51单片机,STM32单片机,最近在学习ARM11的Tiny6410 以后还会更新一些C/C++方面的东西 关于写博客这件事,其实 一直想...
  • STM32F4开发板快速入门—-GPIO篇 GPIO 设置输入/出总共8种模式 * 输入浮空,输入上拉,输入下拉,模拟输入。 * 开漏输出,推挽输出,推挽复用共功能,开漏复用功能 模式选择的话,一般得看具体电路了,具体看...
  • 本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可。 1、键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样这个8个引脚都是高...
  • //键盘全局声明 extern unsigned int Keyboard_Val ;//当前键值 //extern unsigned char Keyboard_Change_Flag;//键值改变标志,读入新键值后,标志位清零 extern u8 key_pressed_flag; //有按键按下时置1 extern ...
  • 4*4矩阵键盘驱动编写 4.串口(外设HMI串口屏,HC—06,CH340) 普通:用电脑串口命令控制单片机灯闪烁 提高:HMI智能串口屏与单片机通信, 蓝牙芯片进行通信 5.定时器(OLED,LCD,串口屏) 人生第一个时钟 普通:...
  • 修改位置为,system_stm32f4xx.c,400行位置。 #if defined (STM32F40_41xxx) #define PLL_N 336 //360 /* SYSCLK = PLL_VCO / PLL_P */ #define PLL_P 2 #endif /* STM32F40_41xxx */ 软件说明 使用定时器...
  • 一、矩阵键盘的原理图、PCB图 二、矩阵键盘的初始化 三、扫描函数详解 一、矩阵键盘的原理图、PCB图 二、矩阵键盘的初始化 PF0到PF3固定为推挽输出,PF12到PF15固定为下拉输入。 即,无键按下时,对应PF12...
  • 最近参加电子大赛要写一个矩阵按键,刚开始写了好长时间换了好几个矩阵按键都不好使,但是 我感觉我的程序和原理都没有错,调试了好久也没有...stm32f10x.h" #include "delay.h" /******************...
  • 2017年电设国赛板球系统,用stm32f4系列芯片编写的代码,用到了微分先行PID,与树莓派串口通信,控制小球位置的代码,zlg矩阵键盘芯片等等元器件

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

stm32f4矩阵键盘