ST语言控制电机往返运动
控制电机往返运动
配置:
三个接口接入电机
Two input:ContolWord,nTorque
one output:StatusWord
PROGRAM MAIN
VAR// 输入输出映射ControlWord AT %Q* : UINT; // 控制字输出(如映射到CANopen PDO)nTorque AT %Q*: INT; // 目标扭矩值StatusWord AT %I* : UINT; // 状态字输入(如映射到CANopen PDO)// 内部变量nState : INT := 0; // 状态机步骤(0-3)bEnable : BOOL := TRUE; // 总使能信号tTimer : TON; // 延时计时器tTimer1 : TON;bToggleTorque : BOOL := FALSE; // 扭矩方向切换标志bFirstTorque: BOOL := TRUE; // 标记首次输出(初始为+50);nCount: INT;
END_VAR// 主逻辑
//tTimer(IN := TRUE, PT := T#3S);
//IF tTimer.Q THEN
// nCount := nCount + 1;
// tTimer(IN := FALSE);
// tTimer(IN := TRUE);
//END_IFIF bEnable THENCASE nState OF// --- 状态机切换流程 ---0: // 初始状态:Not Ready to Switch On → Switch On Disabled(自动跳转,无需操作)IF StatusWord = 16#40 THEN nState := 1; // 等待进入Switch On DisabledEND_IF;1: // Switch On Disabled → Ready to Switch On(发送0x06)ControlWord := 16#06;IF StatusWord = 16#21 THEN nState := 2; // 确认状态字变为0x21END_IF;2: // Ready to Switch On → Switched On(发送0x07)ControlWord := 16#07;IF StatusWord = 16#23 THEN nState := 3; // 确认状态字变为0x23END_IF;3: // Switched On → Operation Enabled(发送0x1F)ControlWord := 16#1F;IF StatusWord = 16#27 THEN nState := 4; tTimer(IN := TRUE, PT := T#3S); // 关键修复:进入状态4时立即启动计时器END_IF;// --- 扭矩输出循环 ---4: // IF tTimer.Q THEN // 每次计时到达1秒时执行
// tTimer(IN := FALSE); // 复位计时器
// nCount := nCount + 1;
// // 按顺序输出+50或-50
// IF bFirstTorque THEN
// nTorque := 50; // 正向扭矩
// ELSE
// nTorque := -50; // 反向扭矩
// END_IF;// bFirstTorque := NOT bFirstTorque; // 切换标记
// // 重新启动1秒计时// tTimer(IN := TRUE, PT := T#3S);
// END_IFtTimer1(IN := TRUE, PT := T#1500MS); IF tTimer1.Q THEN // 每次计时到达1秒时执行tTimer1(IN := FALSE); // 复位计时器nCount := nCount + 1;// 按顺序输出+50或-50IF bFirstTorque THENnTorque := 50; // 正向扭矩ELSEnTorque := -50; // 反向扭矩END_IF;bFirstTorque := NOT bFirstTorque; // 切换标记tTimer1(IN := TRUE, PT := T#1500MS); END_IF END_CASE
END_IF//CASE nState OF
// // --- 状态机切换流程 ---
// 4:
// tTimer1(IN := TRUE, PT := T#3S);
// IF tTimer1.Q THEN // 每次计时到达1秒时执行
// tTimer1(IN := FALSE); // 复位计时器
// nCount := nCount + 1;
// tTimer1(IN := TRUE, PT := T#3S);
// END_IF
//END_CASE