单片机-自建C库函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文

文章目录

  • 前言
  • 一、位操作运算
  • 二、状态滤波
    • 2.1
    • 2.2
  • 三 缓存空间
  • 四 滤波算法
    • 4.1 平均值滤波
  • 五 环形队列
    • 5.1
    • 5.2
    • 5.3
  • 总结


前言

在单片机开发项目的过程中,有很多与硬件无关的操作,比如位操作、滤波操作等。很多时候我们将它封装成库,在以后的代码编写过程中我们就可以直接移植就可以。

一、位操作运算

#define LIB_SET_UINT32_BIT(Data, Offset)    ((Data) |= (uint32)((uint32)1u << (Offset)))
#define LIB_SET_UINT16_BIT(Data, Offset)    ((Data) |= (uint16)((uint16)1u << (Offset)))
#define LIB_SET_UINT8_BIT(Data, Offset)     ((Data) |= (uint8)((uint8) 1u << (Offset)))

#define LIB_RESET_UINT32_BIT(Data, Offset)  ((Data) &= (uint32)(~(uint32)((uint32)1u << (Offset))))
#define LIB_RESET_UINT16_BIT(Data, Offset)  ((Data) &= (uint16)(~(uint16)((uint16)1u << (Offset))))
#define LIB_RESET_UINT8_BIT(Data, Offset)   ((Data) &= (uint8 )(~(uint8 )((uint8 )1u << (Offset))))

#define LIB_GET_UINT32_BIT(Data, Offset)    (((uint8)(((uint32) (Data)) >> (Offset))) & (uint8)0x01u)
#define LIB_GET_UINT16_BIT(Data, Offset)    (((uint8)(((uint16) (Data)) >> (Offset))) & (uint8)0x01u)
#define LIB_GET_UINT8_BIT(Data, Offset)     (((uint8)(((uint8 ) (Data)) >> (Offset))) & (uint8)0x01u)

#define LIB_GET_BYTE_0(Data)                ((uint8) (Data))
#define LIB_GET_BYTE_1(Data)                ((uint8)((Data)>>(uint8)8u))
#define LIB_GET_BYTE_2(Data)                ((uint8)((Data)>>(uint8)16u))
#define LIB_GET_BYTE_3(Data)                ((uint8)((Data)>>(uint8)24u))

#define LIB_GET_BYTE_LIT_UINT16(Data)		((uint16)Data[0u] + ((uint16)Data[1u] << 8u))
#define LIB_GET_BYTE_BIG_UINT16(Data)		((uint16)Data[1u] + ((uint16)Data[0u] << 8u))

二、状态滤波

2.1

typedef struct Type_FilterStruct
{
    uint8 ucStatus;
    uint8 ucLastStatus;
    uint8 ucValidStatus;
    uint16 usFilterCount;

} LibFilterStruct;
uint8 LIB_StatusFilter( LibFilterStruct *pFilterStatus, uint16 filterMaxCnt )
{
    uint8  e_u_reValue = FALSE;
    uint16 e_w_filterMaxCnt = (uint16)0u;

    if(( filterMaxCnt > (uint16)0u ) && ( filterMaxCnt < LIB_MAXVALUE_16 ))
    {
        e_w_filterMaxCnt = filterMaxCnt;
    }
    else
    {
        e_w_filterMaxCnt = LIB_MAXVALUE_16;
    }

    if( pFilterStatus->ucStatus != pFilterStatus->ucLastStatus )
    {
        pFilterStatus->ucLastStatus = pFilterStatus->ucStatus;
        pFilterStatus->usFilterCount = (uint16)0u;
    }

    if( pFilterStatus->ucStatus != pFilterStatus->ucValidStatus )
    {
        if( pFilterStatus->usFilterCount < e_w_filterMaxCnt )
        {
            pFilterStatus->usFilterCount++;
        }
        else
        {
            pFilterStatus->ucValidStatus = pFilterStatus->ucStatus;
            e_u_reValue = TRUE;
        }
    }
    else
    {
    }

    return (e_u_reValue);
}

该函数的作用:当状态从一个状态切换到另一个状态时,稳定在多长时间不改变表示切换完成。

2.2

