瀏覽代碼

加减速逻辑正常,段切换逻辑正常,但脉冲有多发,前500ms启动时波形奇怪.

master
JIU JIALIN 1 天之前
父節點
當前提交
b17a6a2a95
共有 60 個檔案被更改,包括 2724 行新增2595 行删除
  1. +2
    -8
      PLSR/PLSR/Core/Inc/tim.h
  2. +15
    -14
      PLSR/PLSR/Core/Src/main.c
  3. +14
    -0
      PLSR/PLSR/Core/Src/stm32f4xx_it.c
  4. +230
    -274
      PLSR/PLSR/Core/Src/tim.c
  5. +1
    -7
      PLSR/PLSR/Core/Src/usart.c
  6. +2
    -2
      PLSR/PLSR/EWARM/settings/test.1.dnx
  7. +618
    -377
      PLSR/PLSR/EWARM/test.1.dep
  8. +1312
    -1358
      PLSR/PLSR/EWARM/test.1/Exe/test.1.hex
  9. 二進制
      PLSR/PLSR/EWARM/test.1/Exe/test.1.out
  10. 二進制
      PLSR/PLSR/EWARM/test.1/Exe/test.1.sim
  11. +530
    -555
      PLSR/PLSR/EWARM/test.1/List/test.1.map
  12. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/app_hooks.o
  13. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/dma.o
  14. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/gpio.o
  15. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/main.o
  16. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/os_cpu_a.o
  17. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/os_cpu_c.o
  18. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/os_dbg.o
  19. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/startup_stm32f407xx.o
  20. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal.o
  21. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_cortex.o
  22. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_crc.o
  23. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_dma.o
  24. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_dma_ex.o
  25. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_exti.o
  26. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash.o
  27. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash_ex.o
  28. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash_ramfunc.o
  29. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_gpio.o
  30. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_i2c.o
  31. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_i2c_ex.o
  32. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_msp.o
  33. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_pwr.o
  34. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_pwr_ex.o
  35. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_rcc.o
  36. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_rcc_ex.o
  37. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_sram.o
  38. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_tim.o
  39. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_tim_ex.o
  40. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_timebase_tim.o
  41. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_uart.o
  42. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_usart.o
  43. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_wwdg.o
  44. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_it.o
  45. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_crc.o
  46. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_dac.o
  47. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_dma.o
  48. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_exti.o
  49. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_gpio.o
  50. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_i2c.o
  51. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_pwr.o
  52. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_rcc.o
  53. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_rng.o
  54. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_spi.o
  55. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_tim.o
  56. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_usart.o
  57. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/system_stm32f4xx.o
  58. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/tim.o
  59. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/ucos_ii.o
  60. 二進制
      PLSR/PLSR/EWARM/test.1/Obj/usart.o

+ 2
- 8
PLSR/PLSR/Core/Inc/tim.h 查看文件

@@ -93,12 +93,6 @@ typedef enum {
PLSR_ROUTE_ERROR = 3 // 路径错误
} PLSR_RouteState_t;

// // 段状态枚举
// typedef enum {
// PLSR_SECTION_IDLE = 0, // 段空闲
// PLSR_SECTION_RUNNING = 1, // 段运行中
// PLSR_SECTION_COMPLETED = 2 // 段完成
// } PLSR_SectionState_t;

