队列-CAN通讯


最近在写can通讯的代码,发现在CAN通讯数据量比较大的时候,由于命令不能及时的处理导致部分CAN命令的丢失。后来查询资料发现可以采用队列的方式对CAN命令的传输做一个缓冲处理,这样可以在通讯量大的时候也能保证命令不丢失。以下就是我在学习队列过程中的方法和如何运用到CAN上。

队列的介绍

	队列就像一个单车道的隧道,来的车辆都要一个一个的通过,先来的车辆优先通过隧道,后来的车辆也就
后通过。整个过程用专业的词就是先入先出(FIFO)的原理。

图1 队列存储结构示意图

就像上图所示的一样,队列头相当于隧道的出口,队列尾相当于隧道的入口。来的车辆从队尾进入队头出去。

队列的实现(C语言)

下面就直接附上代码进行分析

先是入队函数

#define MAX_DATA_NUM 80	//队列最大的深度

int massage_data[80]={0};	//缓冲区

int fornt=0;	//出队的个数
int rear=0;	//记录入队的个数
int mark=0;	//缓冲区填满次数
/* 入队函数 */
int data_push(int *massage,int data)
{
	massage[rear] = data;
	rear ++;
	if(rear >= MAX_DATA_NUM){
		rear -= MAX_DATA_NUM;
		mark++;
	}
} 

在上述的代码中,rear就相当于隧道入口处的监控,记录着进入隧道的车辆数量。而massage就相当于是用来记录车辆车牌号的一张表格,表格的顺序按照rear来,而车牌号就是data。if后面的语句主要是用来防止队列的丢失。MAX_DATA_NUM 值的设定需要根据实际的使用环境来设定,该值设定的过小,若数据读取的速度过慢,很容易导致数据缓冲区溢出,从而导致数据丢失。若该值设定的过大,则会浪费内存空间。

出队函数

int data_pop(int *massage)
{
	if((fornt == rear)&&(mark == 0)){
		printf("\r\n队列元素已经全部出栈\r\n");
		return 0; 
	}
		
	printf("%2d ",massage[fornt]);
	fornt ++;
	if(fornt >= MAX_DATA_NUM){ 
		fornt -= MAX_DATA_NUM;
		mark--; 
	} 
	return 1;
	
}

出队函数就相当于是隧道出口的监控,当一辆车从出口驶出,则front加一,用来记录出隧道的车辆数量,同时去表格上查找对应编号的车辆信息。并输出通过入口时对应的车牌号。

主函数

int main() 
{
    int i,j=1;
    for(i=0;i<40;i++){
    	data_push(massage_data,i);
	}
	for(i=0;i<80;i++){
    	j = data_pop(massage_data);
    	if(j == 0)
    		break;
	}
    return 0;
}

队列在CAN中的实现代码

以下的代码是在stm32F205中实现的:
#define MAX_MASSAGE	 80
volatile uint32_t msg_rptr = 0, msg_wptr = 0; 
MASSAGE_TYPE MsgBuff[MAX_MASSAGE];

/*
 *	函数功能:消息传输计数
 */
int Massage_Count(void)
{
	int Count = msg_wptr;
	Count += MAX_MASSAGE;
	Count -= msg_rptr;
	if(Count >= MAX_MASSAGE)
		Count -= MAX_MASSAGE;
	return Count;
}
/*
 *	CAN消息数据出列
 */
MASSAGE_TYPE *Massage_Pop(void)
{
	if(Massage_Count() > 0) {
		int rptr = msg_rptr;
		msg_rptr ++;
		if(msg_rptr >= MAX_MASSAGE) {
			msg_rptr -= MAX_MASSAGE;
		}
		return &MsgBuff[rptr];
	}
	return NULL;
}

总结

	队列的使用不仅仅是在CAN通讯上,在生活中,队列的运用无处不还在,像医院的排队叫号,食堂排队打饭等等。
在一些网络通信中,还有对单纯队列改进后的链式队列。
	经过以上的简单学习,并运用到实际的项目中,感觉学习数据结构和算法不能单纯的仅仅是学习,而是应该考
虑在实际的项目中应该如何去使用它,并且思考在哪些方面可以使用,以便于以后遇到的时候可以及时的想起来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值