寫了一個,沒有測試,實現方式和15樓基本一致,上代碼
----------------------------------------------------------------------------分割線-------------------------------------------------------------
FUNCTION_BLOCK FB_啟動定位
(*一圈360度,分為12個段點,每個段點30度,每個段點都有一個開關,每個開關可以任意設置ON和OFF狀態。
當開關打開的區間,步進電機以正常速度旋轉,并在段點停留0.5秒,
沒有打開段點的區間,以快于正常速度進行旋轉,且不做停留*)
VAR_INPUT
Sen1 :BOOL;//位置狀態設置1
Sen2 :BOOL;
Sen3 :BOOL;
Sen4 :BOOL;
Sen5 :BOOL;
Sen6 :BOOL;
Sen7 :BOOL;
Sen8 :BOOL;
Sen9 :BOOL;
Sen10:BOOL;
Sen11:BOOL;
Sen12:BOOL;//位置狀態設置12
Start :BOOL;//啟動
Stop :BOOL;//停止
Auto :BOOL;//手自,TRUE:自動;FALSE:手動
Done :BOOL;//定位完成信號
Now_Ang :REAL;//當前角度
Tim :REAL;//TRUE位停頓時間,單位:s
END_VAR
VAR_OUTPUT
rRun_F :REAL;//快速運行距離(FALSE段角度)
bRun_F :BOOL;//快速定位啟動(FALSE段)
rRun_T :REAL;//正常速度運行距離(TRUE段角度)
bRun_T :BOOL;//正常速定位啟動(TRUE段)
END_VAR
VAR
Pto :BOOL;//定位啟動信號
nums:INT :=12;//位置個數
Now_posi :INT;//轉盤當前位置
StatsAry :ARRAY[1..12]OF BOOL;//各位置檢測傳感器狀態存儲數組
rtri :BOOL;//位置計算觸發
i,j :INT;//循環變量
False_Gap :INT;//距離下一個FALSE信號需要轉動的位置個數
num :INT;//定位中的段記錄
rstr,rsto,rdon :R_TRIG;//啟動,停止,轉動一個角度的觸發沿
rton :TON;//間隔定時
END_VAR
----------------------------------------------------------------------------分割線-------------------------------------------------------------
(*==============================參數初始化==============================*)
StatsAry[1]:=Sen1;StatsAry[2]:=Sen2;StatsAry[3]:=Sen3;StatsAry[4]:=Sen4;StatsAry[5]:=Sen5;StatsAry[6]:=Sen6;
StatsAry[7]:=Sen7;StatsAry[8]:=Sen8;StatsAry[9]:=Sen9;StatsAry[10]:=Sen10;StatsAry[11]:=Sen11;StatsAry[12]:=Sen12;
rRun_T:=(2*3.14159265)/nums;
Now_posi:=REAL_TO_INT((Now_Ang*nums)/(2*3.14159265))+1;
(*==============================觸發沿==============================*)
rstr(CLK:=Start);//啟動沿
rsto(CLK:=Stop);//停止沿
rdon(CLK:=Done);//定位完成沿
rton(IN:=num=2,PT:=REAL_TO_TIME(Tim*1000.0));//間隔定時
IF rsto.Q OR (rton.Q AND NOT Auto) THEN//停止或者在手動狀態下單次定位結束
bRun_F:=FALSE;
bRun_T:=FALSE;
num:=0;
END_IF
IF rdon.Q THEN//對定位次數進行計數
num:=num+1;
END_IF
(*==============================尋找下一次轉動的TRUE信號的位置==============================*)
IF rstr.Q OR (rton.Q AND Auto)THEN//啟動計算
num:=0;
rtri:=TRUE;
END_IF
IF rtri THEN
IF Now_posi<>nums THEN//TRUE位置在當前位置前方
FOR i:=Now_posi+1 TO nums BY 1 DO
IF StatsAry THEN
False_Gap:=i-Now_posi-1;//TRUE位置在當前位置前方
rRun_F:=rRun_T*False_Gap;
Pto:=TRUE;
rtri:=FALSE;
EXIT;
END_IF
END_FOR
END_IF
IF Now_posi<>1 THEN//TRUE位置在當前位置后方
FOR j:=1 TO Now_posi BY 1 DO
IF StatsAry[j] THEN
False_Gap:=nums-j+Now_posi-1;//TRUE位置在當前位置后方
rRun_F:=rRun_T*False_Gap;
Pto:=TRUE;
rtri:=FALSE;
EXIT;
END_IF
END_FOR
END_IF
END_IF
(*==============================執行邏輯==============================*)
IF Pto THEN//啟動定位,或自動狀態下定時器達到計時
bRun_T:=FALSE;
bRun_F:=TRUE;
END_IF
IF num=1 THEN//完成FALSE段的定位,進行TRUE段定位
bRun_F:=FALSE;
bRun_T:=TRUE;
END_IF