选择PWM输出引脚
根据自己的电路,选择pwm输出引脚,图中PB6和PB7为板子空闲引脚,且可以复用为PWM功能。
CubeMX中配置
根据选择的引脚,在CubeMX配置,选择TIM4中的Channal1和Channal2输出PWM。
计算分频
PWM频率 = 定时器频率/(分频系数 x 自动重装载值)
PWM占空比 = CCRx / 自动重装载值。
period = CLOCK/Freq -1;
pulse = (period+1)*Dutycycle / 100;
首先查看TIM4的时钟频率,TIM4挂载在APB1 TIMer clocks上,时钟是84M。在PreScaler中填入84-1,先分频为1M。本文需要1000HZ的波形周期,所以计数值为1M/1000HZ得到计数值为1000,并将1000-1填入counter period中。打开自动重装载。
注:STM32F4系列中各总线挂载的定时器
APB2:TIM1、TIM8、TIM9-11
APB1:其他定时器
在NVIC中打开TIM4中断
添加控制引脚
电机驱动板需要控制引脚控制电机正反转,因此,在CubeMX中添加连个控制引脚PC0和PC1。设置为输出模式
添加PWM任务
在Freertos中添加一个myStart_PWM任务,并生成代码。
修改应用程序
补充:读写定时器相关值的函数.
__HAL_TIM_SetAutoreload: 设置重装载值
__HAL_TIM_GetAutoreload: 获取当前重装载值
__HAL_TIM_SetCounter:设置计数值
__HAL_TIM_GetCounter:获取当前计数值
__HAL_TIM_SetCompare:设置比较值
__HAL_TIM_GetCompare: 获取当前比较值
修改StartTask_PWM任务
void StartTask_PWM(void const * argument)
{
//打开PWM
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);
//打开控制引脚
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
//设置占空比
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_1,800);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_2,200);
for(;;)
{
//重装载
osDelay(1000);
}
/* USER CODE END StartTask_PWM */
}
编译,此刻提示编译错误,htim4为找到
在该文件前加入extern TIM_HandleTypeDef htim4;
连接电路,上电测试
踏坑:在CubeMX中生成的代码中,main函数中做了MX_TIM4_Init(),让我误认为PWM已经打开了。经过大量时间,还需自行打开PWM,由于手头没有示波器,花了大量时间排查。
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);