|
本帖最后由 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
|