Kaynağa Gözat

修改数据类型临时提交

2
JIU JIALIN 4 hafta önce
ebeveyn
işleme
855663f1fa
14 değiştirilmiş dosya ile 3911 ekleme ve 3867 silme
  1. +16
    -2
      PLSR/PLSR/Core/Inc/tim.h
  2. +34
    -23
      PLSR/PLSR/Core/Src/tim.c
  3. +23
    -13
      PLSR/PLSR/Core/Src/tools.c
  4. +439
    -439
      PLSR/PLSR/EWARM/test.1.dep
  5. +2756
    -2747
      PLSR/PLSR/EWARM/test.1/Exe/test.1.hex
  6. BIN
      PLSR/PLSR/EWARM/test.1/Exe/test.1.out
  7. BIN
      PLSR/PLSR/EWARM/test.1/Exe/test.1.sim
  8. +643
    -643
      PLSR/PLSR/EWARM/test.1/List/test.1.map
  9. BIN
      PLSR/PLSR/EWARM/test.1/Obj/gpio.o
  10. BIN
      PLSR/PLSR/EWARM/test.1/Obj/main.o
  11. BIN
      PLSR/PLSR/EWARM/test.1/Obj/modbus_log.o
  12. BIN
      PLSR/PLSR/EWARM/test.1/Obj/tim.o
  13. BIN
      PLSR/PLSR/EWARM/test.1/Obj/tools.o
  14. BIN
      PLSR/PLSR/EWARM/test.1/Obj/usart.o

+ 16
- 2
PLSR/PLSR/Core/Inc/tim.h Dosyayı Görüntüle

@@ -107,6 +107,17 @@ typedef enum {
PLSR_DIR_FORWARD = 0, // 正向
PLSR_DIR_REVERSE = 1 // 反向
} PLSR_Direction_t;

/**
* @brief PLSR错误代码枚举
*/
typedef enum {
PLSR_ERROR_NONE = 0, ///< 无错误
PLSR_ERROR_FREQ_OUT_OF_RANGE = 1, ///< 频率超出范围
PLSR_ERROR_PARAM_CALC_FAILED = 2, ///< 参数计算失败
PLSR_ERROR_TIMER_CONFIG_FAILED = 3, ///< 定时器配置失败
PLSR_ERROR_HARDWARE_FAULT = 4 ///< 硬件故障
} PLSR_ErrorCode_t;
/* USER CODE END Private defines */

void MX_TIM2_Init(void); // TIM2恢复用于脉冲计数
@@ -168,7 +179,7 @@ typedef struct
uint32_t freq_step; ///< 频率步长
uint32_t default_freq; ///< 脉冲默认速度

uint64_t pulse_count; ///< 当前脉冲计数
int64_t pulse_count; ///< 当前脉冲计数(支持正负值)
int64_t prevPulseCount; ///< 上阶段目标脉冲
int64_t accel_pulse_count; ///< 第一部分脉冲数(可能是加速、减速或匀速)
int64_t const_pulse_count; ///< 第二部分脉冲数(匀速)
@@ -203,6 +214,7 @@ typedef struct
uint8_t ext_port; ///< 外部事件端口选择
uint8_t dir_port; ///< 方向端口选择
uint8_t current_part; ///< 当前执行部分:1-第一部分,2-第二部分,3-第三部分
PLSR_ErrorCode_t error_code; ///< 错误代码
} PLSR_RouteConfig_t;

// 三部分执行状态枚举
@@ -227,7 +239,7 @@ void PLSR_PWM_Init(void);
void PLSR_PWM_Start(void);
void PLSR_Section_PWM_Stop(void);
void PLSR_Route_PWM_Stop();
void PLSR_PWM_SetFrequency(uint32_t frequency);
uint8_t PLSR_PWM_SetFrequency(uint32_t frequency);
void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, uint32_t* period);
void PLSR_Fix_Compensated(uint32_t frequency, uint32_t* ccr);

