PC机每隔100ms给协调器发送28字节的数据,协调器接收后,回显。
过一段时间后,会提示:HAL_UART_RX_FULL,而且发送的数据也不是完整的28个字节。
Alvin Chen:
当缓冲区数据长度大于等于HAL_UART_DMA_FULL 时, 触发HAL_UART_RX_FULL事件
你的数据是否及时读出以及及时释放。
你把你uart 贴下
user4711142:
回复 Alvin Chen:
我用的是中断方式:
/********************************************
* @brief自定义的串口初始化函数
* @para
********************************************/
void MyApp_UartInit(void)
{halUARTCfg_t uartConfig;uartConfig.configured= TRUE;// 2×30 don't care – see uart driver.uartConfig.baudRate= MY_APP_BAUD;uartConfig.flowControl= FALSE;uartConfig.flowControlThreshold = MY_APP_THRESH; // 2×30 don't care – see uart driver.uartConfig.rx.maxBufSize= MY_APP_RX_SZ;// 2×30 don't care – see uart driver.uartConfig.tx.maxBufSize= MY_APP_TX_SZ;// 2×30 don't care – see uart driver.uartConfig.idleTimeout= MY_APP_IDLE;// 2×30 don't care – see uart driver.uartConfig.intEnable= TRUE;// 2×30 don't care – see uart driver.uartConfig.callBackFunc= rxCB;//串口接收到数据时的处理HalUARTOpen (0, &uartConfig);
}
/********************************************************************
* @brief串口处理函数,将接收到的数据发送出去
* @parauint8 port :串口号 0 、1
* @parauint8 event:事件
*********************************************************************/
#define UART_DATA_MAX 28//最大32个字节的数据
static uint8 MyApp_AFTxBuf[UART_DATA_MAX+5]={0};//缓存从串口中接收到的数据,+5:帧头4个字节,帧尾1个字节
void rxCB( uint8 port, uint8 event )
{static uint8 temp = 0; if((event & (HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT))&&(!MyApp_Tx_Len)){ //打印事件temp = (event&0x0F)+'B';HalUARTWrite(0,&temp,1);//清空MyApp_AFTxBuf数组。osal_memset(MyApp_AFTxBuf,0,UART_DATA_MAX+5);MyApp_AFSendUartData();//将数据读取并将标志位置位}
}
/*************************************************
*
*************************************************/
void MyApp_AFSendUartData(void)
{
#ifdef MYAPP_LOOPBACK_TEST//还回测试,测试串口功能
#elseif(!MyApp_Tx_Len){MyApp_Tx_Len=HalUARTRead(HAL_UART_PORT_0,MyApp_AFTxBuf+5,UART_DATA_MAX);MyApp_Tx_Len_Buf = MyApp_Tx_Len;//缓存osal_memcpy(Myapp_Uart_RBuf,MyApp_AFTxBuf,MyApp_Tx_Len_Buf+5);}
#endif
}//在事件处理函数中,每隔99ms,轮询MyApp_Tx_Len_Buf 是否非零,如果是,则AF发送
uint16 MyApp_ProcessEvent( uint8 task_id, uint16 events )
{
……if(events & MYAPP_UART_DTU_EVT){MyApp_UartDtu_Pro();osal_start_timerEx(MyApp_TaskID,MYAPP_UART_DTU_EVT,99); //每隔90ms,检测一次是否有数据需要透传。return (events ^ MYAPP_UART_DTU_EVT);}
……
}
MyApp_UartDtu_Pro()//这个函数有点乱,没贴代码
{
判断MyApp_Tx_Len_Buf 是否非零,如果是,则进行处理;
处理完成后,MyApp_Tx_Len_Buf = 0;MyApp_Tx_Len= 0;
}
user4711142:
回复 user4711142:
数据怎么及时读出,及时释放?是要在底层更改还是应用层更改?
Alvin Chen:
回复 user4711142:
给你个建议应该是个原因:
你把你RXcall的处理修正一下:
不要在callback去处理数据,仅去HalUARTRead,数据在其他地方处理,这样应该会有所改善。
user4711142:
回复 Alvin Chen:
1、我只在callback中读取数据;
2、定义用户事件处理函数,每隔100ms检测是否有数据,如果有在进行处理
这样可以么?
Alvin Chen:
回复 user4711142:
建议你直接在你的callback 里面read 到然后启动一个events去处理。
你现在只在你的callback ,然后做一个events去 回write试试。
user4711142:
回复 Alvin Chen:
void rxCB( uint8 port, uint8 event )
{uint8 *MyApp_AFTxBuf;
if((event & (HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT))&&(!MyApp_Tx_Len)){ if(!(MyApp_AFTxBuf=osal_mem_alloc(UART_DATA_MAX))) //申请一段内存,如果申请不成功,则直接返回。{HalUARTWrite(0,"Return\r\n",8);return ;}MyApp_Tx_Len=HalUARTRead(HAL_UART_PORT_0,MyApp_AFTxBuf,UART_DATA_MAX); //读取数据osal_memcpy(&Myapp_Uart_RBuf[5],MyApp_AFTxBuf,MyApp_Tx_Len_Buf);//数据缓冲osal_mem_free(MyApp_AFTxBuf);//释放申请的内存//数据处理事件osal_set_event(MyApp_TaskID,MYAPP_UART_DTU_EVT);}
}请问这样可以么?是否还需要继续精简??
user4711142:
回复 user4711142:
测试了一下,还是不行,还是有产生rxbuf满事件HAL_UART_DMA_FULL
user4711142:
回复 Alvin Chen:
void rxCB( uint8 port, uint8 event )
{static uint8 len = 0;if((event & (HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT))&&(!MyApp_Tx_Len)){ Evt_temp = event;//保存事件MyApp_Tx_Len=HalUARTRead(HAL_UART_PORT_0,MyApp_AFTxBuf,UART_DATA_MAX); //读取数据MyApp_Tx_Len_Buf = MyApp_Tx_Len;//数据缓冲osal_set_event(MyApp_TaskID,MYAPP_UART_DTU_EVT);//数据处理事件}
}这样还是会有接收缓冲区满的事件HAL_UART_DMA_FULL ,该怎么办呀
Alvin Chen:
回复 user4711142:
你好,我自己写了一个测试正常如下:
void AF_Uart_config(void) {halUARTCfg_t uartConfig;uartConfig.configured = TRUE;uartConfig.baudRate = HAL_UART_BR_9600;uartConfig.flowControl = FALSE;uartConfig.flowControlThreshold = 32;uartConfig.rx.maxBufSize = 64;uartConfig.tx.maxBufSize = 64;uartConfig.idleTimeout = 6;uartConfig.intEnable = TRUE;uartConfig.callBackFunc = AF_Uart_Callback;HalUARTOpen (HAL_UART_PORT_0, &uartConfig);} void AF_Uart_Callback( uint8 port, uint8 event ) {uint16 data_len;uint8 *uart_data;if(event & (HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT)){data_len=Hal_UART_RxBufLen(HAL_UART_PORT_0);uart_data=osal_mem_alloc(data_len);if ( uart_data != NULL ){HalUARTRead(HAL_UART_PORT_0,uart_data,data_len);HalUARTWrite(HAL_UART_PORT_0,uart_data,data_len);data_len=0;}osal_mem_free( uart_data );}}