C语言数据结构之管道浅析
生活随笔
收集整理的這篇文章主要介紹了
C语言数据结构之管道浅析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
管道是什么?
管道是先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),相當(dāng)于一個(gè)緩沖區(qū);
數(shù)據(jù)長度一般是1Byte,這里設(shè)置管道緩沖區(qū)為512Byte;
管道的作用是?
有時(shí)候需要一定長度的數(shù)據(jù),不僅僅是1Byte;
實(shí)現(xiàn)思路:申請緩沖區(qū)
》使用兩個(gè)指針分別指向緩沖區(qū)的首地址和尾地址,例如begin,end
—》要實(shí)現(xiàn)隨時(shí)找到管道中任意一個(gè)成員,使用兩個(gè)指針分別指向第一個(gè)成員(head)和最后一個(gè)成員(tail)
—》使用環(huán)形緩沖區(qū)存儲(chǔ)數(shù)據(jù)
如何使用管道?
以下程序的管道 = 管道結(jié)構(gòu)體+緩沖區(qū);
//定義一個(gè)管道結(jié)構(gòu)體 typedef struct _Pipe_t {uint8_t * beginPtr; //管道內(nèi)存塊首地址uint8_t * headPtr; //管道元素首部,指向下一個(gè)要存儲(chǔ)的地址uint8_t * tailPtr; //管道元素尾部,指向下一個(gè)要讀取的地址uint8_t * endPtr; //管道內(nèi)存塊尾部 ,最后一個(gè)內(nèi)存地址+1 } Pipe_t;//初始化管道,申請緩沖區(qū) //參數(shù)1:結(jié)構(gòu)體指針 //參數(shù)2:緩沖區(qū)(數(shù)組)首地址 //參數(shù)3:緩沖區(qū)大小 //示例:pipe_init(&TLSR8266_pipe, (uint8_t *)Usart3_buff,USART3_BUFF_SIZE); void pipe_init(Pipe_t *pipe, uint8_t * buffer, uint16_t size) { (*pipe).beginPtr = buffer; (*pipe).headPtr = buffer; (*pipe).tailPtr = buffer; (*pipe).endPtr = buffer+size; }//從管道中讀取數(shù)據(jù) //參數(shù)1:管道名 //參數(shù)2:讀取數(shù)值,存放到value //示例:pipe_read(&TLSR8266_pipe, &buf[4]); bool pipe_read(Pipe_t *pipe, uint8_t * value) {if((*pipe).headPtr != (*pipe).tailPtr){*value = *((*pipe).tailPtr);(*pipe).tailPtr++;if((*pipe).tailPtr == (*pipe).endPtr)(*pipe).tailPtr = (*pipe).beginPtr;return true;}else{*value = 0xFF;//也可以是0x00吧return false;} }//向管道寫入數(shù)據(jù) //參數(shù)1:管道名 //參數(shù)2:要寫入的數(shù)值 //示例:pipe_write(&TLSR8266_pipe,ch); //一般用于中斷服務(wù)函數(shù)里面讀取到的數(shù)據(jù),寫入; bool pipe_write(Pipe_t *pipe, uint8_t value) {if((*pipe).headPtr != (*pipe).tailPtr - 1)//判斷管道元素首部是否與管道元素尾部相同,相同表示存滿{if(((*pipe).headPtr != (*pipe).endPtr -1) || ((*pipe).tailPtr != (*pipe).beginPtr))//判斷管道元素首部是否存放到管道尾地址,或者管道元素尾部是否存放到管道首地址{*((*pipe).headPtr) = value; //數(shù)據(jù)存放到管道元素首部(*pipe).headPtr++; //管道元素首部向后移一位if((*pipe).headPtr == (*pipe).endPtr)//如果管道元素首部等于管道尾地址,即存滿管道了{(lán)(*pipe).headPtr = (*pipe).beginPtr;//管道元素首部指向管道首地址(環(huán)形內(nèi)存)}return true;}else{return false;}}else{return false;} }下面以TLRS 8266的藍(lán)牙模塊為例,使用管道存儲(chǔ)和讀取藍(lán)牙數(shù)據(jù)
//初始化藍(lán)牙模塊的時(shí)候,應(yīng)該一起初始化管道,也是申請一個(gè)管道; pipe_init(&TLSR8266_pipe, (uint8_t *)Usart3_buff,USART3_BUFF_SIZE);//主要用途是使用管道存儲(chǔ)和讀取藍(lán)牙數(shù)據(jù)//封裝“pipe_read”函數(shù) /********************************************************** **函數(shù)功能:讀取AT指令發(fā)送后返回的值 **buf數(shù)組大小固定為6個(gè)元素 ***********************************************************/ static void TLSR8266_ReadReturn(unsigned char* buf) {pipe_read(&TLSR8266_pipe, &buf[0]);pipe_read(&TLSR8266_pipe, &buf[1]);pipe_read(&TLSR8266_pipe, &buf[2]);pipe_read(&TLSR8266_pipe, &buf[3]);pipe_read(&TLSR8266_pipe, &buf[4]);pipe_read(&TLSR8266_pipe, &buf[5]); } uint8_t buf[6] = {0}; TLSR8266_ReadReturn(buf); printf("buf : %s\r\n",buf);//打印出從管道讀取的數(shù)據(jù)//藍(lán)牙模塊接收手機(jī)發(fā)送來的數(shù)據(jù),存放到管道里面 void USART3_IRQHandler(void) {if(USART_GetFlagStatus(USART3, USART_FLAG_IDLE) != RESET){}if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET){USART_ReceiveData(USART3);//接收到數(shù)據(jù)}//接收完的一批數(shù)據(jù),還沒有被處理,則不再接收其他數(shù)據(jù)if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){uint8_t ch = USART3->DR;USART_ClearITPendingBit (USART3, USART_IT_RXNE);if(TLSR8266_pipe_enable)pipe_write(&TLSR8266_pipe,ch);//向管道寫入數(shù)據(jù)usart1_putc(ch);//把藍(lán)牙接收的數(shù)據(jù)顯示在串口上 // printf("%x ",ch);//十六進(jìn)制顯示} }至此,基本完成對管道的使用;
代碼鏈接:https://pan.baidu.com/s/1DUtrQLRgiwj7_tOsszDL-g 密碼:a3xy
總結(jié)
以上是生活随笔為你收集整理的C语言数据结构之管道浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python简单开发接口
- 下一篇: linux增加端口失败,端口没被占用,怎