uint8 LIB_StatusFilterType2( LibFilterStruct *pFilterStatus, uint16 filterInMaxCnt ,uint16 filterOutMaxCnt)
{
    uint8  e_u_reValue = FALSE;
    uint16 e_w_filterInMaxCnt = (uint16)0u;
    uint16 e_w_filterOutMaxCnt = (uint16)0u;
    if(( filterInMaxCnt > (uint16)0u ) && ( filterInMaxCnt < ((uint16)0xFFFFu) ))
    {
    	e_w_filterInMaxCnt = filterInMaxCnt;
    }
    else
    {
    	e_w_filterInMaxCnt = ((uint16)0xFFFFu);
    }
    if(( filterOutMaxCnt > (uint16)0u ) && ( filterOutMaxCnt < ((uint16)0xFFFFu) ))
    {
    	e_w_filterOutMaxCnt = filterOutMaxCnt;
    }
    else
    {
    	e_w_filterOutMaxCnt = ((uint16)0xFFFFu);
    }

    if( pFilterStatus->ucStatus != pFilterStatus->ucLastStatus )
    {
        pFilterStatus->ucLastStatus = pFilterStatus->ucStatus;
        pFilterStatus->usFilterCount = (uint16)0u;
    }

    if( pFilterStatus->ucStatus != pFilterStatus->ucValidStatus )
    {
    	if(pFilterStatus->ucValidStatus == TRUE)
    	{
    	       if( pFilterStatus->usFilterCount < e_w_filterOutMaxCnt )
    	        {
    	            pFilterStatus->usFilterCount++;
    	        }
    	        else
    	        {
    	            pFilterStatus->ucValidStatus = pFilterStatus->ucStatus;
    	            e_u_reValue = TRUE;
    	        }
    	}
    	else if(pFilterStatus->ucValidStatus == FALSE)
    	{
        	if( pFilterStatus->usFilterCount < e_w_filterInMaxCnt )
            {
                pFilterStatus->usFilterCount++;
            }
            else
            {
                pFilterStatus->ucValidStatus = pFilterStatus->ucStatus;
                e_u_reValue = TRUE;
            }
    	}
    }
    else
    {
    }
    return (e_u_reValue);
}

该函数的作用:在固定时间,状态切换并且维持在稳定的时间。

三 缓存空间

typedef struct
{
	uint8  bIsValid;
	uint16 u16QueueLen;
	uint16 u16ItermSize;
	uint16 u1DdataLen;
	uint16  u16Data[CP_ADC_FIFO_ITERM_SIZE];
}fifo_t;
void fifo_init(fifo_t* pFifo, uint16 queueLength,uint16 itermSize)
{
	if((pFifo == NULL) || (queueLength == 0) || (itermSize == 0))
	{
	}
	else
	{
		pFifo->u16QueueLen = queueLength;
		pFifo->u16ItermSize = itermSize;
		for(uint16 i = 0; i < pFifo->u16QueueLen; i++)
		{
			pFifo->bIsValid = 0;
			pFifo->u1DdataLen = 0;
			for(uint16 j = 0; j < itermSize; j++)
			{
				pFifo[i].u16Data[j] = 0;
			}
		}
	}
}

uint8 fifo_get(fifo_t* pFifo,uint16* buf, uint16* len)
{
	uint8 ret = 0;
	if((pFifo == NULL) || (buf == NULL) || (len == NULL))
	{
		ret = 0;
	}
	else
	{
		for(uint16 i = 0; i < pFifo->u16QueueLen; i++)
		{
			if(pFifo[i].bIsValid == 1)
			{
				pFifo[i].bIsValid = 0;
				*len = pFifo[i].u1DdataLen;
				for(uint16 j = 0; j < pFifo[i].u1DdataLen; j++)
				{
					buf[j] = pFifo[i].u16Data[j];
				}
				ret = 1;
				break;
			}
		}
	}
	return ret;
}
uint8 fifo_set(fifo_t* pFifo,uint16* buf, uint16 len)
{
	uint8 ret = 0;
	if((len > CP_ADC_FIFO_ITERM_SIZE) || (pFifo == NULL) || (buf == NULL))
	{
		ret = 0;
	}
	else
	{
		for(uint16 i = 0; i < pFifo->u16QueueLen; i++)
		{
			if(pFifo[i].bIsValid == 0)
			{
				pFifo[i].bIsValid = 1;
				if(len > pFifo[i].u16ItermSize)
				{
					len = pFifo[i].u16ItermSize;
				}
				pFifo[i].u1DdataLen = len;
				for(uint16 j = 0; j < pFifo[i].u1DdataLen; j++)
				{
					pFifo[i].u16Data[j] = buf[j];
				}
				ret = 1;
				break;
			}
		}
	}
	return ret;
}

函数作用:适用于ADC采集数据等。

四 滤波算法

4.1 平均值滤波

static uint16 averageValue_Fillter(const uint16 *pData, uint16 len)
{
	uint16 min = 0, max = 0, verg = 0, invaild_count = 0,vaild_count = 0;
	uint32 sum = 0;
	uint16 tmp;
	if(pData == NULL || len == 0)
	{
		return 0;
	}
	else
	{
		min = pData[0];
		max = pData[0];
		for(uint16 i = 0; i < len; i++)
	    {
			tmp = pData[i];
	        if(pData[i] != 0)
	        {
	        	if(min == 0)
	        	{
	        		min = pData[i];
	        	}
	            if(min > pData[i])
	            {
	                min = pData[i];
	            }
	            if(max < pData[i])
	            {
	                max = pData[i];
	            }
	        }
			else
	        {
	            invaild_count++;
	        }
			sum += pData[i];
	    }
		vaild_count = len - invaild_count;
		if(vaild_count > 2)
		{
			sum -= min;
			sum -= max;
			verg = sum / (vaild_count - 2);
		}
		else if(vaild_count == 2)
		{
			verg = sum / 2;
		}
		else if((vaild_count = 0) || (vaild_count = 1))
		{
			verg = 0;
		}
		else{
			verg = 0;
		}
	}
	return verg;
}

