尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

STM32F103C8T6 HAL 库按键中断控制流水灯

STM32F103C8T6 HAL 库按键中断控制流水灯 STM32F103C8T6 HAL 库按键中断控制流水灯实验报告文章目录STM32F103C8T6 HAL 库按键中断控制流水灯实验报告一、实验目的二、实验任务三、实验环境与器件3.1 软件环境3.2 硬件器件四、硬件连接五、实验原理5.1 GPIO 输出控制5.2 按键外部中断5.3 按键消抖5.4 流水灯计时5.5 暂停与继续六、关键程序代码6.1 系统时钟配置6.2 GPIO 和外部中断初始化6.3 按键中断回调6.4 主循环七、实验结果一、实验目的掌握 STM32F103C8T6 的 GPIO 推挽输出配置方法。掌握 HAL 库中 GPIO 初始化、输出控制和延时计时函数的使用。掌握外部中断 EXTI、NVIC 和中断回调函数的基本工作原理。使用 PB1 按键外部中断控制流水灯的暂停和继续。二、实验任务在前面流水灯实验的基础上使用 STM32 HAL 库和按键外部中断实现以下功能PA0、PA3、PC13 三只 LED 轮流点亮每只 LED 点亮时间约为 1 秒按下 PB1 按键后流水灯暂停并保持当前 LED 状态再次按下 PB1 按键后流水灯继续运行。本实验采用按键下降沿中断方式不在主循环中不断查询按键状态。三、实验环境与器件3.1 软件环境Keil µVision5ARMCC V5.06 编译器STM32CubeF1 HAL 库Keil.STM32F1xx_DFP 器件支持包ST-Link 下载器。3.2 硬件器件STM32F103C8T6 最小系统核心板一块LED 两只330 Ω1 kΩ 限流电阻两只按键一个面包板和杜邦线若干ST-Link 下载器一个。四、硬件连接功能STM32 引脚接线方式有效电平LED1PA0PA0 → 限流电阻 → LED → GND高电平点亮LED2PA3PA3 → 限流电阻 → LED → GND高电平点亮板载 LEDPC13核心板内部已连接 LED低电平点亮按键PB1PB1 → 按键 → GND低电平有效PB1 使用 GPIO 内部上拉。按键没有按下时PB1 为高电平按键按下时PB1 被拉低因此产生下降沿。PC13 板载 LED 的驱动电平与普通外接 LED 相反PC13 输出低电平时 LED 点亮输出高电平时 LED 熄灭。五、实验原理5.1 GPIO 输出控制将 PA0、PA3、PC13 配置为通用推挽输出通过 HAL 库函数控制输出电平HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);/* PA0 输出高电平 */HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);/* PA0 输出低电平 */HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);/* PC13 输出低电平 */HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);/* PC13 输出高电平 */PA0 和 PA3 输出高电平时点亮PC13 输出低电平时点亮。5.2 按键外部中断PB1 配置为下降沿触发中断GPIO_InitStruct.PinGPIO_PIN_1;GPIO_InitStruct.ModeGPIO_MODE_IT_FALLING;GPIO_InitStruct.PullGPIO_PULLUP;HAL_GPIO_Init(GPIOB,GPIO_InitStruct);PB1 对应 EXTI1 中断线因此需要使能HAL_NVIC_SetPriority(EXTI1_IRQn,0U,0U);HAL_NVIC_EnableIRQ(EXTI1_IRQn);当按键按下时程序进入voidEXTI1_IRQHandler(void){HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);}HAL_GPIO_EXTI_IRQHandler()会清除中断标志并调用用户编写的回调函数voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin)5.3 按键消抖机械按键在按下和松开的瞬间会产生抖动如果直接处理中断可能被误认为按了很多次。本实验没有在中断中使用HAL_Delay()而是比较两次按键的时间if((now_tick-last_press_tick)200U)只有在距离上一次有效按键超过 200 ms 时才认为本次按键有效并将key_event置为 1。5.4 流水灯计时程序在主循环中使用HAL_GetTick()判断时间而不使用阻塞延时代码。if((HAL_GetTick()-last_change_tick)1000U)HAL_GetTick()返回当前系统启动后的毫秒数时间差达到 1000 ms 时切换下一只 LED。这样的写法不会长时间阻塞主程序按键中断也可以及时响应。5.5 暂停与继续程序使用变量running表示运行状态running 1流水灯运行running 0流水灯暂停。每次按下 PB1中断回调置位key_event主循环检测到事件后将running取反running(running0U)?1U:0U;当running 0时主循环不改变 LED 输出状态因此当前 LED 保持点亮再次按下 PB1 后恢复流水灯切换。六、关键程序代码6.1 系统时钟配置本实验使用内部 HSI 8 MHz不依赖外部晶振。staticvoidSystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct{0};RCC_ClkInitTypeDef RCC_ClkInitStruct{0};RCC_OscInitStruct.OscillatorTypeRCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIStateRCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValueRCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLStateRCC_PLL_NONE;if(HAL_RCC_OscConfig(RCC_OscInitStruct)!HAL_OK){Error_Handler();}RCC_ClkInitStruct.ClockTypeRCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSourceRCC_SYSCLKSOURCE_HSI;RCC_ClkInitStruct.AHBCLKDividerRCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDividerRCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDividerRCC_HCLK_DIV1;if(HAL_RCC_ClockConfig(RCC_ClkInitStruct,FLASH_LATENCY_0)!HAL_OK){Error_Handler();}}6.2 GPIO 和外部中断初始化staticvoidMX_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct{0};__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_AFIO_CLK_ENABLE();/* 初始状态熄灭 LED */HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP;GPIO_InitStruct.PullGPIO_NOPULL;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;GPIO_InitStruct.PinGPIO_PIN_0;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);GPIO_InitStruct.PinGPIO_PIN_3;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);GPIO_InitStruct.PinGPIO_PIN_13;HAL_GPIO_Init(GPIOC,GPIO_InitStruct);/* PB1 按键下降沿中断 */GPIO_InitStruct.PinGPIO_PIN_1;GPIO_InitStruct.ModeGPIO_MODE_IT_FALLING;GPIO_InitStruct.PullGPIO_PULLUP;HAL_GPIO_Init(GPIOB,GPIO_InitStruct);HAL_NVIC_SetPriority(EXTI1_IRQn,0U,0U);HAL_NVIC_EnableIRQ(EXTI1_IRQn);}6.3 按键中断回调voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){staticuint32_tlast_press_tick0U;uint32_tnow_tick;if(GPIO_PinGPIO_PIN_1){now_tickHAL_GetTick();if((now_tick-last_press_tick)200U){last_press_ticknow_tick;key_event1U;}}}6.4 主循环while(1){if(key_event!0U){key_event0U;running(running0U)?1U:0U;last_change_tickHAL_GetTick();}if(running0U){last_change_tickHAL_GetTick();continue;}if((HAL_GetTick()-last_change_tick)1000U){last_change_tickHAL_GetTick();HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);if(step0U){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);}elseif(step1U){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);}step;if(step3U){step0U;}}}七、实验结果受帧率问题本gif动图并不能很好体现实验结果详情请看视频内容
返回列表