@@ -278,6 +290,8 @@ extern PLSR_RouteConfig_t PlsrRoute; // 全局PLSR路径控制结构体
extern uint8_t PlsrExtEventFlag; // 外部事件标志
extern int64_t PlsrTotalPulseCount; // 全局累加脉冲计数器(程序运行期间持续累加,支持负数)
extern int64_t PlsrLocation;
extern volatile uint8_t PlsrFreqUpdateRequest; // 频率更新请求标志(中断安全)
extern volatile uint32_t PlsrPendingFreq; // 待更新的频率值(中断安全)
/* USER CODE END Prototypes */

#ifdef __cplusplus


+ 34
- 23
PLSR/PLSR/Core/Src/tim.c Dosyayı Görüntüle

@@ -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);


+ 23
- 13
PLSR/PLSR/Core/Src/tools.c Dosyayı Görüntüle

@@ -20,34 +20,44 @@ void PLSR_Fix_Compensated(uint32_t frequency, uint32_t* ccr)
* @param prescaler: 预分频器值指针
* @param period: 周期值指针
* @retval None
* @note 根据目标频率计算TIM10的预分频器和周期值
* @note 根据目标频率计算定时器的预分频器和周期值,使用64位数据类型避免高频时溢出
*/
void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, uint32_t* period)
{
/* 参数有效性检查 */
if (frequency < PLSR_PWM_FREQ_MIN) frequency = PLSR_PWM_FREQ_MIN;
if (frequency > PLSR_PWM_FREQ_MAX) frequency = PLSR_PWM_FREQ_MAX;
uint32_t timer_clock = 0;
/* 使用64位数据类型避免高频计算时的溢出 */
uint64_t timer_clock = 0;
if(PlsrRoute.output_port == 0 || PlsrRoute.output_port == 1)
{
timer_clock = 168000000UL; // TIM10/TIM11时钟 (APB2 84MHz)
timer_clock = 168000000ULL; ///< TIM10/TIM11时钟 (APB2 168MHz)
}
else
{
timer_clock = 84000000UL; // TIM13/TIM14时钟 (APB1 42MHz)
timer_clock = 84000000ULL; ///< TIM13/TIM14时钟 (APB1 84MHz)
}
uint32_t divider = (timer_clock + frequency / 2) / frequency; // 四舍五入
if (divider < 2) divider = 2; // 至少 2
/* 防止除零错误 */
if (frequency == 0) frequency = 1;
/* 使用64位计算避免溢出,四舍五入处理 */
uint64_t divider = (timer_clock + (uint64_t)frequency / 2) / (uint64_t)frequency;
if (divider < 2) divider = 2; ///< 最小分频比为2

// 限制 ARR <= 65535
uint32_t psc = (divider + 65535) / 65536; // 向上取整
if (psc > 0xFFFF) psc = 0xFFFF;
/* 计算预分频器,限制ARR <= 65535 */
uint64_t psc = (divider + 65535ULL) / 65536ULL; ///< 向上取整
if (psc > 0xFFFFULL) psc = 0xFFFFULL; ///< 限制预分频器最大值

uint32_t arr = (divider / psc) - 1;
if (arr < 1) arr = 1;
if (arr > 65535) arr = 65535;
/* 计算自动重载值 */
uint64_t arr = (divider / psc) - 1;
if (arr < 1) arr = 1; ///< 最小ARR值为1
if (arr > 65535ULL) arr = 65535ULL; ///< 限制ARR最大值

/* 安全转换为16位和32位数据类型 */
*prescaler = (uint16_t)(psc - 1);
*period = arr;
*period = (uint32_t)arr;
}

// ==================== PLSR 路径计算函数实现 ====================


+ 439
- 439
PLSR/PLSR/EWARM/test.1.dep
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


+ 2756
- 2747
PLSR/PLSR/EWARM/test.1/Exe/test.1.hex
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Exe/test.1.out Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Exe/test.1.sim Dosyayı Görüntüle


+ 643
- 643
PLSR/PLSR/EWARM/test.1/List/test.1.map
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/gpio.o Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/main.o Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/modbus_log.o Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/tim.o Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/tools.o Dosyayı Görüntüle


BIN
PLSR/PLSR/EWARM/test.1/Obj/usart.o Dosyayı Görüntüle


Yükleniyor…
İptal
Kaydet