五 环形队列

5.1

#define CYCBUF_DATACOPY_MODE_0   (0)
#define CYCBUF_DATACOPY_MODE_1   (1)
#define CYCBUF_DATACOPY_MODE (CYCBUF_DATACOPY_MODE_1)

static CycBufCtrlBlock_t CycBufCtrlBlock[CYCBUF_NUM_MAX];


void CycBuf_Init(void)
{
	for(uint32_t i = 0; i < CYCBUF_NUM_MAX; i++)
	{
		CycBufCtrlBlock[i].DataBuf 		= NULL;
		CycBufCtrlBlock[i].DataBufSize 	= 0;
		CycBufCtrlBlock[i].ReadCursor 	= 0;
		CycBufCtrlBlock[i].WriteCursor 	= 0;
		CycBufCtrlBlock[i].Status 		= CYCBUF_FREE;
	}
}


uint8_t CycBuf_Open(uint8_t* const ID_Buf, uint8_t* const DataBuf, const uint32_t DataBufSize)
{
	uint8_t Ret= CYCBUF_RET_SUCCESS;
	uint8_t i;
       
    if((0 == DataBufSize) || (NULL == DataBuf)) 
    {
		if(0 == DataBufSize)
		{
			Ret =CYCBUF_RET_OPEN_ABORT;
		}
		else 
		{
			Ret = CYCBUF_RET_ERR_PARAMETER;
		}
    }
    else 
    {
			
		for(i = 0; i < CYCBUF_NUM_MAX; i++)
		{
			if(CYCBUF_FREE == CycBufCtrlBlock[i].Status) 
			{
				break;
			}
			else 
			{
				;
			}
		}
		
		if(i >= CYCBUF_NUM_MAX)
		{
			Ret = CYCBUF_RET_BUF_OUT_OF_MAX;
		}
		else 
		{        
			CycBufCtrlBlock[i].DataBuf 		= DataBuf;
			CycBufCtrlBlock[i].DataBufSize 	= DataBufSize;
			CycBufCtrlBlock[i].ReadCursor 	= 0;
			CycBufCtrlBlock[i].WriteCursor 	= 0;
			CycBufCtrlBlock[i].Status 		= CYCBUF_INUSE;
			*ID_Buf = i;
			Ret = CYCBUF_RET_SUCCESS;
		}
    }

	return Ret;
}


uint8_t CycBuf_Close(const uint8_t ID)
{
	uint8_t Ret;
	if(ID < CYCBUF_NUM_MAX)	
	{
		CycBufCtrlBlock[ID].DataBuf 	= NULL;
		CycBufCtrlBlock[ID].DataBufSize = 0;
		CycBufCtrlBlock[ID].ReadCursor 	= 0;
		CycBufCtrlBlock[ID].WriteCursor = 0;
		CycBufCtrlBlock[ID].Status 		= CYCBUF_FREE;
		Ret = CYCBUF_RET_SUCCESS;
	}
	else 
	{
		Ret = CYCBUF_RET_ERR_PARAMETER;
	}
	return Ret;
}


