|  | 
 
| 本帖最后由 sunsili 于 2023-12-11 21:33 编辑 
 STM32F103RCT6开发板M3单片机教程04--按键检测
 
 
 原理图讲解
 本教程使用是(光明谷SUN_STM32mini开发板)
 
   首先了硬件连接原理,STM32F103RCT6开发板是mini最小系统板,板子在没并有按键。需要自行用面包板搭建。
 
   硬件连接:
 
 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 : fan@sunsili.com
**********************************************************************************/
#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 : fan@sunsili.com
**********************************************************************************/
#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 : fan@sunsili.com
**********************************************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include <stdio.h>
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 : fan@sunsili.com          *************\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        *******************/
编译调试
 连接串口打印,输出按键值。按下按键对应灯会亮。
 
 工程源码
 
 
 
 
 | 
 
+10 |