首页 > 其他分享 >[单片机框架][bsp层][cx32l003][bsp_key] KEY配置和使用

[单片机框架][bsp层][cx32l003][bsp_key] KEY配置和使用

时间:2022-10-31 18:35:52浏览次数:52  
标签:cx32l003 BUTTON endif bsp 单片机 NUM BS button


按键的基本原理是设置单片机IO口(PB0-PB3)为输入状态,如DDRB = 0XF0(方向寄存器,“1”为输出,“0”为输入);

单片机一直检测按键端口(PB0-PB3)的状态,当端口为低电平时(即按键按下),实行相应的动作(比如控制LED灯)。

原理就是这么回事,但是正真实现时,按键会有抖动,要进行按键去抖,下图为按键按下时的抖动图。

按键实行一个动作过程是需要一定时间的,一般为100mS-1S左右,而一个单片机执行一个机器周期的时间很短,时钟为10MH的周期为0.1μs,这样按键每一次动作程序就会多次检测按键,出现误判(一次按下,多次动作)。

/********************************************************************************
* @file bsp_key.c
* @author jianqiang.xue
* @version V1.0.0
* @date 2021-04-03
* @brief NULL
********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "RTE_Components.h"
#include CMSIS_device_header

#include "bsp_gpio.h"
#include "bsp_exti.h"
#include "bsp_led.h"
#include "bsp_key.h"

/* Private Includes ----------------------------------------------------------*/
#include "business_gpio.h"
#include "business_function.h"

/* Private Define ------------------------------------------------------------*/

#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) \
do \
{ \
if ((__INDEX__) == 0) \
BS_BUTTON0_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 1) \
BS_BUTTON1_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 2) \
BS_BUTTON2_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 3) \
BS_BUTTON3_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 4) \
BS_BUTTON4_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 5) \
BS_BUTTON5_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 6) \
BS_BUTTON6_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 7) \
BS_BUTTON7_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 8) \
BS_BUTTON8_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 9) \
BS_BUTTON9_GPIO_CLK_ENABLE(); \
else if ((__INDEX__) == 10) \
BS_BUTTON10_GPIO_CLK_ENABLE(); \
} while (0U)

/* Private Variables ---------------------------------------------------------*/
#if BS_BUTTON_NUM != 0

static GPIO_TypeDef *g_button_port[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_GPIO_PORT
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_GPIO_PORT
#endif
};

static const uint16_t g_button_pin[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_PIN
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_PIN
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_PIN
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_PIN
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_PIN
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_PIN
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_PIN
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_PIN
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_PIN
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_PIN
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_PIN
#endif
};

static const bsp_gpio_pin_pull_t g_button_pull[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_PULL
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_PULL
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_PULL
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_PULL
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_PULL
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_PULL
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_PULL
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_PULL
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_PULL
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_PULL
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_PULL
#endif
};

static const bool g_button_exti[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_EXTI_SEL
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_EXTI_SEL
#endif
};

static const uint8_t g_button_irqn[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_EXTI_IRQn
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_EXTI_IRQn
#endif
};

static const bsp_gpio_exti_int_type_t g_button_irq_edge_level_sel[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON6_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_EXTI_EDGE_LEVEL_SEL
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_EXTI_EDGE_LEVEL_SEL
#endif
};

static const bsp_gpio_exti_int_event_t g_button_irq_rise_fall_sel[BS_BUTTON_NUM] = {
#if (BS_BUTTON_NUM > 0)
BS_BUTTON0_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 1)
,BS_BUTTON1_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 2)
,BS_BUTTON2_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 3)
,BS_BUTTON3_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 4)
,BS_BUTTON4_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 5)
,BS_BUTTON5_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 6)
,BS_BUTTON5_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 7)
,BS_BUTTON7_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 8)
,BS_BUTTON8_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 9)
,BS_BUTTON9_EXTI_RISE_FALL_SEL
#endif
#if (BS_BUTTON_NUM > 10)
,BS_BUTTON10_EXTI_RISE_FALL_SEL
#endif
};

/* External Variables --------------------------------------------------------*/
typedef void(*bsp_button_callback)(void);
static bsp_button_callback irq_callback[BS_BUTTON_NUM];
/* Private Macro -------------------------------------------------------------*/
static void bsp_button_exti_callback(void *gpiox, uint16_t gpio_pin);
/* Public Function Prototypes -----------------------------------------------*/

