/**************************************************************
* 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信号的控制,敬请期待!
