循环队列
1.使用流程
1.确定队列数组长度,在功能块中填入
2.将功能块调用,并按照下图中填入相应参数
2.SCL代码
代码为.scl文件,使用方法:将代码复制到文本文档中.txt,将文件类型改为.scl,完成后在博途添加外部文件,选择从源生成块即可生成FB。
FUNCTION_BLOCK "FB_RingQueue"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
bPush : Bool;//入队
bPop : Bool;//出队
bReset : Bool;//复位
END_VAR
VAR_OUTPUT
bError : Bool;//故障状态
wStatus : Word;//故障代码
END_VAR
VAR_IN_OUT
iItem : Int;//入队或出队的元素
ioQueue : Array[0..10] OF Int;//队列空间
END_VAR
VAR
statQueueIndex : DInt;
bPush_ek_1 : Bool;//入队上一时刻状态
bPop_ek_1 : Bool;//出队上一时刻状态
bReset_ek_1 : Bool;//复位上一时刻状态
END_VAR
VAR_TEMP
tempQueueSize : Word;//已经使用的队列空间
tempCount : DInt;
END_VAR
VAR CONSTANT
QUEUE_FULL : Word := 16#8A04;//队列已满;
QUEUE_EMPTY : Word := 16#8A05;//队列已空;
END_VAR
BEGIN
//循环队列功能块
//Lucas
//2024-11-5
//设置堆栈长度
REGION QueueSize
#tempQueueSize := 11;
END_REGION
//入队
REGION #bPush
IF #bPush_ek_1 = FALSE & #bPush = TRUE THEN
#ioQueue[#statQueueIndex] := #iItem;
#statQueueIndex += 1;
IF #statQueueIndex > #tempQueueSize - 1 THEN
#statQueueIndex := 0;
END_IF;
END_IF;
#bPush_ek_1 := #bPush;
END_REGION
//出队
REGION #bPop
IF #bPop_ek_1=FALSE & #bPop = TRUE THEN
IF #statQueueIndex=0 THEN
#bError := true;
#wStatus := #QUEUE_EMPTY;
RETURN;
ELSE
#iItem := #ioQueue[0];
FOR #tempCount := 0 TO #statQueueIndex - 2 DO
#ioQueue[#tempCount] := #ioQueue[#tempCount + 1];
END_FOR;
#statQueueIndex -= 1;
#ioQueue[#statQueueIndex + 1] := 0;
END_IF;
END_IF;
#bPop_ek_1 := #bPop;
END_REGION
REGION Reste
IF #bReset_ek_1 = false & #bReset = TRUE THEN
#bError := 0;
#wStatus := 0;
END_IF;
#bReset_ek_1 := #bReset;
END_REGION
END_FUNCTION_BLOCK
顺序队列
1.使用方法
顺序队列的使用方法和循环队列的使用方法一致,请参考循环队列使用方法
2.顺序队列与循环队列区别
顺序队列数组会被添加满,例:11个数据的数组,我添加数据11次,他就不能添加数据了,必须取出才能继续添加
而循环队列不会被加满,当数据加到对应数组的长度后,再次添加队列会从数组的第一个开始添加
3.SCL代码
代码为.scl文件,使用方法:将代码复制到文本文档中.txt,将文件类型改为.scl,完成后在博途添加外部文件,选择从源生成块即可生成FB。
FUNCTION_BLOCK "FB_SeqQueue"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
bPush : Bool;//入队
bPop : Bool;//出队
bReset : Bool;//复位
END_VAR
VAR_OUTPUT
bError : Bool;//故障状态
wStatus : Word;//故障代码
END_VAR
VAR_IN_OUT
iItem : Int;//入队或出队的元素
ioQueue : Array[0..10] OF Int;//队列空间
END_VAR
VAR
statQueueIndex : DInt;//指针
bPush_ek_1 : Bool;//入队上一时刻状态
bPop_ek_1 : Bool;//出队上一时刻状态
bReset_ek_1 : Bool;//复位上一时刻状态
END_VAR
VAR_TEMP
tempQueueSize : Word;//已经使用的队列空间
tempCount : DInt;
END_VAR
VAR CONSTANT
QUEUE_FULL : Word := 16#8A04;//队列已满;
QUEUE_EMPTY : Word := 16#8A05;//队列已空;
END_VAR
BEGIN
//顺序队列
//Lucas
//2024-11-5
//设置堆栈长度
REGION QueueSize
#tempQueueSize := 11;
END_REGION
//入队
REGION #bPush
IF #bPush_ek_1=FALSE & #bPush=TRUE THEN
IF #statQueueIndex >= #tempQueueSize THEN
#bError := true;
#wStatus := #QUEUE_FULL;
RETURN;
END_IF;
#ioQueue[#statQueueIndex] := #iItem;
#statQueueIndex += 1;
END_IF;
#bPush_ek_1 := #bPush;
END_REGION
//出队
REGION bPop
IF #bPop_ek_1=FALSE & #bPop=true THEN
IF #statQueueIndex=0 THEN
#bError := true;
#wStatus := #QUEUE_EMPTY;
RETURN;
ELSE
#iItem := #ioQueue[0];
FOR #tempCount := 0 TO #statQueueIndex - 2 DO
#ioQueue[#tempCount] := #ioQueue[#tempCount + 1];
END_FOR;
#statQueueIndex -= 1;
#ioQueue[#statQueueIndex + 1] := 0;
END_IF;
END_IF;
#bPop_ek_1 := #bPop;
END_REGION
//复位
REGION Reste
IF #bReset_ek_1=false & #bReset=TRUE THEN
#bError := 0;
#wStatus := 0;
END_IF;
#bReset_ek_1 := #bReset;
END_REGION
END_FUNCTION_BLOCK