好项目,不私藏!适用于单片机开发的开源轮子
點擊上方“小麥大叔”,選擇“置頂/星標公眾號”
福利干貨,第一時間送達
大家好,我是小麥。今天推薦一個適用于單片機裸機開發的開源輪子。
QueueForMcu
基于單片機實現的隊列功能模塊,主要用于8位、16位、32位非運行RTOS的單片機應用,兼容大多數單片機平臺。
開源代碼:https://github.com/xiaoxinpro/QueueForMcu
一、特性
動態創建隊列對象
動態設置隊列數據緩沖區
靜態指定隊列元素數據長度
采用值傳遞的方式保存隊列數據
二、快速使用
#include?"queue.h"#define?Q_UART_BUFFER_SIZE??1024QUEUE_HandleTypeDef?qUartTx; QUEUE_DATA_T?BufferUartTx[Q_UART_BUFFER_SIZE];int?main(void) {QUEUE_DATA_T?temp;//初始化隊列Queue_Init(&qUartTx,?BufferUartTx,?Q_UART_BUFFER_SIZE);while(1){//入隊Queue_Push(&qUartTx,?'Q');Queue_Push(&qUartTx,?'u');Queue_Push(&qUartTx,?'e');Queue_Push(&qUartTx,?'u');Queue_Push(&qUartTx,?'e');//出隊Queue_Pop(&qUartTx,?&temp);Queue_Pop(&qUartTx,?&temp);Queue_Pop(&qUartTx,?&temp);Queue_Pop(&qUartTx,?&temp);Queue_Pop(&qUartTx,?&temp);} }三、配置說明
目前QueueForMcu只有一個靜態配置項,具體如下:
在文件 queue.h 中有一個宏定義 QUEUE_DATA_T 用于指定隊列元素的數據長度,默認是 unsigned char ,可以根據需要更改為其他數據類型。
四、數據結構
隊列的數據結構為 QUEUE_HandleTypeDef 用于保存隊列的狀態,源碼如下:
typedef?struct?QUEUE_HandleTypeDef{unsigned?int?head;??????????????????????//隊列頭指針unsigned?int?tail;??????????????????????//隊列尾指針unsigned?int?buffer_length;?????????????//隊列緩存長度(初始化時賦值)QUEUE_DATA_T?*?buffer;??????????????????//隊列緩存數組(初始化時賦值) }QUEUE_HandleTypeDef;其中 QUEUE_DATA_T 為配置項中自定義的數據類型。
五、創建隊列
1、創建隊列緩存
由于我們采用值傳遞的方式保存隊列數據,因此我們在創建隊列前要手動創建一個隊列緩存區,用于存放隊列數據。
QUEUE_DATA_T?BufferUartTx[1024];以上代碼即創建一個大小為 1024 的隊列緩存區。
2、創建隊列結構
接下來使用 QUEUE_HandleTypeDef 創建隊列結構,用于保存隊列的狀態:
QUEUE_HandleTypeDef?qUartTx;3、初始化隊列
準備好隊列緩存和隊列結構后調用 Queue_Init 函數來創建隊列,該函數原型如下:
void?Queue_Init(QUEUE_HandleTypeDef?*?hqueue,?QUEUE_DATA_T?*?buffer,?unsigned?int?len)參數說明:
| hqueue | 需要初始化的隊列結構,如果二次初始化將清空原隊列的內容。 |
| buffer | 隊列緩存的首地址指針 |
| len | 隊列長度,不能比隊列緩存長度還要大。 |
參考代碼:
Queue_Init(&qUartTx,?BufferUartTx,?Q_UART_BUFFER_SIZE);六、壓入隊列
1、單數據壓入
將數據壓入隊列尾部使用 Queue_Push 函數,該函數原型如下:
QUEUE_StatusTypeDef?Queue_Push(QUEUE_HandleTypeDef?*?hqueue,?QUEUE_DATA_T?data)參數說明:
| hqueue | 需要壓入數據的隊列結構。 |
| data | 待壓入隊列的數據。 |
返回值說明:
該函數會返回一個 QUEUE_StatusTypeDef 枚舉數據類型,返回值會根據隊列狀態返回以下幾個值:
| QUEUE_OK | 數據壓入隊列成功。 |
| QUEUE_OVERLOAD | 未壓入數據到隊列中,原因隊列已滿。 |
參考代碼:
Queue_Push(&qUartTx,?'Q'); Queue_Push(&qUartTx,?0x51); Queue_Push(&qUartTx,?81);2、多數據壓入
若需要將多個數據(數組)壓入隊列可以使用 Queue_Push_Array 函數,原理上循環調用 Queue_Push 函數來實現的,函數原型如下:
unsigned?int?Queue_Push_Array(QUEUE_HandleTypeDef?*?hqueue,?QUEUE_DATA_T?*?pdatas,?unsigned?int?len)參數說明:
| hqueue | 需要壓入數據的隊列結構。 |
| pdatas | 待壓入隊列的數組首地址。 |
| len | 待壓入隊列的數組長度。 |
當數組長度大于隊列剩余長度時,數組多余的數據將被忽略。
返回值說明:
該函數將返回實際被壓入到隊列中的數據長度。
當隊列中的剩余長度富余時,返回值將等于參數 len 的值。
當隊列中的剩余長度不足時,返回值為實際被壓入到隊列的數據長度。
七、彈出隊列
1、單數據彈出
將隊列頭部數據彈出隊列使用 Queue_Pop 函數,需要注意的是,彈出的數據將從隊列中刪除,該函數原型如下:
QUEUE_StatusTypeDef?Queue_Pop(QUEUE_HandleTypeDef?*?hqueue,?QUEUE_DATA_T?*?pdata)參數說明:
| hqueue | 需要彈出數據的隊列結構。 |
| pdata | 用于保存彈出數據變量的指針。 |
返回值說明:
該函數會返回一個 QUEUE_StatusTypeDef 枚舉數據類型,返回值會根據隊列狀態返回以下幾個值:
| QUEUE_OK | 數據彈出隊列成功。 |
| QUEUE_VOID | 未彈出數據到隊列中,原因隊列為空。 |
參考代碼:
QUEUE_DATA_T?temp; if(QUEUE_OK?=?Queue_Pop(&qUartTx,?&temp)) {//?temp?為隊列彈出的數據 } else {//?彈出數據失敗 }2、多數據彈出
若需要將多個數據彈出隊列可以使用 Queue_Pop_Array 函數,原理上循環調用 Queue_Pop 函數來實現的,需要注意的是,成功彈出的數據將從隊列中刪除,函數原型如下:
unsigned?int?Queue_Pop_Array(QUEUE_HandleTypeDef?*?hqueue,?QUEUE_DATA_T?*?pdatas,?unsigned?int?len)參數說明:
| hqueue | 需要彈出數據的隊列結構。 |
| pdatas | 用于保存彈出數據數組的首地址。 |
| len | 需要彈出數據數組的長度。 |
當需要彈出數據的長度大于隊列中的數據長度時,彈出數組多余的空間將不會被賦值。
返回值說明:
該函數將返回實際從隊列中彈出的數據長度。
當隊列中的數據長度足夠時,返回值將等于參數 len 的值。
當隊列中的數據長度不足時,返回值為實際從隊列中彈出的數據長度。
3、單數據復制
當需要從隊列頭部獲取數據,但又不希望數據從隊列中刪除時,可以使用 Queue_Peek 函數來實現,該函數的參數與返回值與 Queue_Pop 完全相同。
使用 Queue_Peek 和 Queue_Pop 函數的區別在于:
Queue_Pop 得到隊列中的數據后會刪除隊列中的數據。
Queue_Peek 得到隊列中的數據后會保留隊列中的數據。
4、多數據復制
當需要從隊列頭部獲取多個數據,但又不希望數據從隊列中刪除時,可以使用 Queue_Peek_Array 函數來實現,該函數的參數與返回值與 Queue_Pop_Array 完全相同。
使用 Queue_Peek_Array 和 Queue_Pop_Array 函數的區別在于:
Queue_Pop_Array 得到隊列中的數據后會刪除隊列中的數據。
Queue_Peek_Array 得到隊列中的數據后會保留隊列中的數據。
八、其他功能
1、清空隊列
當需要清空隊列數據時,無需彈出所有數據,只需要調用 Queue_Clear 即可快速清空指定隊列,在創建隊列時會調用此函數來初始化隊列,因此對于剛創建完成的隊列無需調用清空隊列函數。
函數原型:
void?Queue_Clear(QUEUE_HandleTypeDef?*?hqueue)參數說明:
| hqueue | 需要清空的隊列結構。 |
2、獲取隊列數據數量
當需要獲取隊列中的數據長度時,調用 Queue_Count 函數,函數原型如下:
unsigned?int?Queue_Count(QUEUE_HandleTypeDef?*?hqueue)參數說明:
| hqueue | 需要獲取數據長度的隊列結構。 |
返回值說明:
該函數將返回隊列中的數據長度。
返回值范圍在0到創建隊列時的長度之間。
—— The End?——
往期推薦
單片機開發從來不用數據結構?
寫爛代碼的人離職之后...
難倒高手了,c語言枚舉end的作用是什么?
30個單片機常見問題解決辦法!一般人我不告訴他們
馬斯克的腦機接口,一塊樹莓派就能做出來?
加入嵌入式技術交流群一起進步
點擊上方名片關注我
你點的每個好看,我都認真當成了喜歡
總結
以上是生活随笔為你收集整理的好项目,不私藏!适用于单片机开发的开源轮子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022年技术胖私藏工具分享
- 下一篇: 私藏的google浏览器插件