|
|
@@ -708,25 +708,29 @@ void PLSR_Route_PWM_Stop() |
|
|
|
*/ |
|
|
|
void PLSR_PWM_SetFrequency(uint32_t frequency) |
|
|
|
{ |
|
|
|
uint16_t prescaler = 0; // 预分频器值 |
|
|
|
uint32_t period = 0; // 自动重载值(周期) |
|
|
|
uint32_t ccr = 0; |
|
|
|
uint16_t prescaler = 0; ///< 预分频器值 |
|
|
|
uint32_t period = 0; ///< 自动重载值(周期) |
|
|
|
uint32_t ccr = 0; ///< 比较寄存器值 |
|
|
|
|
|
|
|
// 频率范围检查 - 确保频率在1hz到100khz范围内 |
|
|
|
/* 频率范围检查 - 确保频率在有效范围内 */ |
|
|
|
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX) |
|
|
|
{ |
|
|
|
return; // 频率超出范围,直接返回,不做任何修改 |
|
|
|
return; ///< 频率超出范围,直接返回,不做任何修改 |
|
|
|
} |
|
|
|
|
|
|
|
// 计算最佳定时器参数 - 根据目标频率计算预分频器和周期值 |
|
|
|
/* 计算最佳定时器参数 - 根据目标频率计算预分频器和周期值 */ |
|
|
|
PLSR_CalculateTimerParams(frequency, &prescaler, &period); |
|
|
|
ccr = (period + 1) / 2; |
|
|
|
PLSR_Fix_Compensated(frequency,&ccr); |
|
|
|
// 参数有效性检查 - 防止period为0导致除零错误 |
|
|
|
|
|
|
|
/* 参数有效性检查 - 防止period为0导致除零错误 */ |
|
|
|
if(period == 0) |
|
|
|
{ |
|
|
|
return; // period无效,直接返回,避免HardFault异常 |
|
|
|
return; ///< period无效,直接返回,避免HardFault异常 |
|
|
|
} |
|
|
|
|
|
|
|
/* 安全计算CCR值,使用64位避免溢出 */ |
|
|
|
uint64_t ccr_temp = ((uint64_t)period + 1ULL) / 2ULL; |
|
|
|
ccr = (uint32_t)ccr_temp; |
|
|
|
PLSR_Fix_Compensated(frequency, &ccr); |
|
|
|
// 根据output_port选择目标定时器并更新参数 |
|
|
|
switch(PlsrRoute.output_port) |
|
|
|
{ |
|
|
@@ -778,25 +782,32 @@ void PLSR_PWM_SetFrequency(uint32_t frequency) |
|
|
|
*/ |
|
|
|
void PLSR_TIM6_SetUpdateFreq(uint32_t freq_us) |
|
|
|
{ |
|
|
|
// 保存新的频率设置 |
|
|
|
/* 参数有效性检查 */ |
|
|
|
if (freq_us == 0) freq_us = 1; ///< 防止除零错误 |
|
|
|
if (freq_us > 65535) freq_us = 65535; ///< 限制最大周期值 |
|
|
|
|
|
|
|
/* 保存新的频率设置 */ |
|
|
|
s_tim6_update_freq_us = freq_us; |
|
|
|
|
|
|
|
// 定时器时钟参数 (基于STM32F4系列APB1时钟配置) |
|
|
|
// APB1时钟频率:42MHz 定时器二倍频 |
|
|
|
uint32_t target_period_us = freq_us; // 目标周期(微秒) |
|
|
|
/* 定时器时钟参数 (基于STM32F4系列APB1时钟配置) */ |
|
|
|
/* APB1时钟频率:42MHz 定时器二倍频到84MHz */ |
|
|
|
uint32_t target_period_us = freq_us; ///< 目标周期(微秒) |
|
|
|
|
|
|
|
/* 计算定时器参数 */ |
|
|
|
/* 预分频器设为83,使计数频率为84MHz/(83+1) = 1MHz,即1us/tick */ |
|
|
|
uint16_t prescaler = 83; ///< 预分频器值,产生1MHz计数频率 |
|
|
|
uint32_t period = target_period_us - 1; ///< 自动重载值,减1是因为从0开始计数 |
|
|
|
|
|
|
|
// 计算定时器参数 |
|
|
|
// 预分频器设为41,使计数频率为84MHz/(83+1) = 1MHz,即1us/tick |
|
|
|
uint16_t prescaler = 83; // 预分频器值,产生1MHz计数频率 |
|
|
|
uint32_t period = target_period_us - 1; // 自动重载值,减1是因为从0开始计数 |
|
|
|
/* 确保period在有效范围内 */ |
|
|
|
if (period > 65535) period = 65535; ///< 限制ARR最大值 |
|
|
|
|
|
|
|
// 停止TIM6中断 - 避免参数更新过程中的中断干扰 |
|
|
|
/* 停止TIM6中断 - 避免参数更新过程中的中断干扰 */ |
|
|
|
HAL_TIM_Base_Stop_IT(&htim6); |
|
|
|
|
|
|
|
// 更新TIM6核心参数 |
|
|
|
__HAL_TIM_SET_PRESCALER(&htim6, prescaler); // 设置预分频器 |
|
|
|
__HAL_TIM_SET_AUTORELOAD(&htim6, period); // 设置自动重载值(决定更新频率) |
|
|
|
__HAL_TIM_SET_COUNTER(&htim6, 0); // 重置计数器到初始状态 |
|
|
|
/* 更新TIM6核心参数 */ |
|
|
|
__HAL_TIM_SET_PRESCALER(&htim6, prescaler); ///< 设置预分频器 |
|
|
|
__HAL_TIM_SET_AUTORELOAD(&htim6, period); ///< 设置自动重载值(决定更新频率) |
|
|
|
__HAL_TIM_SET_COUNTER(&htim6, 0); ///< 重置计数器到初始状态 |
|
|
|
|
|
|
|
// 触发更新事件 - 立即将新参数加载到影子寄存器 |
|
|
|
HAL_TIM_GenerateEvent(&htim6, TIM_EVENTSOURCE_UPDATE); |
|
|
|