MCU的环形FIFO

fifo.h

#ifndef __FIFO_H
#define __FIFO_H

#include "main.h"

#define RINGBUFF_LEN	(500)     //定义最大接收字节数 500

typedef struct
{
    uint16_t Head;   										// 头指针 指向可读起始地址  每读一个,数字+1
    uint16_t Tail;											// 尾指针	指向可写的起始地址	 每写一个,数字+1,当尾指针超过数组大小,
																				// 则尾指针又指向数组首地址。
    uint16_t Lenght;										// 长度
    uint8_t  Ring_data[RINGBUFF_LEN];		// 数据缓冲区
}RingBuff_t;



uint16_t getRingBuffLenght(RingBuff_t *ringBuff);    // 获取缓冲区长度
void initRingBuff(RingBuff_t *ringBuff);
void writeRingBuff(RingBuff_t *ringBuff,uint8_t data);									 // 写入对应数据
void deleteRingBuff(RingBuff_t *ringBuff,uint16_t size);               // 删除对应长度的数据
uint8_t readRingBuff(RingBuff_t *ringBuff,uint16_t position);    // 读取对应位的数据




/*   使用示例

1.创建环形队列句柄

	RingBuff_t _ringBuff


2.初始化
		initRingBuff(&_ringBuff);	

3.添加数据

				HAL_UART_Receive_IT(&huart2,&_RxBuff[0],1);			// 打开串口中断	
				writeRingBuff(&_ringBuff,tjc_RxBuff[0]);
				

4. 数据包解析

#define FRAMELENGTH 6  // 数据包的长度

void DataAnalysis()
{

	  while(getRingBuffLenght(&tjc_ringBuff) >= FRAMELENGTH)    // 如果以及接收的数据长于数据包的长度
	  {
		  //校验帧头帧尾是否匹配
		  if(readRingBuff(&tjc_ringBuff,0) != 0x55 ||readRingBuff(&tjc_ringBuff,4) != 0xff || readRingBuff(&tjc_ringBuff,5) != 0xff)
		  {
			  deleteRingBuff(&tjc_ringBuff,1);									//不匹配删除1字节
		  }else												  //匹配
		  {																											// 数据处理 开始	 
				
					switch (readRingBuff(&tjc_ringBuff,1))			// 判断页面和控件
					{
						case 0x10:				// 左右
         
						
							break;
						default:
							break;
					}// 数据处理 结束		
			  deleteRingBuff(&tjc_ringBuff,FRAMELENGTH);							// 删除对应数据包的
			  break;
		  }
	  }
}


*/


#endif

fifo.c

#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <fifo.h>

/********************************************************
函数名:  	initRingBuff
功能:    	初始化环形缓冲区
输入参数:
返回值: 		void
修改记录:
**********************************************************/
void initRingBuff(RingBuff_t *ringBuff)
{
  //初始化相关信息
  ringBuff->Head = 0;
  ringBuff->Tail = 0;
  ringBuff->Lenght = 0;
}

/********************************************************
函数名:  	writeRingBuff
功能:    	往环形缓冲区写入数据  每次写入一个数据
**********************************************************/
void writeRingBuff(RingBuff_t *ringBuff,uint8_t data)
{
  if(ringBuff->Lenght >= RINGBUFF_LEN) 								//判断缓冲区是否已满
  {
    return ;
  }
  ringBuff->Ring_data[ringBuff->Tail]=data;							//写入到尾数据
  ringBuff->Tail = (ringBuff->Tail+1)%RINGBUFF_LEN;			//防止越界非法访问 Tail=RINGBUFF_LEN 就为0
																											//如果Tail指针已经到达缓冲区的末尾,那么Tail+1就会变成0   
  ringBuff->Lenght++;}																	// 数据长度+1

/********************************************************
函数名:  	deleteRingBuff
功能:    	删除串口缓冲区中相应长度的数据  从头删除指定长度
输入参数:	要删除的长度
**********************************************************/
void deleteRingBuff(RingBuff_t *ringBuff, uint16_t size)
{
	if(size >= ringBuff->Lenght)        // 确保小于以有数据
	{
	    initRingBuff(ringBuff);
	    return;
	}
	for(int i = 0; i < size; i++)
	{
		if(ringBuff->Lenght == 0)//判断非空
		{
			initRingBuff(ringBuff);
		return;
		}
		ringBuff->Head = (ringBuff->Head+1)%RINGBUFF_LEN;//防止越界非法访问
		ringBuff->Lenght--;
	}
}

/********************************************************
函数名:  	readRingBuff
功能:    	从串口缓冲区读取1字节数据
输入参数:		position:读取的位置
返回值: 		所在位置的数据(1字节)  
**********************************************************/
uint8_t readRingBuff(RingBuff_t *ringBuff, uint16_t position)
{
	uint16_t realPosition = (ringBuff->Head + position) % RINGBUFF_LEN;
	return ringBuff->Ring_data[realPosition];
}