uint8_t CycBuf_Write(const uint8_t ID, const uint8_t* const WriteBuf, const uint32_t WriteSize)
{
	uint8_t  Ret;
	uint8_t  Rollback;
	uint32_t i;
	uint32_t FreeBufSize;


	if((ID >= CYCBUF_NUM_MAX) || (NULL == WriteBuf)	|| ( 0 == WriteSize))
	 {
		Ret = CYCBUF_RET_ERR_PARAMETER;
	}
	else 
	{
	

		if(CYCBUF_FREE == CycBufCtrlBlock[ID].Status)
		{
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else 
		{
		if(((CycBufCtrlBlock[ID].WriteCursor + 1) % CycBufCtrlBlock[ID].DataBufSize) == CycBufCtrlBlock[ID].ReadCursor)
			 {
				Ret = CYCBUF_RET_BUF_FULL;
			}
			else
			{
				if(CycBufCtrlBlock[ID].WriteCursor >= CycBufCtrlBlock[ID].ReadCursor)
		
			    {
					FreeBufSize = CycBufCtrlBlock[ID].DataBufSize + CycBufCtrlBlock[ID].ReadCursor - CycBufCtrlBlock[ID].WriteCursor;
					Rollback = TRUE;
				}
				else 
				{
					FreeBufSize = CycBufCtrlBlock[ID].ReadCursor - CycBufCtrlBlock[ID].WriteCursor;
					Rollback = FALSE;
				}
				
				if(WriteSize >= FreeBufSize) 
				{
					Ret = CYCBUF_RET_BUF_NO_ENOUGH_BUF;
				}
				else
				{		
					/* ��ѭ�����渴������,      ���ַ����������ܲ��ԱȽ�                */
					#if(CYCBUF_DATACOPY_MODE == CYCBUF_DATACOPY_MODE_0)
					
					for(i = 0; i < WriteSize; i++)
					{
						CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].WriteCursor] = WriteBuf[i];
						CycBufCtrlBlock[ID].WriteCursor	= (CycBufCtrlBlock[ID].WriteCursor + 1) % CycBufCtrlBlock[ID].DataBufSize;
					}
					
					#else

					if(Rollback) {
						uint32_t FirstPartLen;
						uint32_t SecondPartLen;

						FirstPartLen = CycBufCtrlBlock[ID].DataBufSize - CycBufCtrlBlock[ID].WriteCursor;
						if(FirstPartLen >= WriteSize) {				
							for(i = 0; i < WriteSize; i++)
							{
								CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].WriteCursor + i] = WriteBuf[i];
							}
						}
						else {
							for(i = 0; i < FirstPartLen; i++)
							{
								CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].WriteCursor + i] = WriteBuf[i];
							}

							SecondPartLen = WriteSize - FirstPartLen;
							for(i = 0; i < SecondPartLen; i++)
							{
								CycBufCtrlBlock[ID].DataBuf[i] = WriteBuf[FirstPartLen + i];
							}
						}
					}
					else {
						for(i = 0; i < WriteSize; i++)
						{
							CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].WriteCursor + i] = WriteBuf[i];
						}	
					}

					CycBufCtrlBlock[ID].WriteCursor = (CycBufCtrlBlock[ID].WriteCursor + WriteSize) % CycBufCtrlBlock[ID].DataBufSize;
					
					#endif		
					
					Ret = CYCBUF_RET_SUCCESS;
				}
			}
		}
		
		CYCBUF_EXIT_CRITICAL_AREA();
	}
	return Ret;
}


uint8_t CycBuf_PreviewRead(const uint8_t ID, uint8_t* const ReadBuf, const uint32_t ReadSize)
{
	uint8_t  Ret;
	uint32_t i;
	uint8_t  Rollback;
	uint32_t UsedBufSize;
	uint32_t WriteCursorBuf;
	uint32_t ReadCursorBuf;

	if((ID >= CYCBUF_NUM_MAX) || (NULL == ReadBuf)	|| ( 0 == ReadSize)) {
		Ret = CYCBUF_RET_ERR_PARAMETER;
	}
	else
	{
		CYCBUF_ENTER_CRITICAL_AREA();

		WriteCursorBuf =  CycBufCtrlBlock[ID].WriteCursor;
		ReadCursorBuf =  CycBufCtrlBlock[ID].ReadCursor;

		if(CYCBUF_FREE == CycBufCtrlBlock[ID].Status)
		{
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			if(CycBufCtrlBlock[ID].WriteCursor == CycBufCtrlBlock[ID].ReadCursor) {
				Ret = CYCBUF_RET_BUF_EMPTY;
			}
			else  {
				/* ������Ч���ݸ��� */
				if(CycBufCtrlBlock[ID].WriteCursor >= CycBufCtrlBlock[ID].ReadCursor) {
					UsedBufSize = CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
					Rollback = FALSE;
				}
				else {
					UsedBufSize = CycBufCtrlBlock[ID].DataBufSize + CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
					Rollback = TRUE;
				}
				
				if(ReadSize > UsedBufSize) {
					Ret = CYCBUF_RET_BUF_NO_ENOUGH_DATA;
				}
				else {		
					/* ��ѭ�����渴������,      ���ַ����������ܲ��ԱȽ�                */
					#if(CYCBUF_DATACOPY_MODE == CYCBUF_DATACOPY_MODE_0)
					
					for(i = 0; i < ReadSize; i++)
					{
						ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor];
						CycBufCtrlBlock[ID].ReadCursor = (CycBufCtrlBlock[ID].ReadCursor + 1) % CycBufCtrlBlock[ID].DataBufSize;
					}
					
					#else
					
					if(Rollback) {
						uint32_t FirstPartLen;
						uint32_t SecondPartLen;

						FirstPartLen = CycBufCtrlBlock[ID].DataBufSize - CycBufCtrlBlock[ID].ReadCursor;
						if(FirstPartLen >= ReadSize) {				
							for(i = 0; i < ReadSize; i++)
							{
								ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
							}
						}
						else {
							for(i = 0; i < FirstPartLen; i++)
							{
								ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
							}

							SecondPartLen = ReadSize - FirstPartLen;
							for(i = 0; i < SecondPartLen; i++)
							{
								ReadBuf[FirstPartLen + i] = CycBufCtrlBlock[ID].DataBuf[i];
							}
						}
					}
					else {
						for(i = 0; i < ReadSize; i++)
						{
							ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
						}	
					}

					CycBufCtrlBlock[ID].ReadCursor = (CycBufCtrlBlock[ID].ReadCursor + ReadSize) % CycBufCtrlBlock[ID].DataBufSize;
					
					#endif

					Ret = CYCBUF_RET_SUCCESS;
				}
			}
		}

		CycBufCtrlBlock[ID].WriteCursor = WriteCursorBuf;
		CycBufCtrlBlock[ID].ReadCursor = ReadCursorBuf;
		
		CYCBUF_EXIT_CRITICAL_AREA();
	}
	
	return Ret;
}


