環形緩沖區的實作原理:
環形緩沖區通常有一個讀指針和一個寫指針。讀指針指向環形緩沖區中可讀的資料,寫指針指向環形緩沖區中可寫的緩沖區。通過移動讀指針和寫指針就可以實作緩沖區的資料讀取和寫入。在通常情況下,環形緩沖區的讀使用者僅僅會影響讀指針,而寫使用者僅僅會影響寫指針。如果僅僅有一個讀使用者和一個寫使用者,那麼不需要添加互斥保護機制就可以保證資料的正确性
(一)查詢方式 ---程式設計簡單,缺點耗時
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;
}
}
}