【STM32F429】HAL库的PWM中断,精确控制脉冲数,控制步进电机

这两天在调步进电机,希望是使得步进电机每次都达到期望的高度。在查了一天的资料,发现大部分上传的资料都是使用CubeMX生成的,可复制性很高,但未免有失可读性,故上传我的心得经验。

本来原子哥的例程里有整合度很高的,已经封装好的精确控制步进电机前进距离的函数。无奈例程使用了高级定时器TIM8,TIM8需要复用的引脚会影响到CAN的通讯,无奈自行研究,最终决定通过PWM中断,计数脉冲数,以此实现精确控制步进电机的步距角。

话不多说,先谈谈我遇到的坑吧,我个人算是新手,所以在一开始调步进电机时,连初始化和基本步骤都不是很明白,所以下文会从最基础的地方开始。

第一次我选择了定时器4的通道2作为PWM的输出口,然而很快我就发现了TIM4_ CHANNEL2的对应引脚是PD13,复用了PD13 作为PWM输出口后,步进电机出现了上下乱移,不受程序控制的情况,无奈作罢。

第二次,我选择了定时器4通道1,引脚是PD12。于是进入了正常设置环节,

第一个Driverinit,初始化了PF7,PF9作为编码器的DIR+,和DIR-来控制方向。具体可参见备注。

第二个是定时器中断处理函数,调用的是TIM4的句柄。

第三个是TIM4的PWM波初始化。

其中关于2,3点的理解出了偏差,这是我踩得最大的坑!!!没有之一!!!

首先我要强调的是HAL_TIM_PWM_StartHAL_TIM_PWM_Start_IT的区别。在我的理解中,使用前者只能成功设置时钟输出PWM波,而不能调用中断。而后者才是时钟中断

STM32控制器上使用HAL实现PWM中断的回调函数,主要涉及定时器的配置以及中断服务程序的编写。HAL提供了一套标准的API来配置PWM输出,并支持中断机制,使得用户可以在中断触发时执行自定义的回调函数。 ### 1. 配置定时器为PWM模式 首先,需要通过STM32CubeMX或手动配置定时器(如TIMx)为PWM输出模式。配置时应指定以下参数: - **Channel**:选择使用的通道(如TIM_CHANNEL_1) - **Counter Mode**:计数模式(向上计数、向下计数或中央对齐模式) - **Period**:自动重载寄存器(ARR)的值,决定PWM周期 - **Prescaler**:预分频器值,决定定时器时钟分频 - **Compare Value**:比较寄存器(CCR)的值,决定占空比 例如,使用HAL初始化PWM通道的代码如下: ```c htim3.Instance = TIM3; htim3.Init.Prescaler = 83; // 84MHz / (83+1) = 1MHz htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; // 1MHz / (999+1) = 1kHz htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); ``` ### 2. 启用中断并配置NVIC 在CubeMX中启用定时器的更新中断(Update Interrupt)或捕获/比较中断(Capture/Compare Interrupt),并设置优先级。生成代码后,会自动添加以下NVIC配置代码: ```c HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM3_IRQn); ``` ### 3. 实现中断回调函数 HAL提供了`HAL_TIM_PeriodElapsedCallback()`函数作为定时器更新中断的回调函数。该函数在中断服务程序中被调用。用户可以在该函数中实现自定义逻辑。 ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim3) { // 自定义PWM中断处理逻辑 // 例如:切换LED状态 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); } } ``` ### 4. 完整的中断服务程序(ISR) HAL会自动生成中断服务程序,并调用`HAL_TIM_IRQHandler()`来处理中断事件。确保在`stm32f7xx_it.c`中保留以下代码: ```c void TIM3_IRQHandler(void) { HAL_TIM_IRQHandler(&htim3); } ``` ### 5. 示例:PWM中断控制LED闪烁 以下是一个完整的示例,展示如何使用PWM中断控制LED以特定频率闪烁: ```c // main.c 中的初始化部分 MX_TIM3_Init(); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_TIM_Base_Start_IT(&htim3); // 启动定时器中断 // 回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim3) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 每次中断翻转LED状态 } } ``` ### 注意事项 - 确保定时器的时钟源正确配置,通常来自APB1或APB2总线。 - 若使用多个通道,需在回调函数中判断具体是哪个定时器触发了中断。 - 若需要在特定比较事件(如通道匹配)时触发中断,可使用`HAL_TIM_IC_CaptureCallback()`或`HAL_TIM_OC_DelayElapsedCallback()`等回调函数[^1]。 ---
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值