聊天中无聊说起先进先出队列,手搓了1个
''先进先出队列(用数组做缓存区)Type FIFO_LONG
Buff() As Long
xSizeAs Long
CountAs Long
Head As Long
End Type
Dim Fifo As FIFO_LONG
Sub FIFO_INIT(ByVal nSize As Long)
If nSize <= 8 Then nSize = 8
ReDim Fifo.Buff(0 To nSize - 1)
Fifo.xSize = nSize
Fifo.Head= 0
Fifo.Count = 0
End Sub
Function FIFO_PUSH(ByRef x As Long) As BOOLEAN '压入数据(尾部)
If Fifo.Count = Fifo.xSize Then Exit Function
Dim i As Long : i = Fifo.Head + Fifo.Count
If i >= Fifo.xSize Then i = i - Fifo.xSize
Fifo.Count = Fifo.Count + 1
Fifo.Buff(i) = x : FIFO_PUSH = True
End Function
Function FIFO_SHIFT(ByRef x As Long) As BOOLEAN '吐出数据(头部)
If Fifo.Count = 0 Then Exit Function
Dim i As Long : i = Fifo.Head
Fifo.Head = Fifo.Head + 1
If Fifo.Head = Fifo.xSize Then Fifo.Head = 0
Fifo.Count = Fifo.Count - 1
x = Fifo.Buff(i) : FIFO_SHIFT = True
End Function 你能不能做一个能一下子吐出很多数据、一下子压入很多数据的 FIFO?一个数据一个数据地压入、吐出,对 IO 效率很不友好。尤其是像单片机实现 USB CDC 转串口 TTL 这块就需要 FIFO 能做到数据的批量读入写出(因为可以用到 DMA)。 本帖最后由 tlwh163 于 2024-7-3 19:59 编辑
有点草率 只能说对简单数据类型 勉强可以用 请指正!
Type FIFO_LONG
As Long Buff() '队列空间
As Long xSize '缓存容量
As Long iHead '数据首的下标
As Long Count '有效数据长度
End Type
Dim Fifo As FIFO_LONG
Sub FIFO_INIT(ByVal nSize As Long)
If nSize < 8 Then nSize = 8'最小容量8
ReDim Fifo.Buff(0 To nSize + nSize - 1) '多1倍空间便于操作
Fifo.xSize = nSize : Fifo.iHead = 0 : Fifo.Count = 0
End Sub
'尾部压入数据(源数据地址,申请数量)返回:实际装入数量
Function FIFO_PUSH(ByVal xPtr As Long, ByVal xCount As Long) As Long
If xPtr = 0 Or xCount <= 0 Or Fifo.Count = Fifo.xSize Then
FIFO_PUSH = 0 : Exit Function
End If
If (Fifo.Count + xCount) > Fifo.xSize Then'装不下了
xCount = (Fifo.xSize - Fifo.Count) '多的数据丢弃
End If
Dim k As Long : k = (Fifo.iHead + Fifo.Count)
If k >= Fifo.xSize Then k = k - Fifo.xSize'队列的插入点下标
memcpy Varptr(Fifo.Buff(k)), xPtr, xCount * LenB(Fifo.Buff(0))
Fifo.Count = Fifo.Count + xCount '修正队列计数器
FIFO_PUSH = xCount '返回实际接收多少个数据
k = k + xCount - Fifo.xSize
If k > 0 Then '队列空间外的数据(如果有),移动到队列下标0
k = k * LenB(Fifo.Buff(0))
memcpy Varptr(Fifo.Buff(0)), Varptr(Fifo.Buff(Fifo.xSize)), k
End If
End Function
''头部吐出数据(目标地址,请求数量)返回:实际吐出数量
Function FIFO_SHIFT(ByVal xPtr As Long, ByVal xCount As Long) As Long
If xPtr = 0 Or xCount <= 0 Or Fifo.Count = 0 Then
FIFO_SHIFT = 0 : Exit Function
End If
If Fifo.Count < xCount Then xCount = Fifo.Count'能吐多少吐多少
Dim k As Long : k = Fifo.iHead + xCount
If k >= Fifo.xSize Then k = k - Fifo.xSize'新的队列首下标
If k > 0 Then '需要将队列头部的数据,搬一些到队列空间的尾部
memcpy Varptr(Fifo.Buff(Fifo.xSize)), Varptr(Fifo.Buff(0)), k * LenB(Fifo.Buff(0))
End If
memcpy xPtr, Varptr(Fifo.Buff(Fifo.iHead)), xCount * LenB(Fifo.Buff(0))
Fifo.Count = Fifo.Count - xCount '修正队列计数器
Fifo.iHead = k '修正队列首下标
FIFO_SHIFT = xCount '返回实际吐出多少个数据
End Function
页:
[1]