C语言|举报|字号 订阅
如题,我项目里的中断方式串口发送工作得很好。尤其是对实时性要求较高且数据量较大且发送频繁时,优势较循环查询式不言而喻。
具体思路是采用FIFO队列作为待发数据的缓冲,每次把要发送的数据入列,同时启动发送。在中断函数中每次从队列中取一个字节发送,直至队列空。
这个队列采用“环形队列”,即把它看作首尾相连的(虽然内存是线形的),这样好处理,指针加1可以采用加1求模来算。
下面贴出队列的代码,如果有数据结构的基础,那么很容易理解:
#include "stdlib.h"
#define OK 1
#define ERROR 0
struct LoopQueue{
unsigned char elemsize; //队列元素大小
unsigned char maxlength; //队列最大长度(留一个不用,用来判断队列满)
void *pBase; //队列基地址
unsigned char front; //列首元素位置(不含地址信息,0~maxlength-1)
unsigned char rear; //列尾元素位置(不含地址信息,0~maxlength-1)
};
unsigned char InitQueue(struct LoopQueue *pQueue)
{
pQueue->pBase = malloc(pQueue->elemsize * pQueue->maxlength);
pQueue->front = pQueue->rear = 0;
if(pQueue->pBase != NULL)
return OK;
else
return ERROR;
}
unsigned char QueueLength(struct LoopQueue *pQueue)
{
return pQueue->rear < pQueue->front ?
pQueue->rear + pQueue->maxlength - pQueue->front :
pQueue->rear - pQueue->front;
}
unsigned char EnterQueue(struct LoopQueue *pQueue, void *pData)
{
unsigned char next = (pQueue->rear + 1) % pQueue->maxlength;
unsigned char i;
if(next == pQueue->front) //若尾指针的下一位置是头指针,队列满
return ERROR;
for(i = 0; i < pQueue->elemsize; i++)
*((unsigned char *)pQueue->pBase + pQueue->elemsize * pQueue->rear + i) =
*((unsigned char *)pData + i);
pQueue->rear = next;
return OK;
}
unsigned char ExitQueue(struct LoopQueue *pQueue, void *pData)
{
unsigned char i;
if(pQueue->front == pQueue->rear) //队列空
return ERROR;
for(i = 0; i < pQueue->elemsize; i++)
*((unsigned char *)pData + i) =
*((unsigned char *)pQueue->pBase + pQueue->elemsize * pQueue->front + i);
pQueue->front = (pQueue->front + 1) % pQueue->maxlength;
return OK;
}
unsigned char EmptyQueue(struct LoopQueue *pQueue)
{
if(pQueue->pBase == NULL)
return ERROR;
else
{
pQueue->front = pQueue->rear = 0;
return OK;
}
}
掌握了,还可以用到其它地方。比如可以做一个类似Windows的实现消息驱动的消息队列,实时处理各消息和指令等。