// 运行模式枚举
typedef enum {
@@ -155,7 +149,7 @@ typedef struct {
uint32_t current_freq; // 当前频率
uint32_t target_freq; // 目标频率
uint32_t pulse_count; // 当前脉冲计数
uint32_t target_count; // 目标脉冲数,设置该值是因为
uint32_t prevPulseCount; // 上阶段目标脉冲
uint32_t start_freq; // 起始频率
uint32_t end_freq; // 结束频率
uint8_t output_port; // 输出端口选择
@@ -241,7 +235,7 @@ uint32_t PLSR_Counter_GetCount(void);
// ==================== PLSR TIM6频率配置函数 ====================
void PLSR_TIM6_SetUpdateFreq(uint32_t freq_us);
uint32_t PLSR_TIM6_GetUpdateFreq(void);
void PLSR_TIM6_Start(void);
void PLSR_TIM6_Start(void); //<在路径开始
void PLSR_TIM6_Stop(void);




+ 15
- 14
PLSR/PLSR/Core/Src/main.c 查看文件

@@ -246,22 +246,23 @@ static void KeyTask(void *p_arg)
{
(void)p_arg;
uint8_t startflag = 0;
PLSR_Route_Start(&g_plsr_route);
while (1)
{
PLSR_Section_Process(&g_plsr_route);
// if(ModbusSlave.holding_regs[0x2000] == 1) //按下发送脉冲按钮后,向0x3000地址写1,松手写2,设置地址偏移为0x1000,所以这里值为0x2000
// {
// startflag = 1;
// }
// if(startflag == 1)
// {
// PLSR_Route_Start(&g_plsr_route);
// }
// if(ModbusSlave.holding_regs[0x2000] == 2)
// {
// startflag = 0;
// }
if(ModbusSlave.holding_regs[0x2000] == 1) //按下发送脉冲按钮后,向0x3000地址写1,松手写2,设置地址偏移为0x1000,所以这里值为0x2000
{
startflag = 1;
g_plsr_route.route_state = PLSR_ROUTE_IDLE;
}
if(g_plsr_route.route_state == PLSR_ROUTE_COMPLETED)
{
startflag = 0;
}
if(startflag == 1)
{
PLSR_Route_Start(&g_plsr_route);
PLSR_Section_Process(&g_plsr_route);
}


OSTimeDlyHMSM(0, 0, 0, 10); /* 延时10ms */
}


+ 14
- 0
PLSR/PLSR/Core/Src/stm32f4xx_it.c 查看文件

@@ -43,6 +43,7 @@
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim6;
extern TIM_HandleTypeDef htim10;
extern DMA_HandleTypeDef hdma_usart1_rx;
@@ -239,6 +240,19 @@ void USART1_IRQHandler(void)
OSIntExit();
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles TIM2 global interrupt.
*/
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */

/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */

/* USER CODE END TIM2_IRQn 1 */
}

/**
* @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.


+ 230
- 274
PLSR/PLSR/Core/Src/tim.c 查看文件

@@ -29,7 +29,6 @@ uint8_t g_plsr_ext_event_flag = 0; // 外部事件标志

// ==================== PLSR内部变量 ====================
static uint32_t s_tim6_update_freq_us = 1000; // TIM6更新频率(微秒)
// static uint32_t s_target_pulse_count = 0; // 目标脉冲计数 - 暂时注释掉未使用的变量

// ==================== 等待时间相关变量 ====================
static volatile uint32_t s_wait_time_counter = 0; // 等待时间计数器
@@ -67,14 +66,14 @@ void PLSR_Wait_StartTimer(PLSR_RouteConfig_t* route)
s_wait_time_target = wait_cond->wait_time_ms;
s_wait_time_counter = 0;
s_wait_time_flag = 0;
PLSR_TIM6_Start();
//PLSR_TIM6_Start();
break;
case PLSR_WAIT_ACT_TIME:
s_act_time_target = wait_cond->act_time_ms;
s_act_time_counter = 0;
s_act_time_flag = 0;
PLSR_TIM6_Start();
//PLSR_TIM6_Start();
break;
case PLSR_WAIT_CONDITION:
@@ -103,7 +102,6 @@ uint8_t PLSR_Wait_CheckTime(PLSR_RouteConfig_t* route)
// 清除标志位和停止计时器
s_wait_time_flag = 0;
s_wait_time_target = 0;
PLSR_TIM6_Stop();
return 1; // 等待时间已到
}
@@ -449,29 +447,30 @@ void MX_TIM14_Init(void)
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 根据定时器实例进行不同的初始化配置
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */

/* USER CODE END TIM2_MspInit 0 */
// 使能TIM2时钟
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();

// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();

/**TIM2 GPIO Configuration
PA15 ------> TIM2_ETR
*/
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; // TIM2复用功能
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspInit 1 */

/* USER CODE END TIM2_MspInit 1 */
@@ -646,6 +645,8 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);

/* TIM2 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspDeInit 1 */

/* USER CODE END TIM2_MspDeInit 1 */
@@ -747,13 +748,10 @@ void PLSR_PWM_Init(void)
*/
void PLSR_PWM_Start(void)
{
if (g_plsr_route.run_state == PLSR_ROUTE_RUNNING) //<只有在路径运行状态下才可以进行pwm输出
if (g_plsr_route.route_state == PLSR_ROUTE_RUNNING) //<只有在路径运行状态下才可以进行pwm输出
{
// 启动PWM输出和更新中断
HAL_TIM_PWM_Start_IT(&htim10, TIM_CHANNEL_1);
// 启动TIM2脉冲计数器
PLSR_Counter_Start();
}
}

@@ -765,56 +763,88 @@ void PLSR_PWM_Start(void)
*/
void PLSR_PWM_Stop(void)
{
if (g_plsr_route.run_state == PLSR_ROUTE_COMPLETED)
{
// 停止PWM输出
HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1);
// 停止TIM2计数器
HAL_TIM_Base_Stop(&htim2); // TIM2恢复用于脉冲计数
g_plsr_route.run_state = PLSR_ROUTE_IDLE;
}
// 停止PWM输出
HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1);
// 停止TIM2计数器
HAL_TIM_Base_Stop(&htim2); // TIM2恢复用于脉冲计数
}