/**
* @brief [初始化] 按键引脚初始化并注册按键外部中断回调函数
* @note NULL
* @retval None
*/
void bsp_button_init(void)
{
uint8_t ch;

for (ch = 0; ch < BS_BUTTON_NUM; ch++)
{
/* Enable the BUTTON Clock */
BUTTONx_GPIO_CLK_ENABLE(ch);

if (g_button_exti[ch] == DISABLE)
{
/* Configure Button pin as input */
bsp_gpio_init_input(g_button_port[ch], g_button_pin[ch], g_button_pull[ch]);
}
else
{
/* Configure Button pin as input with External interrupt */
irq_callback[ch] = NULL;
bsp_gpio_init_input_exit(g_button_port[ch], g_button_pin[ch], g_button_irqn[ch],
g_button_irq_edge_level_sel[ch],
g_button_irq_rise_fall_sel[ch],
g_button_pull[ch]);
}
}

if (BS_BUTTON_NUM)
{
bsp_gpio_exit_irq_register_callback(bsp_button_exti_callback);
}
}

/**
* @brief [反初始化] 按键恢复默认状态
* @note NULL
* @param ch: 按键号
* @retval None
*/
void bsp_button_deinit(bsp_button_t ch)
{
bsp_gpio_deinit(g_button_port[ch], g_button_pin[ch]);
}

/**
* @brief 设置按键中断优先级(强制配置为低优先级)
* @note NULL
* @param ch: 按键号
* @retval None
*/
void bsp_button_set_irq(bsp_button_t ch)
{
bsp_exit_set(g_button_irqn[ch], PRIORITY_LOW);
}

/**
* @brief 清除按键中断优先级
* @note NULL
* @param ch: 按键号
* @retval None
*/
void bsp_button_clear_irq(bsp_button_t ch)
{
bsp_exit_clear_set(g_button_irqn[ch]);
}

/**
* @brief 得到按键状态
* @note NULL
* @param ch: 按键号
* @retval 0 -- 低电平, 1 -- 高电平
*/
bool bsp_button_get_state(bsp_button_t ch)
{
return (bool)bsp_gpio_get_state(g_button_port[ch], g_button_pin[ch]);
}

/**
* @brief 注册按键中断的回调函数
* @note NULL
* @param ch: 键号
* @param event: 绑定中断回调事件
* @retval 0--失败 1--成功
*/
bool bsp_button_irq_callback(bsp_button_t ch, void *event)
{
if (irq_callback[ch] != NULL)
{
return false;
}
else
{
irq_callback[ch] = (bsp_button_callback)event;
}
return true;
}