uint8_t CycBuf_Read(const uint8_t ID, uint8_t* const ReadBuf, const uint32_t ReadSize)
{
	uint8_t  Ret;
	uint32_t i;
	uint8_t  Rollback;
	uint32_t UsedBufSize;

	if((ID >= CYCBUF_NUM_MAX) || (NULL == ReadBuf)	|| ( 0 == ReadSize)) {
		Ret = CYCBUF_RET_ERR_PARAMETER;
	}
	else
	{
		CYCBUF_ENTER_CRITICAL_AREA();
		
		if(CYCBUF_FREE == CycBufCtrlBlock[ID].Status)
		{
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			if(CycBufCtrlBlock[ID].WriteCursor == CycBufCtrlBlock[ID].ReadCursor) {
				Ret = CYCBUF_RET_BUF_EMPTY;
			}
			else  {
				/* ������Ч���ݸ��� */
				if(CycBufCtrlBlock[ID].WriteCursor >= CycBufCtrlBlock[ID].ReadCursor) {
					UsedBufSize = CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
					Rollback = FALSE;
				}
				else {
					UsedBufSize = CycBufCtrlBlock[ID].DataBufSize + CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
					Rollback = TRUE;
				}
				
				if(ReadSize > UsedBufSize) {
					Ret = CYCBUF_RET_BUF_NO_ENOUGH_DATA;
				}
				else {		
					/* ��ѭ�����渴������,      ���ַ����������ܲ��ԱȽ�                */
					#if(CYCBUF_DATACOPY_MODE == CYCBUF_DATACOPY_MODE_0)
					
					for(i = 0; i < ReadSize; i++)
					{
						ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor];
						CycBufCtrlBlock[ID].ReadCursor = (CycBufCtrlBlock[ID].ReadCursor + 1) % CycBufCtrlBlock[ID].DataBufSize;
					}
					
					#else
					
					if(Rollback) {
						uint32_t FirstPartLen;
						uint32_t SecondPartLen;

						FirstPartLen = CycBufCtrlBlock[ID].DataBufSize - CycBufCtrlBlock[ID].ReadCursor;
						if(FirstPartLen >= ReadSize) {				
							for(i = 0; i < ReadSize; i++)
							{
								ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
							}
						}
						else {
							for(i = 0; i < FirstPartLen; i++)
							{
								ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
							}

							SecondPartLen = ReadSize - FirstPartLen;
							for(i = 0; i < SecondPartLen; i++)
							{
								ReadBuf[FirstPartLen + i] = CycBufCtrlBlock[ID].DataBuf[i];
							}
						}
					}
					else {
						for(i = 0; i < ReadSize; i++)
						{
							ReadBuf[i] = CycBufCtrlBlock[ID].DataBuf[CycBufCtrlBlock[ID].ReadCursor + i];
						}	
					}

					CycBufCtrlBlock[ID].ReadCursor = (CycBufCtrlBlock[ID].ReadCursor + ReadSize) % CycBufCtrlBlock[ID].DataBufSize;
					
					#endif

					Ret = CYCBUF_RET_SUCCESS;
				}
			}
		}
		
		CYCBUF_EXIT_CRITICAL_AREA();
	}
	
	return Ret;
}


uint8_t CycBuf_Remove(const uint8_t ID, const uint32_t RemoveSize)
{
	uint8_t  Ret;
	uint32_t Len;

	if((ID >= CYCBUF_NUM_MAX) || ( 0 == RemoveSize)) {
		Ret = CYCBUF_RET_ERR_PARAMETER;
	}
	else
	{
		CYCBUF_ENTER_CRITICAL_AREA();
		
		if(CYCBUF_FREE == CycBufCtrlBlock[ID].Status)
		{
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			/* ����������� */
			if(CycBufCtrlBlock[ID].WriteCursor >= CycBufCtrlBlock[ID].ReadCursor) {
				Len = CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
			}
			else {
				Len = CycBufCtrlBlock[ID].DataBufSize + CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
			}

			/* �Ƴ�ָ���������� */
			if(Len >= RemoveSize) {
				CycBufCtrlBlock[ID].ReadCursor = (CycBufCtrlBlock[ID].ReadCursor + RemoveSize) % CycBufCtrlBlock[ID].DataBufSize;
				Ret = CYCBUF_RET_SUCCESS;		
			}
			else {
				Ret = CYCBUF_RET_BUF_NO_ENOUGH_DATA;
			}
		}
		
		CYCBUF_EXIT_CRITICAL_AREA();
	}
	
	return Ret;
}