/**
* @brief 立即设置PWM频率(直接更新,用于初始化)
* @param frequency 目标频率(Hz)
* @brief 计算定时器参数
* @param frequency: 目标频率(Hz)
* @param prescaler: 预分频器值指针
* @param period: 周期值指针
* @retval None
* @note 根据目标频率计算TIM10的预分频器和周期值
*/
void PLSR_PWM_SetFrequency(uint32_t frequency)
static void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, uint32_t* period)
{
uint16_t prescaler = 0; // 预分频器值
uint32_t period = 0; // 自动重载值(周期)
// STM32F4系列定时器时钟频率(通常为84MHz,具体取决于系统配置)
uint32_t timer_clock = 168000000;
// 频率范围检查
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX)
{
// 定时器频率计算原理:
// 输出频率 = 定时器时钟频率 / ((预分频器 + 1) * (自动重装载值 + 1))
// 因此:(预分频器 + 1) * (自动重装载值 + 1) = 定时器时钟频率 / 目标频率
// 频率为0时的异常处理
if (frequency == 0) {
*prescaler = 0;
*period = 0;
return;
}
// 计算总的计数值:定时器时钟频率除以目标频率
// 计算总的计数值:定时器时钟频率除以目标频率
uint32_t total_count = timer_clock / frequency;
// 遍历所有可能的预分频器值,寻找合适的组合
// 预分频器范围:1-65536(寄存器值0-65535)
for (uint16_t psc = 1; psc <= 65535; psc++)
{
for (uint16_t psc = 1; psc <= 65535; psc++) {
// 计算对应的自动重装载值
uint32_t arr = total_count / psc;
// 检查自动重装载值是否在有效范围内(1-65536,寄存器值0-65535)
if (arr <= 65535 && arr >= 1) {
// 找到合适的组合,转换为寄存器值(实际值减1)
prescaler = psc - 1; // 预分频器寄存器值 = 实际预分频值 - 1
period = arr - 1; // 自动重装载寄存器值 = 实际重装载值 - 1
*prescaler = psc - 1; // 预分频器寄存器值 = 实际预分频值 - 1
*period = arr - 1; // 自动重装载寄存器值 = 实际重装载值 - 1
return;
}
}
// 直接更新定时器参数
__HAL_TIM_SET_PRESCALER(&htim10, prescaler);
// 如果找不到合适的值组合,使用默认的1kHz配置
// 预分频器 = 83 (实际分频84),自动重装载 = 999 (实际计数1000)
// 输出频率 = 84MHz / (84 * 1000) = 1kHz
*prescaler = 83; // 84MHz / 84 = 1MHz
*period = 999; // 1MHz / 1000 = 1kHz
}


/**
* @brief 设置PWM频率
* @param frequency: PWM频率 (1Hz-100kHz)
*/
void PLSR_PWM_SetFrequency(uint32_t frequency)
{
uint16_t prescaler = 0; // 预分频器值
uint32_t period = 0; // 自动重载值(周期)
// 频率范围检查 - 确保频率在1hz到100khz范围内
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX)
{
return; // 频率超出范围,直接返回,不做任何修改
}
// 计算最佳定时器参数 - 根据目标频率计算预分频器和周期值
PLSR_CalculateTimerParams(frequency, &prescaler, &period);
// 更新定时器核心参数
__HAL_TIM_SET_PRESCALER(&htim10, prescaler); //< 放置波形出现问题对参数直接进行更新
__HAL_TIM_SET_AUTORELOAD(&htim10, period);
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, period / 2);
// 设置占空比为50% - 比较值设为周期的一半,产生对称的PWM波形
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, period / 2);
}

// ==================== PLSR TIM6频率配置函数实现 ====================
@@ -887,20 +917,114 @@ void PLSR_TIM6_Stop(void)
HAL_TIM_Base_Stop_IT(&htim6);
}

