【BLE 5.3无线MCU CH582】4、串口不定长数据接收
[复制链接]
系列文章:
【BLE 5.3无线MCU CH582】1、初识CH582开发板(开箱)
【BLE 5.3无线MCU CH582】2、MounRiver IDE初体验
【BLE 5.3无线MCU CH582】3、非阻塞方式点灯
1、硬件连接
本文使用串口1,对应的引脚为PA8和PA9。
2、实现思路
利用串口接收相邻两个字符的时间来判断一串数据是否接收完成,如果超过设定的时间,还没有接收到下一个字符,则认为一串数据接收完成。
如果使用115200波特率,数据长度为8bit,停止位为1bit,那么接收一个字节大约需要,(1/115200)*9=0.78ms。
那么就可以利用,接收完一个字符后,如果0.78ms之内没有下一个数据,那么就可以认为一串数据接收完成,考虑到单片机接收数据保存,这里设定超时时间为5ms。
3、核心代码
主要是利用串口接收中断和应用层超时。
#define UART_MAX_LEN 200
struct
{
UINT8 Timeout;
UINT8 RecvBuff[UART_MAX_LEN];
UINT8 RecvLen;
} SerialStr;
void SerialInit(void)
{
/* 配置串口1:先配置IO口模式,再配置串口 */
GPIOA_SetBits( GPIO_Pin_9 );
GPIOA_ModeCfg( GPIO_Pin_8, GPIO_ModeIN_PU ); // RXD-配置上拉输入
GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA ); // TXD-配置推挽输出,注意先让IO口输出高电平
UART1_DefInit();
UART1_ByteTrigCfg( UART_1BYTE_TRIG );
UART1_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT );
PFIC_EnableIRQ( UART1_IRQn );
}
void SerialRecvTimeout(void)
{
if(SerialStr.Timeout>0)
{
SerialStr.Timeout--;
}
}
void SerialRecv(UINT8 data)
{
SerialStr.Timeout=5;
if(SerialStr.RecvLen<UART_MAX_LEN)
{
SerialStr.RecvBuff[SerialStr.RecvLen++]=data;
}
}
void SerialSend(uint8_t *data,uint8_t len)
{
UART1_SendString( data, len ); /* 串口多字节发送 */
}
void SerialPro(void)
{
if(!SerialStr.Timeout&&SerialStr.RecvLen)
{
SerialSend("Recv:",sizeof("Recv:")-1);
SerialSend(SerialStr.RecvBuff,SerialStr.RecvLen);
SerialStr.RecvLen=0;
}
}
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler( void )
{
UINT8 ch;
switch ( UART1_GetITFlag() )
{
case UART_II_LINE_STAT : // 线路状态错误
{
UART1_GetLinSTA();
break;
}
case UART_II_RECV_RDY : // 数据达到设置触发点
{
ch=UART1_RecvByte();
SerialRecv(ch);
break;
}
case UART_II_RECV_TOUT : // 接收超时,暂时一帧数据接收完成
break;
case UART_II_THR_EMPTY : // 发送缓存区空,可继续发送
break;
case UART_II_MODEM_CHG : // 只支持串口0
break;
default :
break;
}
}
4、现象
|