uint8_t CycBuf_IsEmpty(const uint8_t ID)
{
	uint8_t Ret = CYCBUF_RET_SUCCESS;

	if(ID >= CYCBUF_NUM_MAX) {
		Ret =  CYCBUF_RET_ERR_PARAMETER;
	}
	else {
		CYCBUF_ENTER_CRITICAL_AREA();
			
		if(CYCBUF_INUSE != CycBufCtrlBlock[ID].Status) {
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			if(CycBufCtrlBlock[ID].WriteCursor == CycBufCtrlBlock[ID].ReadCursor) {
				Ret = CYCBUF_RET_BUF_EMPTY;
			}
			else {
				Ret = CYCBUF_RET_BUF_NOT_EMPTY;
			}
		}

		CYCBUF_EXIT_CRITICAL_AREA();
	}
	
	return Ret;
}


uint8_t CycBuf_IsFull(const uint8_t ID)
{
	uint8_t Ret = CYCBUF_RET_SUCCESS;

	if(ID >= CYCBUF_NUM_MAX) {
		Ret =  CYCBUF_RET_ERR_PARAMETER;
	}
	else {
		CYCBUF_ENTER_CRITICAL_AREA();
		
		if(CYCBUF_INUSE != CycBufCtrlBlock[ID].Status) {
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			if(CycBufCtrlBlock[ID].WriteCursor + 1 == CycBufCtrlBlock[ID].ReadCursor) {
				Ret = CYCBUF_RET_BUF_FULL;
			}
			else {
				Ret = CYCBUF_RET_BUF_NOT_FULL;
			}
		}

		CYCBUF_EXIT_CRITICAL_AREA();
	}
	return Ret;
}


uint8_t CycBuf_CheckData(const uint8_t ID, uint32_t* const len)
{
	uint8_t Ret = CYCBUF_RET_SUCCESS;

	if(ID >= CYCBUF_NUM_MAX) {
		Ret =  CYCBUF_RET_ERR_PARAMETER;
	}
	else {
		CYCBUF_ENTER_CRITICAL_AREA();
		
		if(CYCBUF_INUSE != CycBufCtrlBlock[ID].Status) {
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			if(CycBufCtrlBlock[ID].WriteCursor >= CycBufCtrlBlock[ID].ReadCursor) {
				*len = CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
			}
			else {
				*len = CycBufCtrlBlock[ID].DataBufSize + CycBufCtrlBlock[ID].WriteCursor - CycBufCtrlBlock[ID].ReadCursor;
			}

			Ret = CYCBUF_RET_SUCCESS;
		}

		CYCBUF_EXIT_CRITICAL_AREA();
	}
	
	return Ret;
}


uint8_t CycBuf_Reset(const uint8_t ID)
{
	uint8_t Ret = CYCBUF_RET_SUCCESS;

	if(ID >= CYCBUF_NUM_MAX) {
		Ret =  CYCBUF_RET_ERR_PARAMETER;
	}
	else {
		CYCBUF_ENTER_CRITICAL_AREA();
		
		if(CYCBUF_INUSE != CycBufCtrlBlock[ID].Status) {
			Ret = CYCBUF_RET_NOT_OPEN;
		}
		else {
			CycBufCtrlBlock[ID].ReadCursor = 0;
			CycBufCtrlBlock[ID].WriteCursor = 0;
		}
		
		CYCBUF_EXIT_CRITICAL_AREA();
	}
	return Ret;
}
typedef enum {
	CYCBUF_CH_0 = 0,    /* +1, USART2 ���Դ��ڷ���ѭ������ */
	CYCBUF_CH_1, 		/* +1, USART2 ���Դ��ڽ���ѭ������ */
	CYCBUF_CH_2,		/* +1, PWR���COM��ͨ��ģ�鷢������֡���� */
	CYCBUF_CH_3,
	CYCBUF_CH_4,
	CYCBUF_CH_5,
	CYCBUF_CH_6,
	CYCBUF_CH_7,
	CYCBUF_NUM_MAX
}CycBuf_Channel_t;

#define CYCBUF_NUM_MAX 10

#define CYCBUF_ENTER_CRITICAL_AREA()  	MCAL_MCUCORE_ENTER_CRITICAL_AREA()
#define CYCBUF_EXIT_CRITICAL_AREA()  	MCAL_MCUCORE_EXIT_CRITICAL_AREA()

