天天看點

環形隊列序列槽(發)應用

環形緩沖區的實作原理:

環形緩沖區通常有一個讀指針和一個寫指針。讀指針指向環形緩沖區中可讀的資料,寫指針指向環形緩沖區中可寫的緩沖區。通過移動讀指針和寫指針就可以實作緩沖區的資料讀取和寫入。在通常情況下,環形緩沖區的讀使用者僅僅會影響讀指針,而寫使用者僅僅會影響寫指針。如果僅僅有一個讀使用者和一個寫使用者,那麼不需要添加互斥保護機制就可以保證資料的正确性

(一)查詢方式 ---程式設計簡單,缺點耗時

void SendCommReqStr0(unsigned char *senddata,int length)

{

int m;

bit EA_state;

EA_state = EA;

EA = 0;

TI0 = 0;

for(m=0;m<length;m++)

{

SBUF0 = *(senddata+m);           //send DATA

while(TI0 == 0); 

TI0 = 0;

}

EA = EA_state;

}

(二) 非緩沖中斷方式 --不耗時,缺點資料無緩沖區,前面包的資料如果還未發完,後面又有包,前面包就會被後面包沖掉

unsigned char sendBuffer[100];

unsigned char sendBufCur,sendBufTotal;

void SendCommReqStr0(unsigned char *senddata,int length)

{

int m;

for(m=0;m<length;m++)

{

  sendBuffer = *(senddata+m);           //send DATA

}

        sendBufCur = 0;

        sendBufTotal = length;

        SBUF0 = senddata[0];

}

void ComInt() interrupt 4  

{   

    if(TI0)                            //發送中斷處理  

    {  

        TI0 = 0;                    //清标志 

        sendBufCur++;

        if(sendBufCur<sendBufTotal) 

        {

            SBUF0 = sendBuffer[sendBufCur];

        }

    }  

}

(三)環形隊列中斷方式 -- 不耗時,支援緩沖區

unsigned char SendItComm=1;

void SendCommBuffer(unsigned char *base, unsigned short size) 

{

        unsigned short i=0;

if (!size) { return; }

while (i<size) 

{  

CommSendBuffer[CommSendBufferTail]=base[i]; 

i++;

CommSendBufferTail++; 

if (CommSendBufferTail==DB_SENDMAXSIZE)

CommSendBufferTail=0;

}

}

if (SendItComm)  //當SendItComm為零時,表示上一幀資料還未發送完畢

{  

SBUF0=CommSendBuffer[CommSendBufferHead]; 

}

}

void CommISR(void) interrupt 4

{

if (TI0)

{

       TI0=0;

CommSendBufferHead++;

if (CommSendBufferHead==DB_SENDMAXSIZE)

{  

CommSendBufferHead=0;

}

if (CommSendBufferHead!=CommSendBufferTail)

{  

SBUF0=CommSendBuffer[CommSendBufferHead]; // send the next byte

SendItComm=0;

}

else

{

SendItComm=1;

}

}

}

繼續閱讀