/********************************************************
函数名:  	getRingBuffLenght
功能:    	获取串口缓冲区的数据数量
返回值: 		串口缓冲区的数据数量
**********************************************************/
uint16_t getRingBuffLenght(RingBuff_t *ringBuff)
{
	return ringBuff->Lenght;
}


/********************************************************
函数名:  	isRingBuffOverflow
功能:    	判断环形缓冲区是否已满
返回值: 		1:环形缓冲区已满 , 2:环形缓冲区未满
**********************************************************/
uint8_t isRingBuffOverflow(RingBuff_t *ringBuff)
{
	return ringBuff->Lenght == RINGBUFF_LEN;
}



### 回答1: 环形FIFO DMA接收是一种用于数据传输的技术。它通过创建一个环形缓冲区,实现高效、连续的数据接收。 首先,环形FIFO DMA接收需要一个环形缓冲区来存储接收到的数据。该缓冲区被划分为多个大小相等的单元,每个单元都有一个指针指向下一个存储位置。 当数据到达时,DMA控制器接收数据并将其写入环形缓冲区的当前位置。然后,指针指向下一个位置,并且DMA控制器继续接收数据并将其写入新的位置。如果指针到达缓冲区的末尾,则它将被重置为缓冲区的开始位置,实现循环。 接收端可以定期检查环形缓冲区中的数据。它可以使用指针来确定当前位置,并从该位置开始读取数据。如果指针到达缓冲区的末尾,则它将被重置为缓冲区的开始位置。 使用环形FIFO DMA接收有许多好处。首先,它可以实现高效的数据接收,因为DMA控制器可以连续地接收数据并减少CPU的负载。其次,它可以减少缓冲区溢出的风险,因为数据会循环写入缓冲区。最后,它可以实现无缝的数据接收,因为接收端可以定期读取和处理缓冲区中的数据,而无需等待整个数据传输完成。 总之,环形FIFO DMA接收是一种高效、连续的数据接收技术。它通过创建一个环形缓冲区来实现数据的循环写入和无缝接收。这种技术可以提高数据传输的效率,并减轻CPU的负担。 ### 回答2: 环形FIFO DMA接收是一种用于高效率数据传输的技术。DMA(直接内存访问)是一种通过绕过CPU将数据直接传输到内存的方式,可以显著提高数据传输速度和系统性能。 环形FIFO DMA接收是指将输入数据按照环形FIFO(先进先出)的方式进行接收处理。在传统的DMA接收中,数据被连续地写入内存中,这样在处理数据时需要频繁地重置读指针和写指针,增加了处理的复杂性。而使用环形FIFO的方式可以减轻这种负担。 在环形FIFO DMA接收中,接收数据的环形FIFO被划分为若干个固定大小的缓冲区,每个缓冲区用于存储一块数据。当接收到数据时,DMA控制器将数据直接写入当前空闲的缓冲区中,而不需要重置指针。当缓冲区写满时,DMA控制器会自动切换到下一个空闲的缓冲区。同时,处理器可以在后台处理上个缓冲区的数据,而不需要等待数据传输完成。 这种环形FIFO的设计使得数据传输和处理可以同时进行,提高了系统的效率和响应速度。同时,由于使用了固定大小的缓冲区,可以方便地进行数据管理和处理。 总结起来,环形FIFO DMA接收是一种高效率的数据传输技术,通过使用环形FIFO缓冲区,可以实现数据传输和处理的同时进行,提高系统的性能和响应速度。 ### 回答3: 环形FIFO DMA接收是一种用于数据传输的技术。它主要用于在计算机系统中,将数据从外部设备传输到内存中。 环形FIFO(First In First Out)是一种存储数据的方式,它类似于队列的概念。当有数据要被传输到内存时,这些数据首先被存储在环形FIFO中,并按照先进先出的原则进行传输。这种存储方式可以有效地处理大量的数据,减少数据传输中的延迟。 DMA(Direct Memory Access)是一种数据传输方式,它可以绕过CPU的干预,直接将数据从外部设备传输到内存中,减轻了CPU的负担。DMA操作由硬件控制器完成,提高了数据传输的效率。 环形FIFO DMA接收是将环形FIFO和DMA技术结合起来使用的一种数据接收方式。当数据从外部设备传输到内存时,首先经过DMA控制器的处理,然后进入环形FIFO进行存储。通过环形FIFO的存储方式,可以保证数据的顺序性,避免数据的丢失或混乱。 环形FIFO DMA接收在数据传输过程中具有很多优点。首先,它可以提高数据传输的速度和效率,减少CPU的负担。其次,由于环形FIFO的存储方式,数据可以按照先进先出的原则进行传输,确保数据的完整性和准确性。另外,环形FIFO DMA接收还能够处理大量的数据,适用于高频率的数据传输场景。 综上所述,环形FIFO DMA接收是一种高效、快速且可靠的数据传输方式,可以在计算机系统中广泛应用于数据接收和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值