我是靠谱客的博主 完美星月,最近开发中收集的这篇文章主要介绍nrf52832 Uart 调试概述:同步方法:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

概述:

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

官方Demo使用

SDK版本: nRF5_SDK17

example: nRF5_SDK_17.0.2_d674ddeexamplesperipheraluart

运行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("rnUART example started.rn");

 

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

 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 溢出问题

 

 

 

 

最后

以上就是完美星月为你收集整理的nrf52832 Uart 调试概述:同步方法:的全部内容,希望文章能够帮你解决nrf52832 Uart 调试概述:同步方法:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部