STM32学习笔记2——按键点灯
程序员文章站
2022-06-09 08:42:05
...
1-硬件
机械按键按下到自动弹起的过程中,按键会有抖动。一般可采用软件消抖(?)或硬件消抖。本例属于硬件消抖。
开发板上电路图
K1不按下时,引脚接地,处于低电平。
K1按下时,引脚接3.3V,处于高电平。
K1抖动时,相当于电路存在交流电,电容导通,3.3V接地,从而使引脚处于低电平。
电阻减少电流大小,保护电路。
2-按键的相关寄存器
K1的引脚为PA0,K2的引脚为PC13。
IDR的数据与当前输入的数据有关。当K1按下后,引脚高电平,IDR0置1。
为了GPIOA使能,需要配置外设使能时钟。外设GPIOA在APB2总线上。
打开IO端口A时钟使能。
端口配置寄存器配置为浮点输入模式。
3-代码
main.c
#include "stm32f10x.h"
#include "bsp_led.h" //led的控制头文件
#include "bsp_key.h" //key的控制头文件
int main(void)
{
LED_GPIO_Config();
KEY1_GPIO_Config();
LED_R(OFF);
LED_G(OFF);
LED_B(OFF);
while(1)
{
if (KEY1_SCAN(KEY1_GPIO_PORT , KEY1_GPIO_PIN) == KEY_ON)
{
LED_G_TOGGLE;
LED_B_TOGGLE;
}
}
}
bsp_key.h
#ifndef __BSP_KEY_H
#define __BSP_KEY_H
#include "stm32f10x.h"
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY1_GPIO_PIN GPIO_Pin_0
#define KEY_ON 1
#define KEY_OFF 0
void KEY1_GPIO_Config(void); //函数声明
uint8_t KEY1_SCAN(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
#endif /* __BSP_KEY_H */
bsp_key.c
#include "bsp_key.h"
void KEY1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE); //APB2外设时钟使能库函数,打开GPIOA时钟使能
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_CLK;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct); //调用库函数初始化GPIOB,&表示取结构体的地址
}
uint8_t KEY1_SCAN (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) //按键检测函数
{
if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON) //检测IDR的库函数
{
while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
return KEY_ON;
}
else return KEY_OFF;
}
bsp.led.h
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "stm32f10x.h"
#define LED_GPIO_PORT GPIOB //GPIOB外设宏定义
#define LED_GPIO_CLK RCC_APB2Periph_GPIOB //外设GPIOB在总线APB2上,GPIOB外设时钟使能位宏定义
#define LED_R_GPIO_PIN GPIO_Pin_5 //红灯引脚PB5
#define LED_G_GPIO_PIN GPIO_Pin_0 //绿灯引脚PB0
#define LED_B_GPIO_PIN GPIO_Pin_1 //蓝灯引脚PB1
//控制RGB灯的亮灭
#define ON 1
#define OFF 0
#define LED_R(a) if(a) \
GPIO_ResetBits(LED_GPIO_PORT , LED_R_GPIO_PIN); \
else \
GPIO_SetBits(LED_GPIO_PORT , LED_R_GPIO_PIN);
#define LED_G(a) if(a) \
GPIO_ResetBits(LED_GPIO_PORT , LED_G_GPIO_PIN); \
else \
GPIO_SetBits(LED_GPIO_PORT , LED_G_GPIO_PIN);
#define LED_B(a) if(a) \
GPIO_ResetBits(LED_GPIO_PORT , LED_B_GPIO_PIN); \
else \
GPIO_SetBits(LED_GPIO_PORT , LED_B_GPIO_PIN);
/*新增led翻转宏定义*/
#define LED_R_TOGGLE (LED_GPIO_PORT->ODR ^= LED_R_GPIO_PIN);
#define LED_G_TOGGLE (LED_GPIO_PORT->ODR ^= LED_G_GPIO_PIN);
#define LED_B_TOGGLE (LED_GPIO_PORT->ODR ^= LED_B_GPIO_PIN);
void LED_GPIO_Config(void);
#endif /* __BSP_LED_H */
bsp_led.c
//bsp: board support package 板级支持包(针对开发板)
#include "bsp_led.h" //记得在Option for Target中指定头文件路径
void LED_GPIO_Config(void)
{
//定义GPIO_InitStruct为GPIO_InitTypeDef结构体类型,以便下面用GPIO配置的存放
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE); //APB2外设时钟使能库函数,打开GPIOB时钟使能
GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_PIN | LED_G_GPIO_PIN | LED_B_GPIO_PIN; //选择控制的GPIO引脚,使用宏定义
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct); //调用库函数初始化GPIOB,&表示取结构体的地址
}