static uint32_t AllPluse = 0; //总脉冲个数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
// 检查中断源 - 处理TIM10的PWM更新中断
if(htim->Instance == TIM10)
// TIM2中断:负责段切换逻辑
if(htim->Instance == TIM2)
{
g_plsr_route.pulse_count++;
// 累加总脉冲数
AllPluse += __HAL_TIM_GetAutoreload(&htim2);
g_plsr_route.pulse_count = AllPluse;
// 检查当前段是否完成
if (PLSR_Section_CheckPulseComplete(&g_plsr_route))
{
// 当前段脉冲发送完毕,进入等待状态
g_plsr_route.run_state = PLSR_STATE_WAIT;
// 检查等待条件是否满足
if (PLSR_Section_CheckWaitCondition(&g_plsr_route))
{
// 等待条件满足,切换到下一段
PLSR_SectionConfig_t* current_section = &g_plsr_route.section[g_plsr_route.current_section_num - 1];
if (current_section->next_section == 0 && g_plsr_route.current_section_num == g_plsr_route.section_num) //< 当前段是最后一段且跳转段为0,路径结束
{
PLSR_Route_Stop(&g_plsr_route);
return;
}
else if (current_section->next_section > 0 && current_section->next_section <= PLSR_MAX_SECTIONS)
{
// 更新prevPulseCount为当前段的累计脉冲数
if (g_plsr_route.mode == PLSR_MODE_RELATIVE) {
g_plsr_route.prevPulseCount = g_plsr_route.pulse_count;
}
// 切换到下一段
g_plsr_route.current_section_num = current_section->next_section;
g_plsr_route.current_freq = g_plsr_route.target_freq; // 当前频率更新为上一段的目标频率
// 启动新段
PLSR_Section_StartNewSection(&g_plsr_route);
// 设置TIM2的自动重载值为新段的脉冲数
PLSR_SectionConfig_t* new_section = &g_plsr_route.section[g_plsr_route.current_section_num - 1];
uint32_t next_pulse_target;
if (g_plsr_route.mode == PLSR_MODE_RELATIVE) {
next_pulse_target = new_section->target_pulse;
} else {
next_pulse_target = new_section->target_pulse - g_plsr_route.pulse_count;
}
__HAL_TIM_SetAutoreload(&htim2, next_pulse_target);
}
else
{
// 没有下一段,停止路径
PLSR_Route_Stop(&g_plsr_route);
return;
}
}
}
// 重置TIM2计数器
__HAL_TIM_SET_COUNTER(&htim2, 0);
}
// TIM6用于等待时间计时
// TIM6中断:仅负责加减速过程的频率更新和等待时间计时
if(htim->Instance == TIM6)
{
// 等待时间计数器累加
s_wait_time_counter++;

// 处理加速和减速过程中的频率更新
if(g_plsr_route.run_state == PLSR_STATE_ACCEL && g_plsr_route.accel_step_count > 0)
{
g_plsr_route.current_freq += g_plsr_route.freq_step;
PLSR_PWM_SetFrequency(g_plsr_route.current_freq);
if(g_plsr_route.current_freq > 0)
{
PLSR_PWM_Start();
}
g_plsr_route.accel_step_count--;
// 加速完成,进入匀速状态
if(g_plsr_route.accel_step_count == 0)
{
g_plsr_route.run_state = PLSR_STATE_CONST;
}
}
else if(g_plsr_route.run_state == PLSR_STATE_DECEL && g_plsr_route.decel_step_count > 0)
{
g_plsr_route.current_freq -= g_plsr_route.freq_step;
PLSR_PWM_SetFrequency(g_plsr_route.current_freq);
if(g_plsr_route.current_freq <= 0) //频率减为0时一般进入等待,且脉冲也已发完
{
g_plsr_route.run_state = PLSR_STATE_WAIT;
PLSR_PWM_Stop();
}
g_plsr_route.decel_step_count--;
// 减速完成,进入匀速状态
if(g_plsr_route.decel_step_count == 0)
{
g_plsr_route.run_state = PLSR_STATE_CONST;
}
}
}
}

