# PLSR脉冲输出控制系统使用说明 V2.0 ## 系统概述 PLSR(脉冲输出指令)系统是基于STM32 HAL库和UCOSII实时操作系统的多段脉冲输出控制系统,兼容信捷PLC的PLSR指令规范。系统支持10段独立配置的脉冲输出,每段可设置不同的频率、脉冲数、加减速算法和等待条件。 ## 硬件配置 ### 定时器配置 - **TIM10**: PWM脉冲输出定时器,输出频率可动态调整 - **TIM2**: 脉冲计数定时器,对TIM10的PWM输出进行计数 - **TIM6**: 系统控制定时器,用于加减速控制和段切换,更新频率可配置 ### 引脚配置 - PWM输出引脚:根据TIM10配置确定 - 方向控制引脚:可选配置 - 外部事件输入引脚:可选配置 ## 核心数据结构 ### 1. 等待条件结构体 (PLSR_WaitCondition_t) ```c typedef struct { PLSR_WaitType_t wait_type; // 等待条件类型 uint32_t wait_time_ms; // 等待时间(ms) uint32_t act_time_ms; // ACT时间(ms) uint8_t condition_flag; // 条件标志 uint8_t ext_event_flag; // 外部事件标志 } PLSR_WaitCondition_t; ``` ### 2. 加减速配置结构体 (PLSR_AccelConfig_t) ```c typedef struct { uint32_t accel_time_ms; // 加速时间(ms) uint32_t decel_time_ms; // 减速时间(ms) PLSR_AccelAlgorithm_t accel_algorithm; // 加减速算法 } PLSR_AccelConfig_t; ``` ### 3. 段配置结构体 (PLSR_SectionConfig_t) ```c typedef struct { uint8_t section_num; // 段号(1-10) uint32_t target_freq; // 目标频率(Hz) uint32_t target_pulse; // 目标脉冲数 uint8_t next_section; // 下一段号(0表示结束) PLSR_SectionState_t section_state; // 段状态 PLSR_AccelConfig_t accel_config; // 加减速配置 PLSR_WaitCondition_t wait_condition; // 等待条件 } PLSR_SectionConfig_t; ``` ### 4. 路径控制结构体 (PLSR_RouteConfig_t) ```c typedef struct { PLSR_RouteState_t route_state; // 路径状态 uint8_t current_section_num; // 当前段号 uint32_t current_freq; // 当前频率 uint32_t target_freq; // 目标频率 uint32_t pulse_count; // 当前脉冲计数 uint32_t start_freq; // 起始频率 uint32_t end_freq; // 结束频率 uint8_t output_port; // 输出端口选择 PLSR_Mode_t mode; // 模式(相对/绝对) PLSR_Direction_t direction; // 方向 // 运行状态参数 PLSR_RunState_t run_state; // 运行状态 uint32_t accel_step_count; // 加速步数计数 uint32_t decel_step_count; // 减速步数计数 uint32_t const_pulse_count; // 匀速脉冲计数 uint32_t freq_step; // 频率步长 uint32_t wait_start_tick; // 等待开始时间 uint32_t act_start_tick; // ACT开始时间 PLSR_SectionConfig_t section[PLSR_MAX_SECTIONS]; // 段配置数组 } PLSR_RouteConfig_t; ``` ## 等待条件类型详解 ### 1. PLSR_WAIT_PLUSEEND - **功能**: 脉冲发送完成后立即切换到下一段 - **使用场景**: 标准的段切换模式 - **特点**: 不需要额外等待时间 ### 2. PLSR_WAIT_TIME - **功能**: 等待指定时间后切换段 - **逻辑**: - 如果等待时间先到达,脉冲发送完成后立即切换 - 如果脉冲先发送完成,等待时间到达后切换 - **默认时间**: 200ms ### 3. PLSR_WAIT_CONDITION - **功能**: 等待外部条件标志后切换段 - **逻辑**: 与WAIT_TIME类似,但等待的是条件标志 - **控制方式**: 通过`PLSR_SetSectionCondition()`设置 ### 4. PLSR_WAIT_ACT_TIME - **功能**: ACT时间控制段切换 - **特殊逻辑**: - ACT时间短:在加速段时直接切换到下一段 - ACT时间长:在减速段时直接切换到下一段 - ACT时间很长:等待当前段完成后再等待ACT时间 - **默认时间**: 200ms ### 5. PLSR_WAIT_EXT_EVENT - **功能**: 等待外部事件触发 - **控制方式**: 通过`PLSR_SetExtEvent()`设置 - **特点**: 不触发则一直等待 ### 6. PLSR_WAIT_EXT_OR_END - **功能**: 外部事件或脉冲结束,任一条件满足即切换 - **特点**: 提供更灵活的切换控制 ## 运行模式说明 ### 相对模式 (PLSR_MODE_RELATIVE) - **脉冲数含义**: 相对于上一段的脉冲增量 - **计算方式**: 直接使用配置的target_pulse值 - **适用场景**: 增量式运动控制 ### 绝对模式 (PLSR_MODE_ABSOLUTE) - **脉冲数含义**: 绝对位置坐标 - **计算方式**: target_pulse - current_pulse_count - **适用场景**: 位置式运动控制 ## 加减速算法 ### 1. 线性加减速 (PLSR_ACCEL_LINEAR) - **特点**: 频率线性变化 - **公式**: freq = start_freq + (target_freq - start_freq) * progress - **适用**: 简单应用场景 ### 2. 曲线加减速 (PLSR_ACCEL_CURVE) - **特点**: S型曲线,平滑过渡 - **公式**: f(x) = 3x² - 2x³ - **适用**: 需要平滑启停的场景 ### 3. 正弦加减速 (PLSR_ACCEL_SINE) - **特点**: 基于正弦函数的平滑变化 - **公式**: f(x) = sin(π/2 * x) - **适用**: 高精度平滑控制 ## 系统使用流程 ### 1. 系统初始化 ```c // 初始化PWM和计数器 PLSR_PWM_Init(); // 配置TIM6更新频率(微秒) PLSR_TIM6_SetUpdateFreq(1000); // 1ms更新频率 // 初始化路径配置 PLSR_Route_Init(&g_plsr_route); ``` ### 2. 路径参数配置 ```c // 设置基本参数 g_plsr_route.start_freq = 1000; // 起始频率1kHz g_plsr_route.end_freq = 0; // 结束频率0Hz g_plsr_route.mode = PLSR_MODE_RELATIVE; // 相对模式 g_plsr_route.direction = PLSR_DIR_FORWARD; // 正向 ``` ### 3. 段参数配置示例 ```c // 配置第1段 g_plsr_route.section[0].target_freq = 5000; // 目标频率5kHz g_plsr_route.section[0].target_pulse = 10000; // 目标脉冲10000个 g_plsr_route.section[0].next_section = 2; // 下一段为第2段 g_plsr_route.section[0].accel_config.accel_time_ms = 2000; // 加速时间2s g_plsr_route.section[0].accel_config.decel_time_ms = 1500; // 减速时间1.5s g_plsr_route.section[0].accel_config.accel_algorithm = PLSR_ACCEL_CURVE; // S曲线 g_plsr_route.section[0].wait_condition.wait_type = PLSR_WAIT_PLUSEEND; // 脉冲结束切换 // 配置第2段 g_plsr_route.section[1].target_freq = 3000; // 目标频率3kHz g_plsr_route.section[1].target_pulse = 5000; // 目标脉冲5000个 g_plsr_route.section[1].next_section = 0; // 结束(下一段为0) g_plsr_route.section[1].wait_condition.wait_type = PLSR_WAIT_TIME; g_plsr_route.section[1].wait_condition.wait_time_ms = 500; // 等待500ms ``` ### 4. 启动路径执行 ```c // 启动路径执行 PLSR_Route_Start(&g_plsr_route); // 检查运行状态 if (PLSR_Route_IsRunning(&g_plsr_route)) { // 路径正在执行 } ``` ### 5. 运行时控制 ```c // 设置外部事件 PLSR_SetExtEvent(1); // 设置段条件标志 PLSR_SetSectionCondition(&g_plsr_route, 2, 1); // 获取当前脉冲计数 uint32_t current_pulse = PLSR_Counter_GetCount(); // 获取当前PWM频率 uint32_t current_freq = PLSR_PWM_GetFrequency(); // 停止路径执行 PLSR_Route_Stop(&g_plsr_route); ``` ## 状态机说明 ### 路径状态 (PLSR_RouteState_t) - **PLSR_ROUTE_IDLE**: 空闲状态 - **PLSR_ROUTE_RUNNING**: 运行状态 - **PLSR_ROUTE_COMPLETED**: 完成状态 - **PLSR_ROUTE_ERROR**: 错误状态 ### 运行状态 (PLSR_RunState_t) - **PLSR_STATE_IDLE**: 空闲状态 - **PLSR_STATE_ACCEL**: 加速状态 - **PLSR_STATE_CONST**: 匀速状态 - **PLSR_STATE_DECEL**: 减速状态 - **PLSR_STATE_WAIT**: 等待状态 - **PLSR_STATE_STOP**: 停止状态 ### 段状态 (PLSR_SectionState_t) - **PLSR_SECTION_IDLE**: 段空闲 - **PLSR_SECTION_RUNNING**: 段运行中 - **PLSR_SECTION_COMPLETED**: 段完成 ## 中断处理 ### TIM6中断回调 ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM6) { // PLSR路径控制处理 PLSR_Route_Process(&g_plsr_route); // 系统时钟递增 g_plsr_system_tick++; } } ``` ## 调试和监控 ### 状态监控函数 ```c // 获取系统时钟 uint32_t tick = PLSR_GetSystemTick(); // 获取当前段号 uint8_t section = g_plsr_route.current_section_num; // 获取运行状态 PLSR_RunState_t state = g_plsr_route.run_state; // 获取脉冲计数 uint32_t pulse = g_plsr_route.pulse_count; ``` ### 调试建议 1. 使用串口输出关键状态信息 2. 监控段切换过程 3. 检查等待条件的触发时机 4. 验证加减速曲线的平滑性 ## 注意事项 1. **频率范围**: PWM频率建议在1Hz-100kHz范围内 2. **TIM6频率**: 建议设置为1ms,过快会增加CPU负担 3. **段号管理**: 段号从1开始,0表示结束 4. **内存管理**: 结构体较大,注意栈空间使用 5. **中断优先级**: 确保TIM6中断优先级适当 6. **线程安全**: 在多线程环境下注意数据保护 ## 常见问题 ### Q1: 脉冲输出不稳定 **A**: 检查TIM6更新频率设置,建议不要设置过快 ### Q2: 段切换不正常 **A**: 检查next_section设置和等待条件配置 ### Q3: 加减速不平滑 **A**: 调整加减速时间或选择合适的算法 ### Q4: 外部事件不响应 **A**: 确认外部事件标志设置正确 ## 版本信息 - **版本**: V2.0 - **更新日期**: 2025年1月 - **兼容性**: STM32 HAL库, UCOSII, 信捷PLC PLSR指令 - **作者**: AI Assistant ## 技术支持 如有技术问题,请检查: 1. 硬件连接是否正确 2. 定时器配置是否匹配 3. 中断是否正常触发 4. 参数配置是否合理 --- **注意**: 本文档基于重构后的PLSR系统V2.0版本,与之前版本不兼容。使用前请仔细阅读并理解各个功能模块的工作原理。