目录
一、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);
}
}
三、踩坑日记
好文阅读
发表评论