nrf52832 Uart 调试

概述:

UARTE 是带有 EasyDMA 的通用异步接收器/发送器 UART。提供快速、全双工、异步的串口通信,内置流量控制(CTS,RTS)支持硬件,速率高达 1 Mbps。

官方Demo使用

SDK版本: nRF5_SDK17

example: nRF5_SDK_17.0.2_d674dde\examples\peripheral\uart

运行Demo 是很OK的

 uint32_t err_code;

    bsp_board_init(BSP_INIT_LEDS);

    const app_uart_comm_params_t comm_params =
      {
          RX_PIN_NUMBER,
          TX_PIN_NUMBER,
          RTS_PIN_NUMBER,
          CTS_PIN_NUMBER,
          UART_HWFC,
          false,
#if defined (UART_PRESENT)
          NRF_UART_BAUDRATE_115200
#else
          NRF_UARTE_BAUDRATE_115200
#endif
      };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);

#ifndef ENABLE_LOOPBACK_TEST
    printf("\r\nUART example started.\r\n");

 

但是如果,要多打印一些东西了,发现只能打印前面一部分数据;,比如这样的:

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

注: Board_UARTPutSTR是基于app_uart_put实现的,如下:

void Board_UARTPutSTR(char *str)
{
	int      len = 0; 
	int      i = 0;
	len = strlen(str);
	while(i<len)
	{
		app_uart_put(str[i++]);
	}
}

为什么只能打印前面一个部分呢?

因为FIFO, Noric的Uart的lib 帮我们实现了fifo,待发送数据是先存放在fifo中,然后进行发送。

由于CPU存放的速度远远大于Uart Tx速度,所以,会很容易造成FIFO溢出,所以后面的数据被覆盖,出现乱码;

查看app_uart_put的源码,很容易理解

uint32_t app_uart_put(uint8_t byte)
{
    uint32_t err_code;
    err_code = app_fifo_put(&m_tx_fifo, byte);             //先将数据存放到fifo中
    if (err_code == NRF_SUCCESS)
    {
        // The new byte has been added to FIFO. It will be picked up from there
        // (in 'uart_event_handler') when all preceding bytes are transmitted.
        // But if UART is not transmitting anything at the moment, we must start
        // a new transmission here.
        if (!nrf_drv_uart_tx_in_progress(&app_uart_inst))         //如果tx 空闲,启动发送 
        {
            // This operation should be almost always successful, since we've
            // just added a byte to FIFO, but if some bigger delay occurred
            // (some heavy interrupt handler routine has been executed) since
            // that time, FIFO might be empty already.
            if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
            {
                err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
            }
        }

           //else 如果tx 工作中,不用管,uart lib会一直将tx fifo中的数据发送,直到为空;
    }
    return err_code;
}

fifo 引入本意是减少tx 外设占用过长时间,提供CPU效率;

有的时候,需要输出大量数据,比如,使用串口进行交互,比较容易造成溢出;解决方法,同步一下uart 的发送和fifo 的写入问题,解决方法继续往下看。。。

 

同步方法:

方法一:

          增加UART_TX_BUF_SIZE  大小,即增加TX FIFO大小,就没有那么容易溢出了;不过缺点很明显,消耗更多ram资源,依旧存在溢出风险

方法二:

         在需要连续打印的地方增加延时,比如:

 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
delay(5);
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
delay(5);
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
delay(5);
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");
 Board_UARTPutSTR("-------------------------------start-------------------------------------\n");

确定同样十分明显

方法三:

 在发送string之前,先检查tx FIFO是否为空,等空闲之后,在发送string,改造如下:

1 在app_uart_fifo.c 增加一个函数获取fifo 的tx是否空闲,如下

bool get_app_uart_tx_in_progress()
{
    return nrf_drv_uart_tx_in_progress(&app_uart_inst) ;
}

2 将Board_UARTPutSTR 改造如下:

/* Outputs a string on the debug UART */
void Board_UARTPutSTR(char *str)
{
    int      len = 0; 
    int      i = 0;
    
    len = strlen(str);
    
    while( get_app_uart_tx_in_progress());          //增加uart tx fifo 是否空闲判断

#if defined(DEBUG_UART)
    while(i<len)
    {
        app_uart_put(str[i++]);
    }
#endif
}

 

综上:

 方法3 比较好的解决了,UART FIFO 溢出问题

 

 

 

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值