环形队列串口(发)应用

来源:互联网 发布:java工程师简历 编辑:程序博客网 时间:2024/06/05 08:35
环形缓冲区的实现原理:


环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性


(一)查询方式 ---编程简单,缺点耗时
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;
}
}

}

0 0
原创粉丝点击