STM32F103RCT6开发板M3单片机教程04--按键检测


原画图讲解


本教程使用是(光明谷SUN_STM32mini开发板

STM32F103RCT6开发板M3单片机教程04--按键检测_第1张图片
首先了硬件连接原理,STM32F103RCT6开发板是mini最小系统板,板子在没并有按键。需要自行用面包板搭建。

STM32F103RCT6开发板M3单片机教程04--按键检测_第2张图片

硬件连接:  

PC10 -> KEY1 (MCU内部上拉) --> GND   (低电平有效)

PC11 -> KEY2(MCU内部上拉) --> GMD    (低电平有效)

程序设计

有两种方法:

方法1、不断检测引脚(PC10, PC11)电平, 当检测到引脚(PC10, PC11)为低电平时,则有按键按下;

方法2、中断检测,设置引脚(PC10, PC11)下降沿触中断,在中断函数里,判断是哪个引脚发生的中断。

现在我们用方法1,编写代码。下集我们用中断方法。

编写代码

  • 复制上节工程文件夹打开(这个方法比较方便)
  • 新建源文件key.c,添加key.c到BSP(Grounp),并编辑
    /**********************************************************************************
    
    * 文件名  :key.c
    
    * 描述    :按键扫描(系统滴答时钟SysTick实现扫描延时)
    
    * 实验平台:Sun_STM32Min系统板
    
    * 硬件连接:  PC10 -> KEY1  --> GND   
    
    *             PC11 -> KEY2 --> GMD      
    
    * 库版本  :ST_v3.5
    
    
    
    * Version    Date       Auther      Reversed History
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
      
    
    * (C) Sunshine Silicon Corporation
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    *  E-Mail : [email protected]
    
    **********************************************************************************/
    
    
    #include "key.h"
    #include "SysTick.h"
    
    /*******************************************************************************
    * 函数名  : Key_GPIO_Config
    * 描述    : KEY IO配置
    * 输入    : 无
    * 输出    : 无
    * 返回    : 无
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    
    *******************************************************************************/
    
    void Key_GPIO_Config(void)
    {
            GPIO_InitTypeDef  GPIO_InitStructure;                                //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体        
    
            RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);                        //使能GPIOA的外设时钟 
            GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2;                        //选择要初始化的GPIOA引脚(PA15,PA14)
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                //设置引脚工作模式为上拉输入            
    
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHz
            GPIO_Init(KEY_PORT, &GPIO_InitStructure);                        //调用库函数中的GPIO初始化函数,初始化GPIOA中的PA15,PA14引脚
    }
    
    
    /*******************************************************************************
    * 函数名  : Key_Detection
    * 描述    : 按键按下检测
    * 输入    : GPIOx:按键对应的GPIO,GPIO_Pin:对应按键端口
    * 输出    : 无
    * 返回    : KEY_DOWN(0):对应按键按下,KEY_UP(1):对应按键没按下
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    
    *******************************************************************************/
    
    u8 Key_Down_Detection(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
    {                        
    
            if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN)        //检测是否有按键按下
            {
                    Delay_nMs(10);        //延时消抖               
    
                    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN)        //检测是否有按键按下
                   {
                            while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN);        //等待按键释放 
    
                            return KEY_DOWN;        
    
                    }
                    else
                    {
                            return KEY_UP;
                    }
            }
            else
            {
                    return KEY_UP;
            }
    }
    
    
    
    /*******************************************************************************
    * 函数名  : Key_Down_Scan
    * 描述    : 按键按下扫描
    * 输入    : 无
    * 输出    : 0:没有按键按下,
                1:按键按下
    * 返回    : 无
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    *******************************************************************************/
    
    u8 Key_Down_Scan(void)
    {
            u16 downflag=0;
            u8 value=0;
    
            downflag=GPIO_ReadInputData(KEY_PORT);
    
            if((downflag & 0x0c00) != 0x0c00)        //检测是否有按键按下
            { 
                    Delay_nMs(10);        //延时消抖       
    
                    downflag = GPIO_ReadInputData(KEY_PORT) & 0x0c00;        
    
                    if(downflag != 0x0c00 )        //检测是否有按键按下 
                    {
                            if((downflag & 0x0400) == 0) value |= 0x01;
                            if((downflag & 0x0800) == 0) value |= 0x02;    
                    }
            }  
    
            return value;
    }
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE key.c        *******************/

  • 新建源文件key.h,并编辑
    /**********************************************************************************
    
    * 文件名  :led.c
    
    * 描述    :led 应用函数库         
    
    * 实验平台:Sun_STM32Min系统板
    
    * 硬件连接:  PA5 -> LED1    板子上没有 要用杜绑线外接
    
    *             PA6 -> LED2   板子上没有 要用杜绑线外接  
    
    *             PA7 -> LED3   板子上没有 要用杜绑线外接
    
    *             PA8 -> LED4   板子有直接观察
    
    * GPIO置低电平亮LED
    
    
    
    * 库版本  :ST_v3.5
    
    
    
    * Version    Date       Auther      Reversed History
    
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    
      
    
    * (C) Sunshine Silicon Corporation
    
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    
    *  E-Mail : [email protected]
    
    **********************************************************************************/
    
    
    
    #include "Led.h"
    
               
    
    /*******************************************************************************
    
    * 函数名  : LED_GPIO_Config
    
    * 描述    : LED IO配置
    
    * 输入    : 无
    
    * 输出    : 无
    
    * 返回    : 无
    
    * 说明    : LED(1~4)的IO口分别是:PB5,PB6,PB7,PB8
    
    *******************************************************************************/
    
    void LED_GPIO_Config(void)
    
    {
    
            GPIO_InitTypeDef  GPIO_InitStructure;                                //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体
    
            
    
            RCC_APB2PeriphClockCmd(LED_RCC, ENABLE);                        //使能GPIOB的外设时钟        
    
            
    
            GPIO_InitStructure.GPIO_Pin = LED_ALL;                                //选择要初始化的GPIOB引脚(PB5,PB6,PB7,PB8)
    
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //设置引脚工作模式为通用推挽输出                 
    
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHz
    
            GPIO_Init(LED_PORT, &GPIO_InitStructure);                        //调用库函数中的GPIO初始化函数,初始化GPIOB中的PB5,PB6,PB7,PB8引脚
    
    
    
            LED_ALL_OFF();                                                                                //关闭ALL_LED                                          
    
    }
    
    
    
    /*点亮LED1.PA5*/
    
    void LED1_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED1);
    
    }
    
    
    
    /*关闭LED1.PA5*/
    
    void LED1_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED1);
    
    }
    
    
    
    /*点亮LED2.PA6*/
    
    void LED2_ON(void)  
    
    {
    
            GPIO_ResetBits(LED_PORT,LED2);
    
    }
    
    
    
    /*关闭LED2.PA6*/
    
    void LED2_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED2);
    
    }
    
    
    
    /*点亮LED3.PA7*/
    
    void LED3_ON(void)   
    
    {
    
            GPIO_ResetBits(LED_PORT,LED3);
    
    }
    
    
    
    /*关闭LED3.PA7*/
    
    void LED3_OFF(void)  
    
    {
    
            GPIO_SetBits(LED_PORT,LED3);
    
    }
    
    
    
    /*点亮LED4.PA8*/
    
    void LED4_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED4);
    
    }
    
    
    
    /*关闭LED4.PA8*/
    
    void LED4_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED4);
    
    }
    
    
    
    /*点亮ALL_LED*/
    
    void LED_ALL_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED_ALL);
    
    }
    
    /*关闭ALL_LED*/
    
    void LED_ALL_OFF(void)  
    
    {
    
            GPIO_SetBits(LED_PORT,LED_ALL);
    
    }
    
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE led.c        *******************/

  • 编辑main.c
    /**********************************************************************************
    
    * Sun STM32 mini Demo
    
    
    
    *   Description
    
       
    
        Uart Demo
    
    
    
       
    
    * Version    Date       Auther      Reversed History
    
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    
      
    
    * (C) Sunshine Silicon Corporation
    
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    
    *  E-Mail : [email protected]
    
    
    
    **********************************************************************************/
    
    
    
    #include "stm32f10x.h"
    
    #include "usart.h"
    
    #include "SysTick.h"
    
    #include "led.h"
    
    #include "key.h"
    
    #include 
    
    
    
    
    
    extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN];        //串口1数据接收缓冲区
    
    extern vu8 Usart1_R_State;                                                //串口1接收状态
    
    extern vu16 Usart1_R_Count;                                                //当前接收数据的字节数         
    
    
    
    
    
    /*******************************************************************************
    
    * 函数名  : main
    
    * 描述    : 主函数,用户程序从main函数开始运行
    
    * 输入    : 无
    
    * 输出    : 无
    
    * 返回值  : int:返回值为一个16位整形数
    
    * 说明    : 无
    
    *******************************************************************************/
    
    int main(void)
    
    {
    
        u8 keyVal;
    
        SysTick_Init_Config();
    
            USART1_Init_Config(115200);//USART1初始化配置
    
        LED_GPIO_Config();
    
        Key_GPIO_Config();
    
        printf ("*===================================================*\n");
    
        printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");
    
        printf ("*  * (C) Sunshine Silicon Corporation    *************\n");
    
        printf ("*  *  Website: http://www.sunsili.com    *************\n");
    
        printf ("*  *   E-Mail : [email protected]          *************\n");
    
        printf ("*===================================================*\n");
    
        printf ("* Sun STM32 mini Key Demo code .*\n");
    
       
    
            while (1)
    
            {
    
            keyVal = Key_Down_Scan();
    
                    if(Usart1_R_State == 1)//一帧数据接收完成
    
                    {
    
                            USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count);   //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
    
                            Usart1_R_State =0;
    
                            Usart1_R_Count =0;
    
                    }
    
            if(keyVal)
    
            {
    
                printf("KeyVal:%d\r", keyVal);
    
                if(keyVal & 0x01) LED3_ON();            
    
                else if(keyVal & 0x02) LED4_ON();            
    
            }
    
            else LED_ALL_OFF();
    
            }
    
    }
    
    
    
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE main.c        *******************/

  • 编译调试

     方法不再重复,经过前两节练习,大家应该是会了.
     连接串口打印,输出按键值。按下按键对应灯会亮。

查看原文,可以下载工程源码

你可能感兴趣的:(嵌入式开发,单片机,嵌入式硬件)