目录

一、User_Key

(1)原理图

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

二、User_Key 接口函数封装

三、踩坑日记

一、User_Key

(1)原理图

        在蓝桥杯物联网竞赛实训平台中,每个节点都有一个 User_Key,即 S1;

        ️User_Key 原理图如图1所示:

        S1 上方连接着 10K 电阻(上拉电阻)、节点电源 VDD_NODE_A、引脚 PC14,下方接地。

当按键按下时,引脚 PC14 与 GND 连接导通,读取到低电平;当按键抬起时,引脚 PC14 与 VDD_NODE_A 连接导通,读取到高电平;

图1        User_Key 电路原理图

(2)STM32CubeMX 软件配置

“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出  一文中有讲解,这里不再赘述❗️

1️⃣点击引脚 PC14 → 选择 GPIO_Input 模式(此处默认不配置上拉电阻和下拉电阻,由于按键电路已经带有上拉电阻,故不修改相关配置);

图2        按键引脚配置

2️⃣点击引脚 PC15 → 选择 GPIO_Output 模式(此处默认为推挽输出);

图3        LD5引脚配置

3️⃣点击 "GPIO" → 点击引脚 PC15 → 将 "GPIO output level" 栏修改为 "High",即将 PC15 引脚初始化为高电平;

⚠️此处修改不是必须的,应当根据题意要求进行配置,这里默认为上电熄灭;

图4        PC15引脚初始化配置

4️⃣生成代码即可;

(3)代码编写

️main函数

/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14) == 0) // 第一次判断引脚电平,若按下则为低电平,进入if

{

HAL_Delay(10); // 延时10ms,按键消抖

if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14) == 0) // 第二次判断引脚电平,排除抖动影响

{

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15); // LD5电平翻转

while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14) == 0); // 按键抬手检测,松开按键后退出

}

}

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

注意:这种写法需要添加按键抬手检测,即

while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14) == 0);

如果不添加,当按键按下后,引脚 PC14 读取到低电平,在短时间内会重复进入到逻辑判断中,而导致逻辑功能重复触发;如果添加,在按键按下处于低电平的这段时间,CPU 会卡在 while 循环中,只有当按键抬起后,才会退出 while 循环,从而避免了逻辑功能多次触发;

(4)实验现象

按键按下,LD5 状态取反

二、User_Key 接口函数封装

️User_Key 接口函数

/**

* @brief Key_Read

* @param None

* @retval key_value 读取到按键按下 - 返回 1

* 未读取到按键按下 - 返回 0

*/

uint8_t Key_Read(void)

{

uint8_t key_value = 0; // 中间变量,存储按键状态

if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14) == 0) // 引脚状态读取

key_value = 1; // 读取到按键按下 - 返回 1

else

key_value = 0; // 未读取到按键按下 - 返回 0

return key_value;

}

User_Key 接口函数调用实例

/* 按键任务处理函数 */

void Task_Key(void)

{

uint8_t key_temp, key_down;

static uint8_t key_old = 0;

/* 每10ms进入一次 */

if(cnt_10ms < 10) return;

cnt_10ms = 0;

/* 三行代码 */

key_temp = Key_Read(); // 键值读取

key_down = key_temp & (key_temp ^ key_old); // 下降沿判断

key_old = key_temp; // 键值存储

/* 下降沿逻辑 */

if(key_down)

{

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);

}

}

三、踩坑日记

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: