【DigiKey&NXP】NXP FRDM-K32L3A6开发板-FreeRTOS系统篇(四)

/**************************************************************
* FunctionName   : UART_ChkSum()
* Description    : 校验和[MsgTyte+MsgLen+MsgDat]
* EntryParameter : None
* ReturnValue    : None
***************************************************************/
u8 UART_ChkSum(u16 cmd, u8 *pDat, u16 len)
{
    u8 tmpSum = 0;
    tmpSum ^= MTH_WRD_HGH(cmd);
    tmpSum ^= MTH_WRD_LOW(cmd);
    tmpSum ^= MTH_WRD_HGH(len);
    tmpSum ^= MTH_WRD_LOW(len);
    for (u16 i=0; i<len; i++)
    {
        tmpSum ^= pDat[i];
    }
    return tmpSum;
}

/*************************************************************
* FunctionName   : UART_Escape()
* Description    : 转义
* EntryParameter : pOut - 转义后的数据; pIn - 需转义的数据; len - 数据长度
* ReturnValue    : 数据长度
***************************************************************/
u16 UART_Escape(u8 *pOut, u8 *pIn, u16 len)
{
u16 tmpLen = 0;

    for (u16 i=0; i<len; i++)
    {
        if ((i == 0) || (i == len-1))
        {
            pOut[tmpLen++] = pIn[i];
        }
        else
        {
            // 把帧头和帧尾之间出现的小于0x10的与0x10异或,并在前面加上0x02
            if (pIn[i] < 0x10)
            {
                pOut[tmpLen++] = 0x02;				          // 加上0x02
                pOut[tmpLen++] = pIn[i] ^ 0x10;               // 与0x10异或
            }
            else
            {
                pOut[tmpLen++] = pIn[i];
            }
        }
    }
    return tmpLen;
}

void SendDataQueue(void)
{
    u16 len = UART_Rcv.WCnt;
    u8 *pDat = UART_Rcv.Buf;
   
    BaseType_t taskToWake = pdFALSE;

    xQueueSendFromISR(UARTProQueHandle, pDat, &taskToWake);    // 中断中发送
}

/******************串口接收中断服务函数********************/
void BOARD_CONN_UART_IRQ_HANDLER(void)
{
	uint8_t ucTemp = UART_FRM_END;
    portBASE_TYPE taskToWake = pdFALSE;
    /*串口接收到数据*/
	if ((kLPUART_RxDataRegFullFlag | kLPUART_RxOverrunFlag) & LPUART_GetStatusFlags(BOARD_CONN_UART))
  {
      /*读取数据*/
	  ucTemp = BOARD_CONN_UART->DATA;

	  if(UART_FRM_SRT == ucTemp)
			 UART_Rcv.WCnt = 0;
	 
	  UART_Rcv.Buf[UART_Rcv.WCnt++] = ucTemp;
	 
	  if(UART_FRM_END == ucTemp)
			 SendDataQueue();
  }
}

/**************************************
* FunctionName   : UART_SendPack()
* Description    : 发送数据包[0x01+cmd+len+ChkSum+Dat+0x03]
* EntryParameter : None
* ReturnValue    : None
**************************************/
void UART_SendPack(u8 *pMsg)          // pMsg = cmd + len + dat
{
    u16 cmd, len = 0;
    u8 tmpCnt = 0;
    u8 tmpBuf[UART_BUF_SIZE] = {0};
    u8 tmpDat[UART_BUF_SIZE] = {0};
    
    cmd = MTH_ARR_WRD(&pMsg[0]);
    if(NULL != cmd)
    {
        len = MTH_ARR_WRD(&pMsg[2]);
        
        tmpBuf[tmpCnt++] = UART_FRM_SRT;                                            
        tmpBuf[tmpCnt++] = MTH_WRD_HGH(cmd);                                        
        tmpBuf[tmpCnt++] = MTH_WRD_LOW(cmd);
        tmpBuf[tmpCnt++] = MTH_WRD_HGH(len);                                        
        tmpBuf[tmpCnt++] = MTH_WRD_LOW(len);  
        tmpBuf[tmpCnt++] = UART_ChkSum(cmd, &pMsg[4], len);                       
        
        for (u16 i=0; i<len; i++)
        {
            tmpBuf[tmpCnt++] = pMsg[i+4];
        }
        
        tmpBuf[tmpCnt++] = UART_FRM_END;                                            
        tmpCnt = UART_Escape(tmpDat, tmpBuf, tmpCnt); 
        xSemaphoreTake(Uart_xMutex, portMAX_DELAY);																	
		LPUART_WriteBlocking(BOARD_CONN_UART, tmpDat, tmpCnt);											
        xSemaphoreGive(Uart_xMutex);
    }

编译完成后,直接下载到开发板中

五、打印输出

串口0输出信息如下图所示,三个线程按照任务的优先级不断打印输出log,后续还需完善串口1的接收及命令解析接口,实现对PWM信号的控制,敬请期待!