@@ -927,10 +1051,10 @@ void PLSR_Route_Set(PLSR_RouteConfig_t* route)
{
route->section[i].section_num = i + 1;
route->section[i].target_freq = (((uint32_t)ModbusSlave.holding_regs[256+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[257+(6*i)]<<16);
route->section[i].target_pulse = (((uint32_t)ModbusSlave.holding_regs[258+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[259+(6*i)]<<16);
route->section[i].wait_condition.wait_type = ModbusSlave.holding_regs[260+(6*i)];
route->section[i].next_section = ModbusSlave.holding_regs[261+(6*i)];
route->section[i].target_freq = (((uint32_t)ModbusSlave.holding_regs[256+(16*i)]) | (uint32_t)ModbusSlave.holding_regs[257+(16*i)]<<16);
route->section[i].target_pulse = (((uint32_t)ModbusSlave.holding_regs[258+(16*i)]) | (uint32_t)ModbusSlave.holding_regs[259+(16*i)]<<16);
route->section[i].wait_condition.wait_type = ModbusSlave.holding_regs[260+(16*i)];
route->section[i].next_section = ModbusSlave.holding_regs[261+(16*i)];
}
}

@@ -958,6 +1082,7 @@ void PLSR_Route_Init(PLSR_RouteConfig_t* route)
PLSR_PWM_Stop(); // 停止PWM输出
PLSR_TIM6_Stop(); // 停止TIM6定时器
PLSR_TIM6_SetUpdateFreq(1000); //初始化TIM6更新频率为1000us
}

/**
@@ -969,31 +1094,42 @@ void PLSR_Route_Start(PLSR_RouteConfig_t* route)
{
// 参数有效性检查
if (route == NULL) return;
// 状态检查 - 避免重复启动
if (route->route_state == PLSR_ROUTE_RUNNING)
return;
return;
//启动时初始化用户可配置参数.
// 启动时初始化用户可配置参数
PLSR_Route_Set(route);
// 路径状态初始化
route->route_state = PLSR_ROUTE_RUNNING; //< 设置路径状态为运行中
route->current_section_num = route->start_section; //< 从起始段开始执行
route->current_freq = route->start_freq; //< 设置当前频率为起始频率
route->pulse_count = 0; //< 清零脉冲计数
route->run_state = PLSR_STATE_IDLE; //< 设置运行状态为空闲
// PWM输出初始化 - 根据起始频率决定是否启动
if (route->start_freq > 0) {
PLSR_PWM_SetFrequency(route->start_freq); //< 设置初始PWM频率
PLSR_PWM_Start(); // 启动PWM输出
}
route->route_state = PLSR_ROUTE_RUNNING; // 设置路径状态为运行中
route->current_section_num = route->start_section; // 从起始段开始执行
route->current_freq = route->start_freq; // 设置当前频率为起始频率
route->pulse_count = 0; // 清零脉冲计数
route->prevPulseCount = 0; // 清零上一段脉冲计数
route->run_state = PLSR_STATE_IDLE; // 设置运行状态为空闲
// 重置全局脉冲计数器
AllPluse = 0;
// 启动定时器控制 - TIM6提供路径处理的时间基准
PLSR_TIM6_Start();
// 启动第一段
PLSR_Section_StartNewSection(route);
// 设置TIM2的自动重载值为第一段的脉冲数
PLSR_SectionConfig_t* first_section = &route->section[route->current_section_num - 1];
__HAL_TIM_SetAutoreload(&htim2, first_section->target_pulse);
// 重置TIM2计数器
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 立即开始处理第一段 - 启动路径执行的状态机
PLSR_Section_Process(route);
if(route->start_freq > 0)
{
PLSR_PWM_SetFrequency(route->start_freq); // 设置初始PWM频率
PLSR_PWM_Start(); // 立即启动PWM输出
}
// 启动定时器
PLSR_TIM6_Start(); // 启动TIM6用于频率更新和等待时间计时
HAL_TIM_Base_Start_IT(&htim2); // 启动TIM2中断用于段切换
}

/**
@@ -1009,14 +1145,23 @@ void PLSR_Route_Stop(PLSR_RouteConfig_t* route)
// 停止PWM输出和定时器
PLSR_PWM_Stop();
PLSR_TIM6_Stop();
HAL_TIM_Base_Stop_IT(&htim2); // 停止TIM2中断
// 重置路径状态
route->route_state = PLSR_ROUTE_IDLE;
route->route_state = PLSR_ROUTE_COMPLETED;
route->run_state = PLSR_STATE_IDLE;
route->current_freq = 0;
// 重置计数器
PLSR_Counter_Reset(); // TIM2恢复用于脉冲计数
// 重置计数器和脉冲数
__HAL_TIM_SET_COUNTER(&htim2, 0);
AllPluse = 0;
route->pulse_count = 0;
route->prevPulseCount = 0;
// 重置加减速参数
route->accel_step_count = 0;
route->decel_step_count = 0;
route->freq_step = 0;
}


@@ -1026,9 +1171,8 @@ void PLSR_Route_Stop(PLSR_RouteConfig_t* route)
* @brief PLSR段处理主函数
* @param route: 路径控制结构体指针
* @retval None
* @note 在TIM6中断中调用,处理当前段的执行逻辑
* 这是PLSR系统的核心状态机,根据当前运行状态调用相应的处理函数
* 状态转换顺序:IDLE -> ACCEL -> CONST -> DECEL -> WAIT -> 下一段
* @note 在TIM6中断中调用,仅处理加减速过程中的频率更新
* 段切换逻辑已移至TIM2中断处理
*/
void PLSR_Section_Process(PLSR_RouteConfig_t* route)
{
@@ -1036,54 +1180,23 @@ void PLSR_Section_Process(PLSR_RouteConfig_t* route)
if (route == NULL) return; // 空指针检查
if (route->route_state != PLSR_ROUTE_RUNNING) return; // 路径必须处于运行状态
// 段号有效性检查
if (route->current_section_num == 0 || route->current_section_num > PLSR_MAX_SECTIONS) {
PLSR_Route_Stop(route); // 段号无效,停止路径执行
return;
}
/*如果是以下两种条件的话,触发立马进行段切换*/
if(route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_ACT_TIME
||route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_EXT_EVENT)
{
PLSR_ChackWait_End(route);
}

// 根据当前运行状态执行相应的处理逻辑
switch (route->run_state)
{
case PLSR_STATE_IDLE:
// 空闲状态:开始新段处理
// 初始化段参数,计算加减速步数,设置目标频率
PLSR_Section_StartNewSection(route);
break;
case PLSR_STATE_ACCEL:
// 加速状态:执行加速算法
// 根据加速算法(线性/曲线/正弦)逐步提高频率
PLSR_Accel_Process(route);
break;
case PLSR_STATE_CONST:
// 匀速状态:保持目标频率运行
// 检查脉冲计数,判断是否需要进入减速或完成段
PLSR_Section_ProcessConstSpeed(route);
break;
case PLSR_STATE_DECEL:
// 减速状态:执行减速算法
// 根据减速算法逐步降低频率到目标值
PLSR_Accel_Process(route);
break;

case PLSR_STATE_WAIT: //脉冲发送完成/或停止都会被设为等待状态
// 等待状态:处理等待条件
PLSR_ChackWait_End(route);
break;
default:
// 未知状态:重置为空闲状态
route->run_state = PLSR_STATE_IDLE;
// 其他状态不需要在TIM6中处理
break;
}
}
@@ -1126,7 +1239,7 @@ void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route)
// 计算匀速段可以发送的脉冲数(扣除加减速段的脉冲数)
PLSR_Section_CalculateConstPulse(route);
// 启动等待条件计时器,为可能的等待状态做准备
//为等待时间计数赋值
PLSR_Wait_StartTimer(route);
}

