3. MCU上运行第一个CMSIS-NN示例
任务目标
在MCU上实现一个按键输入检测程序:通过轮询方式读取按键GPIO状态,检测按下与释放动作,并控制LED的亮灭切换。每次按下按键时LED状态翻转一次,松开时不重复触发。
硬件连接
- 按键一端接GPIO(本例使用PA0),另一端接GND(低电平有效)
- LED正极经限流电阻接GPIO(本例使用PC13),负极接GND
- MCU内部启用PA0上拉电阻,未按下时读到高电平,按下时读到低电平
完整代码(STM32 HAL库)
// main.c 核心逻辑(基于STM32F103C8T6,HAL库)
#include "main.h"
GPIO_InitTypeDef GPIO_InitStruct = {0};
void GPIO_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
// PA0 按键输入,上拉
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// PC13 LED输出
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 初始LED灭
}
int main(void) {
HAL_Init();
GPIO_Init();
uint8_t last_button_state = 1; // 上一次按键状态(1=未按下)
uint8_t current_button_state;
while (1) {
current_button_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
// 检测下降沿:未按下(1) → 按下(0)
if (last_button_state == 1 && current_button_state == 0) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}
last_button_state = current_button_state;
HAL_Delay(10); // 简单消抖,10ms轮询间隔
}
}
编译与烧录
- 使用STM32CubeIDE新建项目,选择芯片STM32F103C8T6
- 将上述代码替换main.c中对应内容(保留HAL_Init和时钟配置)
- 编译生成.hex文件,通过ST-Link烧录到开发板
验证方法
- 初始状态:上电后LED处于熄灭状态
- 按下按键:LED应立即点亮;松开按键,LED保持点亮
- 再次按下:LED熄灭;松开后保持熄灭
- 判定通过:每次按下按键LED状态翻转一次,且按住不松开时不会连续翻转(仅触发一次)
关键说明
- 轮询间隔10ms兼作软件消抖,可滤除大部分机械抖动;若按键抖动明显,可增大到20ms
- 检测下降沿(1→0)而非电平本身,确保一次按下只触发一次翻转
- 若按键接法为高电平有效(另一端接VCC),需将Pull改为GPIO_PULLDOWN,并将检测条件改为上升沿(0→1)