This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129芯片的UARTBusy函数

Other Parts Discussed in Thread: TM4C129ENCPDT, EK-TM4C123GXL

大家好,我想实现串口的单字节发送,就是当上位机有查询指令后,TM4C响应时单字节响应,当将一个字节的响应放到FIFO中发送时,使用ROM_UARTCharPutNonBlocking()这个函数将其发送到串口发送器上。关于判断一个字节是否全部已经从移位寄存器,包括停止位什么的,手册上有说:只有当发送FIFO为空,并且最后一个字符包括停止位已经从移位寄存器被发送时,Busy位失效。我想发送一个字节时,先判断当前FIFO是否为空,再判断Busy位是否无效,再进入发送。

(1)这个busy位是否可以使用UARTBusy函数来处理?

(2)我想请教下这个函数ROM_UARTCharPutNonBlocking()是使用FIFO发送字符,具体执行流程是什么?将字符发送到移位寄存器上,不等待其是否全部发完就返回吗?

(3)UART发送还有一种模式是不使用FIFO的,直接使用UARTCharput函数发送字符,那这个函数是将接受到的数据直接发送到移位寄存器上,每次发送字符前应该也是需要先判断Busy位是否无效?

(4)TM4C的UART手册上说的,好像是默认不启用FIFO的情况时单字节处理的,其实也是使用了FIFO,只是是单字节触发的,是这样的吗?上一个的UARTCharput其实也是说的使用了FIFO,但只是单字节触发的?单字节触发的话UART就要使用阻塞模式处理发送和接收,如果设置FIFO深度的话,UART便可使用不阻塞的方式处理了是吗?

有一些多,谢谢大家看完,给指点下。

  • 请问您现在使用芯片的具体型号是什么?是使用的自己的程序还是TI的例程?

    关于您的UART相关问题,我会在总结后给您回复
  • 关于UARTBusy您可以参考下面文档的30.2.2.6 UARTBusy

         

     可以采用如下的方式:

     while(UARTBusy(UART0_BASE));

  • 2  在例程中的使用方式如下

    //*****************************************************************************
    //
    // Send a string to the UART.
    //
    //*****************************************************************************
    void
    UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
    {
        //
        // Loop while there are more characters to send.
        //
        while(ui32Count--)
        {
            //
            // Write the next character to the UART.
            //
            ROM_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);
        }
    }

    ROM_UARTCharPutNonBlocking的使用意味着,如果Tx FIFO中的字符串空间不足,则UARTSend函数将丢弃字符串中的字符。

    具体您可以看一下 http://www.ti.com/lit/ds/symlink/tm4c1294ncpdt.pdf

    16.3.8 FIFO Operation 以及 Figure 16-1. UART Module Block Diagram

    3  是的

  • 谢谢您,我用的是TM4C129ENCPDT,谢谢您提供相关文档,UARTsend函数,例程中提供的对于发送是循环处理的,就是说如果查询长度是20个字节,则循环将20个字节一次性全部发送出去后再跳出UARTsend函数。我现在是这么处理的:查询长度20个字节,将一个字节放置到发送器后,系统跳出UARTSend函数去执行其他任务,等发送器一个字节内容发送完毕后系统再继续执行UARTsend函数发送第二个字节。但系统同时会有多个串口任务,我想请教下,是否有多串口间一个字节发送的这种案例?
  • pei gong said:
    我现在是这么处理的:查询长度20个字节,将一个字节放置到发送器后,系统跳出UARTSend函数去执行其他任务,等发送器一个字节内容发送完毕后系统再继续执行UARTsend函数发送第二个字节。

    我对此有些不太理解。您现在是不想循环发送,而是

     先发送1个字节---> 退出UART去执行其他任务---->继续UART任务

    是上面的流程吗?

    您是否可以给出相关代码?

    pei gong said:
    但系统同时会有多个串口任务,我想请教下,是否有多串口间一个字节发送的这种案例?

    请问能否详细说明一下?谢谢

  • 是的,是这样的:当前如果有2个串口UART0、UART1,先向UART0发送1个字节---> 退出UART0去执行UART1---->UART1发送1个字节->退出UART1去执行UART0,两个串口交替执行。这样的话,是不是执行效率会高一些?如果是循环发送的话,需要等UART0全部发送完全后才能再去执行UART1.
  • 您现在是假设一共要发20个字节,对比两种方式的效率?

    1 UART0 和 UART1交替发送

    2 单独一个UART全部发送

    所以您现在两个串口都是连到另外一个芯片的两个串口上?总共就需要发送20字节?

    若是这样的话,单独一个UART全部发送会更好一些。 因为UART0 和 UART1交替发送的话,执行的语句会更多,反而会效率低

  • 您好,是的,我想对比下这两种方式的执行效率。我用的是2个独立的UART分别接了两个芯片的串口,分别需要发送20个字节,两个串口是独立的,想通过UART0和UART1交替发送。这种方式执行的语句是多了些,但是单独一个串口UART0执行循环发送的话在UARTsend函数的While中是不是需要等待较长的时间后才能转向UART1的发送呢?
  • 很抱歉,漏掉了这个帖子,现在才看到您的回复

    您可以使用CCS内的对程序运行时间进行测量功能来测试代码的运行时间。

    在debug模式下,点击Run -> clock -> Enable 打开clock 功能,这时在右下角有个时钟的图标出现。 双击它可以清零。

    然后您在要测试的代码上打两个断点,分别运行到两个断点处,就可以看到代码运行周期了。
  • 好的,谢谢,我测测。
  • 期待您的反馈!
  • 您好,我想发一个字节前先判断下上一个字节是否发完,如果发送完成后则继续下一个发送
    while(!ROM_UARTBusy(UART2_BASE))
    {
    ROM_UARTCharPutNonBlocking(UART2_BASE, SendCode);//发送
    }
    测试中发现串口上数据并没有发出来。这么判断不合理吗?
  • ROM_UARTCharPutNonBlocking(UART2_BASE, SendCode);执行完这句后需要增加2.6ms左右的延时,才能正常发送出去。
  • 是的 这个函数的话发送新的数据放入UART是需要一定的延迟(您必须确保传输了先前的数据)

    您可以尝试使用 ROM_UARTCharPut
  • ROM_UARTCharPutNonBlocking这个函数主要是将数据写入到发送FIFO中->字符从发送FIFO到移位寄存器->串口数据,您的意思是字符从发送FIFO到移位寄存器有一定的延时?if(!ROM_UARTBusy(UART2_BASE))那在发之前加这个忙判断后测试串口数据仍是发不出来?想请您分析下。
  • 您好,用这个函数ROM_UARTCharPut()发送也需要大概2.6ms的延时。
  • 由于手边没有129的板子,所以我现在使用TM4C123的板子来测试的

    使用的例程是TivaWare内的例程,默认路径 C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\ek-tm4c123gxl\uart_echo

    设置断点,打开clock功能是可以查看程序运行所需要的系统时钟数,从而得出程序的运行时间

    pei gong said:
    也需要大概2.6ms的延时

    这个延时是确定的吗?

  • 嗯是的,非常感谢您的回复。确实是需要延时大概1.7~2.6ms的时间。
    两个串口单字节交替发送的功能我这边实现了。就是因为有这个延时,所以我想用ROM_UARTBusy(UART0_BASE)这个函数,可以将延时去掉,但用了ROM_UARTBusy(UART0_BASE)这个函数后串口数据就发不出来了。
  • 我们会在下面的帖子内继续讨论

    e2echina.ti.com/.../187396