@@ -1143,9 +1256,9 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route)
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1];
uint8_t next_section_num = current_section->next_section;
route->target_count += current_section->target_pulse;
route->prevPulseCount += current_section->target_pulse;
// 检查下一段是否有效
if (next_section_num == 0 || next_section_num > PLSR_MAX_SECTIONS)
if (next_section_num-1 == 0 || next_section_num > PLSR_MAX_SECTIONS)
{
// 路径结束
route->route_state = PLSR_ROUTE_COMPLETED;
@@ -1159,6 +1272,7 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route)
// 更新当前频率为上一段的目标频率
route->current_freq = current_section->target_freq;
PLSR_PWM_SetFrequency(route->current_freq);
}

/**
@@ -1291,176 +1405,18 @@ void PLSR_Accel_Process(PLSR_RouteConfig_t* route)
// 参数有效性检查
if (route == NULL) return;
// 静态变量用于保存加减速过程中的状态
static uint32_t start_freq_accel = 0; // 加速起始频率
static uint32_t total_accel_steps = 0; // 总加速步数
static uint32_t start_freq_decel = 0; // 减速起始频率
static uint32_t total_decel_steps = 0; // 总减速步数
// 获取当前段配置和初始化变量
// PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; // 暂时注释掉未使用的变量
uint32_t new_freq = route->current_freq; // 新频率,默认为当前频率
// ==================== 加速处理 ====================
if (route->run_state == PLSR_STATE_ACCEL)
{
// 检查是否还有加速步数需要执行
if (route->accel_step_count > 0)
{
// 记录总步数和起始频率(仅在第一次进入加速时)
if (total_accel_steps == 0)
{
total_accel_steps = route->accel_step_count; // 保存总加速步数
start_freq_accel = route->current_freq; // 保存加速起始频率
}
// 根据加速算法类型计算新频率
switch (route->accel_config.accel_algorithm)
{
case PLSR_ACCEL_LINEAR:
{
// 直线加速:使用固定频率增量
// 计算频率范围和每步增量
uint32_t freq_range = route->target_freq - start_freq_accel;
uint32_t freq_increment = freq_range / total_accel_steps;
// 计算已完成的步数
uint32_t completed_steps = total_accel_steps - route->accel_step_count;
// 计算新频率 = 起始频率 + (增量 × 已完成步数) 起始频率不变,频率增量不变,非累加
new_freq = start_freq_accel + (freq_increment * completed_steps);
}
break;
case PLSR_ACCEL_CURVE:
case PLSR_ACCEL_SINE:
{
// 曲线和正弦加速:使用进度计算
// 计算加速进度 (0.0 到 1.0)
float progress = (float)(total_accel_steps - route->accel_step_count) / (float)total_accel_steps;
// 根据算法类型计算频率比例
float freq_ratio = 0.0f;
if (route->accel_config.accel_algorithm == PLSR_ACCEL_CURVE)
{
freq_ratio = PLSR_Accel_CalculateCurve(progress); // 曲线算法
}
else
{
freq_ratio = PLSR_Accel_CalculateSine(progress); // 正弦算法
}
// 计算新频率 = 起始频率 + (频率范围 × 频率比例)
uint32_t freq_range = route->target_freq - start_freq_accel;
new_freq = start_freq_accel + (uint32_t)(freq_range * freq_ratio);
}
break;
default:
{
// 默认使用直线加速
uint32_t freq_range = route->target_freq - start_freq_accel;
uint32_t freq_increment = freq_range / total_accel_steps;
uint32_t completed_steps = total_accel_steps - route->accel_step_count;
new_freq = start_freq_accel + (freq_increment * completed_steps);
}
break;
}
// 减少剩余加速步数
route->accel_step_count--;
}
else
{
// 加速完成,设置为目标频率并切换到匀速状态
new_freq = route->target_freq;
route->run_state = PLSR_STATE_CONST;
// 重置加速相关的静态变量
total_accel_steps = 0;
start_freq_accel = 0;
}

}
// ==================== 减速处理 ====================
else if (route->run_state == PLSR_STATE_DECEL)
{
// 检查是否还有减速步数需要执行
if (route->decel_step_count > 0) {
// 记录总步数和起始频率(仅在第一次进入减速时)
if (total_decel_steps == 0) {
total_decel_steps = route->decel_step_count; // 保存总减速步数
start_freq_decel = route->current_freq; // 保存减速起始频率
}
// 根据减速算法类型计算新频率
switch (route->accel_config.accel_algorithm) {
case PLSR_ACCEL_LINEAR:
{
// 直线减速:使用固定频率减量
// 计算频率范围和每步减量
uint32_t freq_range = start_freq_decel - route->target_freq;
uint32_t freq_decrement = freq_range / total_decel_steps;
// 计算已完成的步数
uint32_t completed_steps = total_decel_steps - route->decel_step_count;
// 计算新频率 = 起始频率 - (减量 × 已完成步数)
new_freq = start_freq_decel - (freq_decrement * completed_steps);
}
break;
case PLSR_ACCEL_CURVE:
case PLSR_ACCEL_SINE:
{
// 曲线和正弦减速:使用进度计算
// 计算减速进度 (0.0 到 1.0)
float progress = (float)(total_decel_steps - route->decel_step_count) / (float)total_decel_steps;
// 根据算法类型计算频率比例
float freq_ratio = 0.0f;
if (route->accel_config.accel_algorithm == PLSR_ACCEL_CURVE) {
freq_ratio = PLSR_Accel_CalculateCurve(progress); // 曲线算法
} else {
freq_ratio = PLSR_Accel_CalculateSine(progress); // 正弦算法
}
// 计算新频率 = 起始频率 - (频率范围 × 频率比例)
uint32_t freq_range = start_freq_decel - route->target_freq;
new_freq = start_freq_decel - (uint32_t)(freq_range * freq_ratio);
}
break;
default:
{
// 默认使用直线减速
uint32_t freq_range = start_freq_decel - route->target_freq;
uint32_t freq_decrement = freq_range / total_decel_steps;
uint32_t completed_steps = total_decel_steps - route->decel_step_count;
new_freq = start_freq_decel - (freq_decrement * completed_steps);
}
break;
}
// 减少剩余减速步数
route->decel_step_count--;
}
else
{
// 减速完成,设置为目标频率
new_freq = route->target_freq;
// 如果目标频率为0,停止PWM输出并直接进入等待状态
if (route->target_freq == 0)
{
PLSR_PWM_Stop(); // 停止PWM输出
route->run_state = PLSR_STATE_WAIT; // 直接进入等待状态
}
else
{
route->run_state = PLSR_STATE_CONST; // 进入匀速状态
}
// 重置减速相关的静态变量
total_decel_steps = 0;
start_freq_decel = 0;
}
}
// 当状态改变或脉冲完成时,进行状态转换检查
if (PLSR_Section_CheckPulseComplete(route))
{
route->run_state = PLSR_STATE_WAIT;
}
}


@@ -1477,7 +1433,7 @@ void PLSR_Section_ProcessConstSpeed(PLSR_RouteConfig_t* route)
//检查段脉冲是否发完,若完成进入等待模式
if (PLSR_Section_CheckPulseComplete(route))
{
route->route_state = PLSR_STATE_WAIT; //如果发完进入等待条件
route->run_state = PLSR_STATE_WAIT; //如果发完进入等待条件
}
}

@@ -1517,7 +1473,7 @@ uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route)
uint32_t target_pulse;
if (route->mode == PLSR_MODE_RELATIVE)
{
target_pulse = current_section->target_pulse + route->target_count;
target_pulse = current_section->target_pulse + route->prevPulseCount; //1000 2000 3000 2->3 2000+1000 route->pulse_count>=3000
}
else
{
@@ -1587,7 +1543,7 @@ void PLSR_Counter_Start(void)
// 重置计数器到0
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 启动TIM2计数器
HAL_TIM_Base_Start(&htim2);
HAL_TIM_Base_Start_IT(&htim2);
}

/**
@@ -1598,7 +1554,7 @@ void PLSR_Counter_Start(void)
*/
void PLSR_Counter_Stop(void)
{
HAL_TIM_Base_Stop(&htim2);
HAL_TIM_Base_Stop_IT(&htim2);
}

