WCH沁恒单片机
直播中

吴湛

10年用户 1016经验值
擅长:可编程逻辑
私信 关注
[问答]

CH579把串口改成中断方式接收,串口接收有时会出错如何解决?

用原厂的例程 UART1,把串口改成中断方式接收,并且串口1改成串口3(串口1用作日志打印),发现串口3在中断时若调用printf打印log,则串口3中断接收的数据会出错,没有调用printf的话是没有问题的

int main()
{
    UINT8 len;
   
/* 配置串口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();
   
#if 1       // 测试串口发送字符串
    UART1_SendString( TxBuff, sizeof(TxBuff) );


#endif   


#if 0       // 查询方式:接收数据后发送出去
    while(1)
    {
        len = UART1_RecvString(RxBuff);
        if( len )
        {
            UART1_SendString( RxBuff, len );            
        }
    }
   
#endif   


#if 1      // 中断方式:接收数据后发送出去
//    UART1_ByteTrigCfg( UART_7BYTE_TRIG );
//    trigB = 7;
//    UART1_INTCfg( ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT );
//    NVIC_EnableIRQ( UART1_IRQn );
//uart tx io
    GPIOA_SetBits(bTXD3);
    GPIOA_ModeCfg(bTXD3, GPIO_ModeOut_PP_5mA);


    //uart rx io
    GPIOA_SetBits(bRXD3);
    GPIOA_ModeCfg(bRXD3, GPIO_ModeIN_PU);
   
    //uart3 init
    UART3_DefInit( );
   
    //enable interupt
//trigB = 7;
//UART3_INTCfg( ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT );
//NVIC_SetPriority(UART3_IRQn, 5);
//NVIC_EnableIRQ( UART3_IRQn );
UART3_ByteTrigCfg( UART_7BYTE_TRIG );
trigB = 7;
UART3_INTCfg( ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT );
NVIC_EnableIRQ( UART3_IRQn );


#endif   


    while(1);   
}




void UART3_IRQHandler(void)
{
    UINT8 i;
    switch( UART3_GetiTFlag() )
    {
        case UART_II_LINE_STAT:        // 线路状态错误
            UART3_GetLinSTA();
            break;
        
        case UART_II_RECV_RDY:          // 数据达到设置触发点
//PRINT("0 R8_UART3_RFC : %d
", R8_UART3_RFC);
for(i = 0; i != trigB; i++) {
RxBuff = UART3_RecvByte();
UART3_SendByte(RxBuff);
}
//PRINT("0 RDY -- i : %d
", i);
break;
        
        case UART_II_RECV_TOUT:         // 接收超时,暂时一帧数据接收完成
//PRINT("1 R8_UART3_RFC : %d
", R8_UART3_RFC);
i = UART3_RecvString(RxBuff);
UART3_SendString( RxBuff, i );
//PRINT("1 TOUT -- i : %d
", i);
            break;
        
        case UART_II_THR_EMPTY:         // 发送缓存区空,可继续发送
            break;
        
        case UART_II_MODEM_CHG:         // 只支持串口0
            break;
        
        default:
            break;
    }
}




测试发现 只要在 UART_II_RECV_RDY 里调用PRINT("0 RDY -- i : %d
", i); 数据就会出错




  


回帖(1)

周奕

2022-9-1 09:33:04
官网的例程中,PRINT的实现是 阻塞的,而不是异步的.
这意味着,打印是很耗时的,基本上取决于串口的速率.


建议:
1,打印的数据尽量的少


2,适当的提高打印的速率(初始化UART1时候,再执行一次设置速率为更块的函数,比如用500K:     UART1_BaudRateCfg( 5E5); )


3,降低uart3 的速率,给打印留时间
举报

更多回帖

发帖
×
20
完善资料,
赚取积分