本项目对原有的PLSR(脉冲输出指令)系统进行了全面重构,以符合信捷PLC的PLSR指令规范,并基于STM32 HAL库和UCOSII实时操作系统实现了完整的多段脉冲输出控制功能。
应用层 (Application Layer)
├── 用户配置接口
├── 状态监控接口
└── 控制命令接口
控制层 (Control Layer)
├── 路径控制模块 (Route Control)
├── 段控制模块 (Section Control)
├── 加减速控制模块 (Acceleration Control)
└── 等待条件处理模块 (Wait Condition)
驱动层 (Driver Layer)
├── PWM输出控制
├── 脉冲计数控制
└── 定时器中断处理
// 等待条件结构体
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;
// 加减速配置结构体
typedef struct {
uint32_t accel_time_ms; // 加速时间(ms)
uint32_t decel_time_ms; // 减速时间(ms)
PLSR_AccelAlgorithm_t accel_algorithm; // 加减速算法
} PLSR_AccelConfig_t;
// 段配置结构体
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;
// 路径控制结构体
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;
// PWM基础控制
void PLSR_PWM_Init(void);
void PLSR_PWM_Start(uint32_t frequency);
void PLSR_PWM_Stop(void);
uint8_t PLSR_PWM_IsRunning(void);
// PWM参数控制
void PLSR_PWM_SetFrequency(uint32_t frequency);
uint32_t PLSR_PWM_GetFrequency(void);
void PLSR_PWM_SetDutyCycle(uint32_t duty_cycle);
// TIM6频率配置
void PLSR_TIM6_SetUpdateFreq(uint32_t freq_us);
uint32_t PLSR_TIM6_GetUpdateFreq(void);
void PLSR_TIM6_Start(void);
void PLSR_TIM6_Stop(void);
// 路径基础控制
void PLSR_Route_Init(PLSR_RouteConfig_t* route);
void PLSR_Route_Start(PLSR_RouteConfig_t* route);
void PLSR_Route_Stop(PLSR_RouteConfig_t* route);
void PLSR_Route_Reset(PLSR_RouteConfig_t* route);
uint8_t PLSR_Route_IsRunning(PLSR_RouteConfig_t* route);
void PLSR_Route_Process(PLSR_RouteConfig_t* route);
// 段控制函数
void PLSR_Section_Init(PLSR_SectionConfig_t* section, uint8_t section_num);
void PLSR_Section_Process(PLSR_RouteConfig_t* route);
void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route);
void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route);
uint8_t PLSR_Section_CheckWaitCondition(PLSR_RouteConfig_t* route);
// 加减速算法
float PLSR_Accel_CalculateCurve(float progress, PLSR_AccelAlgorithm_t algorithm);
void PLSR_Accel_Process(PLSR_RouteConfig_t* route);
// 等待条件控制
void PLSR_Wait_StartTimer(PLSR_RouteConfig_t* route);
uint8_t PLSR_Wait_CheckTimeCondition(PLSR_RouteConfig_t* route);
uint8_t PLSR_Wait_CheckActTime(PLSR_RouteConfig_t* route);
uint8_t PLSR_Wait_CheckExtEvent(PLSR_RouteConfig_t* route);
// 外部事件控制
void PLSR_SetExtEvent(uint8_t flag);
void PLSR_ClearExtEvent(void);
void PLSR_SetSectionCondition(PLSR_RouteConfig_t* route, uint8_t section_num, uint8_t flag);
线性加减速 (PLSR_ACCEL_LINEAR)
// 线性变化
freq = start_freq + (target_freq - start_freq) * progress
曲线加减速 (PLSR_ACCEL_CURVE)
// S型曲线,平滑过渡
curve_factor = 3 * progress * progress - 2 * progress * progress * progress
freq = start_freq + (target_freq - start_freq) * curve_factor
正弦加减速 (PLSR_ACCEL_SINE)
// 正弦函数平滑变化
curve_factor = sin(PI/2 * progress)
freq = start_freq + (target_freq - start_freq) * curve_factor
IDLE → RUNNING → COMPLETED
↓ ↓ ↑
ERROR ←──┴─────────┘
IDLE → ACCEL → CONST → DECEL → WAIT → STOP
↑ ↓ ↓ ↓ ↓ ↓
└──────┴───────┴───────┴───────┴──────┘
IDLE → RUNNING → COMPLETED
↑ ↓ ↓
└───────┴─────────┘
PLSR/
├── Core/
│ ├── Inc/
│ │ └── tim.h # 头文件定义
│ └── Src/
│ └── tim.c # 主要实现文件
├── PLSR_系统使用说明_V2.md # 详细使用说明
├── PLSR_测试示例.c # 测试示例代码
└── 项目重构总结.md # 本文档
// 1. 系统初始化
PLSR_PWM_Init();
PLSR_TIM6_SetUpdateFreq(1000); // 1ms
PLSR_Route_Init(&g_plsr_route);
// 2. 配置段参数
g_plsr_route.section[0].target_freq = 5000;
g_plsr_route.section[0].target_pulse = 10000;
// ... 其他配置
// 3. 启动执行
PLSR_Route_Start(&g_plsr_route);
参考 PLSR_系统使用说明_V2.md
文档
参考 PLSR_测试示例.c
文件
问题: 频率切换时的平滑性
解决: 实现S型曲线算法,确保加速度连续
问题: 多种等待条件的优先级和组合
解决: 状态机设计,明确各种条件的处理逻辑
问题: 中断处理的实时性
解决: 优化中断处理函数,减少计算复杂度
问题: 结构体较大,栈空间限制
解决: 使用全局变量,合理设计数据结构
本次PLSR系统重构是一次全面的系统升级,从数据结构设计到功能实现都进行了重新规划。重构后的系统具有以下优势:
该系统可以广泛应用于步进电机控制、伺服电机控制、数控机床、自动化设备等领域,为工业自动化提供可靠的脉冲输出控制解决方案。
项目信息