/**
* @brief 用于外部中断服务回调,并执行对应引脚的事件
* @note NULL
* @param gpiox: -
* @param gpio_pin: 引脚号
* @retval None
*/
static void bsp_button_exti_callback(void *gpiox, uint16_t gpio_pin)
{
#if BS_BUTTON_NUM > 0
if (gpiox == BS_BUTTON0_GPIO_PORT && gpio_pin == BS_BUTTON0_PIN && irq_callback[BSP_BUTTON_X_0] != NULL)
{
if (irq_callback[BSP_BUTTON_X_0])
{
irq_callback[BSP_BUTTON_X_0]();
}
}
#endif
#if BS_BUTTON_NUM > 1
else if (gpiox == BS_BUTTON1_GPIO_PORT && gpio_pin == BS_BUTTON1_PIN && irq_callback[BSP_BUTTON_X_1] != NULL)
{
if (irq_callback[BSP_BUTTON_X_1])
{
irq_callback[BSP_BUTTON_X_1]();
}
}
#endif
#if BS_BUTTON_NUM > 2
else if (gpiox == BS_BUTTON2_GPIO_PORT && gpio_pin == BS_BUTTON2_PIN && irq_callback[BSP_BUTTON_X_2] != NULL)
{
if (irq_callback[BSP_BUTTON_X_2])
{
irq_callback[BSP_BUTTON_X_2]();
}
}
#endif
#if BS_BUTTON_NUM > 3
else if (gpiox == BS_BUTTON3_GPIO_PORT && gpio_pin == BS_BUTTON3_PIN && irq_callback[BSP_BUTTON_X_3] != NULL)
{
if (irq_callback[BSP_BUTTON_X_3])
{
irq_callback[BSP_BUTTON_X_3]();
}
}
#endif
#if BS_BUTTON_NUM > 4
else if (gpiox == BS_BUTTON4_GPIO_PORT && gpio_pin == BS_BUTTON4_PIN && irq_callback[BSP_BUTTON_X_4] != NULL)
{
if (irq_callback[BSP_BUTTON_X_4])
{
irq_callback[BSP_BUTTON_X_4]();
}
}
#endif
#if BS_BUTTON_NUM > 5
else if (gpiox == BS_BUTTON5_GPIO_PORT && gpio_pin == BS_BUTTON5_PIN && irq_callback[BSP_BUTTON_X_5] != NULL)
{
if (irq_callback[BSP_BUTTON_X_5])
{
irq_callback[BSP_BUTTON_X_5]();
}
}
#endif
#if BS_BUTTON_NUM > 6
else if (gpiox == BS_BUTTON6_GPIO_PORT && gpio_pin == BS_BUTTON6_PIN && irq_callback[BSP_BUTTON_X_6] != NULL)
{
if (irq_callback[BSP_BUTTON_X_6])
{
irq_callback[BSP_BUTTON_X_6]();
}
}
#endif
#if BS_BUTTON_NUM > 7
else if (gpiox == BS_BUTTON7_GPIO_PORT && gpio_pin == BS_BUTTON7_PIN && irq_callback[BSP_BUTTON_X_7] != NULL)
{
if (irq_callback[BSP_BUTTON_X_7])
{
irq_callback[BSP_BUTTON_X_7]();
}
}
#endif
#if BS_BUTTON_NUM > 8
else if (gpiox == BS_BUTTON8_GPIO_PORT && gpio_pin == BS_BUTTON8_PIN && irq_callback[BSP_BUTTON_X_8] != NULL)
{
if (irq_callback[BSP_BUTTON_X_8])
{
irq_callback[BSP_BUTTON_X_8]();
}
}
#endif
#if BS_BUTTON_NUM > 9
else if (gpiox == BS_BUTTON9_GPIO_PORT && gpio_pin == BS_BUTTON9_PIN && irq_callback[BSP_BUTTON_X_9] != NULL)
{
if (irq_callback[BSP_BUTTON_X_9])
{
irq_callback[BSP_BUTTON_X_9]();
}
}
#endif
#if BS_BUTTON_NUM > 10
else if (gpiox == BS_BUTTON10_GPIO_PORT && gpio_pin == BS_BUTTON10_PIN && irq_callback[BSP_BUTTON_X_10] != NULL)
{
if (irq_callback[BSP_BUTTON_X_10])
{
irq_callback[BSP_BUTTON_X_10]();
}
}
#endif
}

#else
void bsp_button_init(void)
{
}

void bsp_button_deinit(bsp_button_t ch)
{
}

bool bsp_button_get_state(bsp_button_t ch)
{
return false;
}

bool bsp_button_irq_callback(bsp_button_t ch, void *event)
{
return false;
}

void bsp_button_exti_callback(void *gpiox, uint16_t gpio_pin)
{
}
#endif
/********************************************************************************
* @file bsp_key.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2021-04-03
* @brief bsp key
********************************************************************************/

#ifndef __BSP_KEY_H
#define __BSP_KEY_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Public enum ---------------------------------------------------------------*/
typedef enum
{
BSP_BUTTON_X_0 = 0,
BSP_BUTTON_X_1,
BSP_BUTTON_X_2,
BSP_BUTTON_X_3,
BSP_BUTTON_X_4,
BSP_BUTTON_X_5,
BSP_BUTTON_X_6,
BSP_BUTTON_X_7,
BSP_BUTTON_X_8,
BSP_BUTTON_X_9,
BSP_BUTTON_X_10
} bsp_button_t;

typedef enum
{
BUTTON_MODE_GPIO = 0,
BUTTON_MODE_EXTI = 1
} bsp_button_mode_t;

/* Public Function Prototypes ------------------------------------------------*/

void bsp_button_init(void);
void bsp_button_deinit(bsp_button_t ch);

void bsp_button_set_irq(bsp_button_t ch);
void bsp_button_clear_irq(bsp_button_t ch);

bool bsp_button_get_state(bsp_button_t ch);

bool bsp_button_irq_callback(bsp_button_t ch, void *event);

#endif


标签:cx32l003,BUTTON,endif,bsp,单片机,NUM,BS,button
From: https://blog.51cto.com/xuejianqiang/5810866

相关文章