typedef enum {
	CYCBUF_FREE = 0,
	CYCBUF_INUSE,
	CYCBUF_BUSY,
	CYCBUF_ABANDON
}CycBuf_Status_t;
	

typedef enum {
	CYCBUF_RET_SUCCESS = 0,
	CYCBUF_RET_NOT_OPEN,
	CYCBUF_RET_OPEN_ABORT,
	CYCBUF_RET_BUF_OUT_OF_MAX,
	CYCBUF_RET_ERR_PARAMETER,
	CYCBUF_RET_BUF_FULL,
	CYCBUF_RET_BUF_EMPTY,
	CYCBUF_RET_BUF_NOT_FULL,
	CYCBUF_RET_BUF_NOT_EMPTY,
	CYCBUF_RET_BUF_NO_ENOUGH_BUF,
	CYCBUF_RET_BUF_NO_ENOUGH_DATA,
	CYCBUF_RET_ERR_UNEXPECTED
}CycBuf_Ret_Value_t;



typedef struct {
    uint8_t* DataBuf;
    uint8_t  Status;
    uint32_t DataBufSize;
    uint32_t ReadCursor;
    uint32_t WriteCursor;
}CycBufCtrlBlock_t;


void CycBuf_Init(void);

extern uint8_t CycBuf_Open(uint8_t* const ID_Buf, uint8_t* const DataBuf, const uint32_t DataBufSize);
extern uint8_t CycBuf_Close(const uint8_t ID);

extern uint8_t CycBuf_Write(const uint8_t ID, const uint8_t* const WriteBuf, const uint32_t DataSize);
extern uint8_t CycBuf_Read(const uint8_t ID, uint8_t* const ReadBuf, const uint32_t ReadSize);
extern uint8_t CycBuf_Remove(const uint8_t ID, const uint32_t RemoveSize);
extern uint8_t CycBuf_PreviewRead(const uint8_t ID, uint8_t* const ReadBuf, const uint32_t ReadSize);

extern uint8_t CycBuf_IsEmpty(const uint8_t ID);
extern uint8_t CycBuf_IsFull(const uint8_t ID);
extern uint8_t CycBuf_CheckData(const uint8_t ID, uint32_t* const len);
extern uint8_t CycBuf_Reset(const uint8_t ID);

5.2

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _FIFO_H_
#define _FIFO_H_
/* Includes ------------------------------------------------------------------*/

//#include "ac78xx.h"
#include 

typedef struct
{
    uint32_t head;  /* output conut */
    uint32_t tail;     /*  input count   */
    uint32_t size;   /*  total size  */
    uint8_t * baseAddr;
}fifo_TypeDef;




uint8_t fifo_Init(fifo_TypeDef * _fifo, uint8_t* data, uint32_t size);
uint8_t fifo_DeInit(fifo_TypeDef * _fifo);
uint8_t fifo_Reset(fifo_TypeDef * _fifo);


uint32_t fifo_insert(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len);
uint32_t fifo_retrieve(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len);

uint32_t fifo_GetLen(fifo_TypeDef * _fifo);
uint8_t fifo_NotFull(fifo_TypeDef * _fifo);
uint32_t fifo_GetFreeSpace(fifo_TypeDef * _fifo);
uint32_t  Fifo_strchr(fifo_TypeDef * _fifo, uint8_t data);

#endif

/* Includes ------------------------------------------------------------------*/
#include  
#include "fifo.h"
#include 



#define minimum(x, y)  (((x) < (y))? (x) : (y))


/************************************************************************
    Function : 
    Description : Init the fifo structure.
            _fifo : reference to _fifo struct.
            size : size of the fifo.
            retval 1 if memory allocation fails or 0.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint8_t fifo_Init(fifo_TypeDef * _fifo, uint8_t* data, uint32_t size)
{
    /* check for a valid pointer */
    if (_fifo == NULL)
    {
        return 1;
    }
    
    /* if fifo size is null nothing to do */
    if ( size == 0)
    {
        memset((uint8_t *)_fifo, 0x00, sizeof(fifo_TypeDef));
        return 1;
    }
    else
    {
        /* allocate fifo space. */
        _fifo->baseAddr = data;
        if (_fifo->baseAddr == NULL)
        {
            /* memory allocation failure. */
            #ifdef SZ_LOG
            putLine();
            putString("----> Malloc Fail!");
            #endif
            
            return 1;
        }
        else
        {
            memset((uint8_t *)_fifo->baseAddr, 0x00, sizeof(uint8_t) * size);
            /* tail = head --> empty fifo */
            _fifo->head = 0;
            _fifo->tail = 0;
            _fifo->size = size;
            return 0;
        }
    }
}


