首页 / 资讯中心 / 文章详情

STM32定时器与PWM控制LED

STM32定时器与PWM控制LED ★ FEATURED ARTICLE
STM32定时器与PWM控制LED一、实验目的深入了解 STM32 定时器的工作原理掌握定时器中断的配置与使用。掌握脉宽调制PWM的生成方法理解占空比与输出平均电压的关系。熟练使用 STM32CubeMX 与 Keil MDK 进行嵌入式程序开发掌握 DAP-Link 仿真器下载与调试流程。二、实验环境硬件STM32F103C8T6 最小核心板、DAP-Link 调试器、LED 灯、限流电阻、杜邦线若干。软件STM32CubeMX、Keil MDK-ARM V5、STM32F1xx 芯片支持包。三、实验原理3.1 定时器中断STM32 通用定时器TIM2~TIM5的核心是一个 16 位可编程预分频器和一个 16 位自动重装载寄存器。定时器溢出时间公式为T (PSC 1) * (ARR 1) / Tclk通过配置 PSC预分频和 ARR自动重装载值可以精准控制定时器产生中断的频率。3.2 PWM脉冲宽度调制PWM 是一种对模拟信号电平进行数字编码的方法。在 STM32 中通过定时器的比较寄存器CCR来控制输出高电平的时间。占空比 CCR / (ARR 1)。通过动态改变 CCR 的值即可改变 LED 的平均电压从而实现呼吸灯效果。四、实验内容与步骤4.1 硬件连接DAP-Link 的3.3V、GND、SWCLK、SWDIO分别与核心板的3.3V、GND、PA14、PA13相连。LED 正极串联限流电阻后接PA0TIM2_CH1负极接GND。4.2 实验一定时器中断实现 2 秒周期亮灭4.2.1 CubeMX 配置配置 RCC 外部晶振时钟树 HCLK 设为 72MHz。在芯片图上将PA0配置为GPIO_Output注意不配置此项会导致引脚无法输出电平。TIM2 配置Prescaler 7199Counter Period 9999。使能 TIM2 全局中断NVIC Settings。4.2.2 核心代码在main.c中启动定时器中断并在回调函数中每 2 次中断翻转一次电平/* USER CODE BEGIN 2 */// 启动定时器中断HAL_TIM_Base_Start_IT(htim2);/* USER CODE END 2 *//* USER CODE BEGIN 4 */// 定时器中断回调函数voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){staticuint32_tcount0;if(htim-InstanceTIM2)// 判断是TIM2触发的中断{count;if(count2)// 定时器每1秒触发一次每2秒翻转一次电平{count0;HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);// 翻转PA0电平}}}/* USER CODE END 4 */4.2.3 Keil 魔术棒配置与程序烧录在编译成功0 Errors后需要通过 DAP-Link 将程序下载到核心板具体设置如下点击 Keil 顶部的魔术棒图标Options for Target。切换到Debug标签页在Use:下拉框中选择CMSIS-DAP Debugger。点击右侧的Settings确认Port为SW且能识别到芯片 IDCODE。切换到Flash Download标签页务必勾选Reset and Run这样烧录完成后单片机才会自动复位并开始运行程序。点击DownloadF8烧录程序。4.2.4 实验结果烧录程序后观察到外接 LED 以 2 秒为周期稳定闪烁。LED14.3 实验二PWM 呼吸灯4.3.1 CubeMX 配置在 TIM2 的 Channel1 选择PWM Generation CH1。参数设为Prescaler 71Counter Period 99。此时 PWM 频率为 10kHz人眼看不到闪烁。4.3.2 核心代码在while(1)循环中利用HAL_GetTick()实现非阻塞延时平滑改变占空比/* USER CODE BEGIN 2 */// 启动PWM输出HAL_TIM_PWM_Start(htim2,TIM_CHANNEL_1);/* USER CODE END 2 *//* USER CODE BEGIN WHILE */uint32_tpulse0;// 当前占空比 (CCR的值)uint32_tstep1;// 每次变化的步进值uint8_tdir1;// 1代表渐亮0代表渐暗uint32_tlast_tick0;// 用于非阻塞延时while(1){// 每10ms改变一次占空比实现平滑呼吸if(HAL_GetTick()-last_tick10){last_tickHAL_GetTick();// 更新时间标志位if(dir1)// 渐亮过程{pulsestep;if(pulse99)// 达到最亮{pulse99;dir0;// 切换为渐暗}}else// 渐暗过程{pulse-step;if(pulse0)// 达到最暗{pulse0;dir1;// 切换为渐亮}}// 将计算出的占空比写入寄存器__HAL_TIM_SET_COMPARE(htim2,TIM_CHANNEL_1,pulse);}/* USER CODE END WHILE */4.3.3 Keil 魔术棒配置与程序烧录点击魔术棒图标Options for Target-Debug标签页确认Use:依然是CMSIS-DAP Debugger。确保Flash Download标签页中的Reset and Run仍然处于勾选状态。点击DownloadF8烧录程序。4.3.4 实验结果烧录程序后LED 呈现逐渐变亮再逐渐变暗的“呼吸”效果过渡平滑无闪烁感。LED24.4 Keil 虚拟示波器波形观察为了直观验证 PWM 波形我们在 Keil 中进入软件仿真模式。注意此时需将魔术棒 Debug 页中的 Use 从 CMSIS-DAP 改为Use Simulator。在 Logic Analyzer 中添加PORTA.0引脚。波形分析在虚拟示波器中可以清晰地看到随着程序的运行方波的高电平脉宽逐渐变宽随后又逐渐变窄完美对应了呼吸灯的渐亮与渐暗过程。五、心得体会这次从零开始完成 STM32 定时器与 PWM 实验对我来说是一次既充满挫败感又极具成就感的经历。在刚开始动手时面对密密麻麻的引脚图和一堆陌生的专业术语我其实非常迷茫。按照教程一步步配置 CubeMX、生成代码、编译烧录原以为会像写高级语言那样点个运行就能看到结果结果却遇到了“灯不亮”的尴尬局面。在排查问题的过程中我深刻体会到了硬件开发的严谨性原来要在 CubeMX 里不仅要配置定时器还得把对应引脚PA0的模式设置为GPIO_Output否则它就一直处于浮空状态根本无法驱动 LED原来在 Keil 里下载完程序如果没勾选魔术棒里的Reset and Run或者忘了按复位键芯片就会一直卡在复位状态不往下跑。这些细枝末节的“坑”让我真正认识到了软件逻辑与硬件物理状态之间必须通过正确的配置来建立桥梁。到了实验二的 PWM 呼吸灯部分更是让我惊叹于定时器的强大。用软件延时HAL_Delay会阻塞程序改用HAL_GetTick()做非阻塞延时后主循环变得非常流畅。看着 LED 灯按照代码的逻辑一点点变亮达到顶峰后又缓缓熄灭就像赋予了这块冰冷的开发板生命一样那一刻的喜悦难以言表。而最后利用 Keil 的虚拟示波器功能看着屏幕上跳动的方波脉宽随着呼吸灯的变化而不断变宽变窄理论与实践在此刻完美重合。这次实验不仅让我掌握了 CubeMX 和 Keil 的联合开发流程更治好了我“眼高手低”的毛病。嵌入式开发绝不是敲几行代码那么简单它需要你耐心地检查每一根杜邦线、反复确认每一个寄存器参数甚至连魔术棒里的一个小勾选都能决定实验的成败。遇到 Bug 不要慌去查芯片手册、去分析时钟树、去利用仿真工具观察波形这才是工程师应该具备的素养。未来我还想尝试用定时器控制电机转速去探索嵌入式世界里更多的奇妙可能。
阅读完成 · 觉得有帮助?
咨询建站