/**


+ 1
- 7
PLSR/PLSR/Core/Src/usart.c 查看文件

@@ -37,14 +37,9 @@ ModbusSlave_t ModbusSlave;
// 内部函数声明
static void Modbus_Send_Response(uint8_t *data, uint16_t length);
static void Modbus_Send_Exception(uint8_t function_code, uint8_t exception_code);
static void Modbus_Process_Read_Coils(uint8_t *frame, uint16_t length);
static void Modbus_Process_Read_Holding_Regs(uint8_t *frame, uint16_t length);
static void Modbus_Process_Write_Multiple_Coils(uint8_t *frame, uint16_t length);
static void Modbus_Process_Write_Multiple_Regs(uint8_t *frame, uint16_t length);

// 辅助函数声明
static uint8_t Get_Coil_Bit(uint16_t addr);
static void Set_Coil_Bit(uint16_t addr, uint8_t value);
/* USER CODE END 0 */

UART_HandleTypeDef huart1;
@@ -493,8 +488,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length)
uint16_t reg_count = (frame[4] << 8) | frame[5];
uint8_t byte_count = frame[6];
if(reg_count == 0 || reg_count > 123 || write_addr + reg_count > MODBUS_HOLDING_REG_COUNT ||
byte_count != reg_count * 2 || length != 9 + byte_count)
if((reg_count == 0) || (reg_count > 123) || ((write_addr + reg_count) > MODBUS_HOLDING_REG_COUNT))
{
Modbus_Send_Exception(MODBUS_FC_WRITE_MULTIPLE_REGS, MODBUS_EX_ILLEGAL_DATA_ADDRESS);
return;


+ 2
- 2
PLSR/PLSR/EWARM/settings/test.1.dnx 查看文件

@@ -12,12 +12,12 @@
<ByteLimit>50</ByteLimit>
</Stack>
<StLinkDriver>
<stlinkserialNo>46232557</stlinkserialNo>
<stlinkfoundProbes />
<CStepIntDis>_ 0</CStepIntDis>
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
<stlinkResetStyle>0</stlinkResetStyle>
<stlinkResetStrategy>2</stlinkResetStrategy>
<stlinkserialNo>46232557</stlinkserialNo>
<stlinkfoundProbes />
</StLinkDriver>
<DebugChecksum>
<Checksum>3949072944</Checksum>


+ 618
- 377
PLSR/PLSR/EWARM/test.1.dep
文件差異過大導致無法顯示
查看文件


+ 1312
- 1358
PLSR/PLSR/EWARM/test.1/Exe/test.1.hex
文件差異過大導致無法顯示
查看文件


二進制
PLSR/PLSR/EWARM/test.1/Exe/test.1.out 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Exe/test.1.sim 查看文件


+ 530
- 555
PLSR/PLSR/EWARM/test.1/List/test.1.map
文件差異過大導致無法顯示
查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/app_hooks.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/dma.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/gpio.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/main.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/os_cpu_a.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/os_cpu_c.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/os_dbg.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/startup_stm32f407xx.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_cortex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_crc.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_dma.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_dma_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_exti.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_flash_ramfunc.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_gpio.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_i2c.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_i2c_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_msp.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_pwr.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_pwr_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_rcc.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_rcc_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_sram.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_tim.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_tim_ex.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_timebase_tim.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_uart.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_usart.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_hal_wwdg.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_it.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_crc.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_dac.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_dma.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_exti.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_gpio.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_i2c.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_pwr.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_rcc.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_rng.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_spi.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_tim.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/stm32f4xx_ll_usart.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/system_stm32f4xx.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/tim.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/ucos_ii.o 查看文件


二進制
PLSR/PLSR/EWARM/test.1/Obj/usart.o 查看文件


Loading…
取消
儲存