/************************************************************************
    Function : 
    Description : DeInit the fifo structure.
            _fifo : reference to _fifo struct.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint8_t fifo_DeInit(fifo_TypeDef * _fifo)
{
    uint8_t status = 1;
    
    if (_fifo == NULL)
    {
        status = 1;
    }
    else
    {
        if (_fifo->baseAddr != NULL)
        {
            /* optional (clear memory region) */
            memset((uint8_t *)_fifo->baseAddr, 0x00, _fifo->size);
            memset((uint8_t *)_fifo, 0x00, sizeof(fifo_TypeDef));
            status = 0;
        }
        else
        {
            /* FiFo invalid base address. */
            status = 1;
        }
    }
    return status;
}


/************************************************************************
    Function : 
    Description : Reset the fifo structure.
            _fifo : reference to _fifo struct.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint8_t fifo_Reset(fifo_TypeDef * _fifo)
{
    if (_fifo == NULL)
    {
        return 1;
    }
    else
    {
        if (_fifo->baseAddr != NULL)
        {
            /* optional (clear memory region) */
            memset((uint8_t *)_fifo->baseAddr, 0x00, _fifo->size);
            
            _fifo->head = 0;
            _fifo->tail = 0;
            return 0;
        }
        else
        {
            /* FiFo invalid base address. */
            return 1;
        }
    }
}



/************************************************************************
    Function : 
    Description : returns how much data is stored in the fifo.
            _fifo : reference to _fifo struct.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint32_t fifo_GetLen(fifo_TypeDef * _fifo)
{
    if (_fifo == NULL)
    {
        return 0;
    }
    else
    {
        return (_fifo->tail - _fifo->head);
    }
}


/************************************************************************
    Function : 
    Description : returns how much free sapce in the fifo.
            _fifo : reference to _fifo struct.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint32_t fifo_GetFreeSpace(fifo_TypeDef * _fifo)
{
    if (_fifo == NULL)
    {
        return 0;
    }
    else
    {
        return (_fifo->size - (_fifo->tail - _fifo->head));
    }
}



/************************************************************************
    Function : 
    Description : returns SET if the FIFO is full.
            _fifo : reference to _fifo struct.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint8_t fifo_NotFull(fifo_TypeDef * _fifo)
{
    if (_fifo == NULL)
    {
        return 0;
    }
    else
    {
        return ((_fifo->tail - _fifo->head) != _fifo->size) ? 1 : 0;
    }
}


/************************************************************************
    Function : 
    Description : Insert data to the fifo.
            _fifo : reference to _fifo struct.
            data : reference to data buffer.
            len : data buffer length.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint32_t fifo_insert(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len)
{
	uint32_t real_len;
	uint32_t offset;
	uint32_t end;


	offset   = _fifo->size - (_fifo->tail - _fifo->head);
    /*Actual size of data we can write*/
    real_len = minimum(len, offset);
    /*Offset of write pointer*/
    offset   = _fifo->tail % _fifo->size;
    /*End position before buffer being warpped*/
    end      = minimum(real_len,  _fifo->size - offset);
    
	/*Copy data to buffer before warp*/
	memcpy(_fifo->baseAddr + offset, data, end);
	
	/*Copy data to buffer after warp*/
	memcpy(_fifo->baseAddr, data + end, real_len - end);
	
	_fifo->tail += real_len;
	
	return real_len;
}


/************************************************************************
    Function : 
    Description : Retrieve data from the fifo.
            _fifo : reference to _fifo struct.
            data : reference to data buffer.
            len : data buffer length.
    Change history:
    Note:
    Author:     
    Date:     Jan-10-2013
************************************************************************/
uint32_t fifo_retrieve(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len)
{
	uint32_t real_len;
	uint32_t offset;
	uint32_t end;
  
	
    offset   = _fifo->tail- _fifo->head;
	real_len = minimum(len, offset);
	
    //得到偏移量
	offset = _fifo->head % _fifo->size;
    
	end = minimum(real_len, _fifo->size - offset);
	
	memcpy(data, _fifo->baseAddr + offset, end);
	
	memcpy(data + end, _fifo->baseAddr, real_len - end);
	
	_fifo->head += real_len;
	
	return real_len;
}

/*****************************************************************************
* 函数名:  串口通道帧尾获取函数
* 函数功能: 获取当前帧帧尾所在地址
* 输入参数: _fifo - fifo结构体
* 输入参数: data-帧尾结束符
* 返回数据: fifo中接收到的数据到字节data第一次出现的长度
*****************************************************************************/ 
uint32_t  Fifo_strchr(fifo_TypeDef * _fifo, uint8_t data)
{
    uint32_t remaining = 0;
    uint32_t len       = 0;
    uint32_t head;
    

    head      = _fifo->head;
    remaining = _fifo->tail- head;
    head      = head % _fifo->size;
	
	
	while(remaining)
	{   
        len++;
        if(data == *((_fifo->baseAddr + head)))
        {
            return len;
        }
        head++;
        remaining--;
		head %= _fifo->size;
	}
	return 0;
}

5.3

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

你可能感兴趣的:(单片机,c语言,嵌入式硬件)