LM3S芯片UART中断触发深度的一些疑惑

Other Parts Discussed in Thread: LM3S8962

芯片LM3S8962,使用UART和PC通信。

发现当发送中断触发深度设为2/8时,发送1-5byte都不会进入发送中断,发送大于6byte才会进中断,这是何解??数据确实已经发送出去,但是不会产生中断。

我的理解是:深度设置为2/8时,就是当发送FIFO中还有4BYTE时,触发中断,难道不是这样理解???

 

配置代码:

UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(),9600 , (
                         UART_CONFIG_WLEN_8  |
                         UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));
    UARTIntClear(UART0_BASE, UART_INT_TX | UART_INT_RX | UART_INT_RT);                              /*  8-N-1模式发送数据         */
    UARTIntEnable(UART0_BASE,UART_INT_RX | UART_INT_RT | UART_INT_TX);                             /*  设置UART中断类型          */
    UARTFIFOLevelSet(    UART0_BASE,                              //  设置收发FIFO中断触发深度
                             UART_FIFO_TX2_8,                        //  发送FIFO为2/8深度(4B)
                             UART_FIFO_RX6_8    );                       //  接收FIFO为6/8深度(12B)
    IntEnable(INT_UART0);                                               /*  UART中断使能              */
    IntMasterEnable();                                                  /*  开总中断                  */

  •   您设置的UART_FIFO_RX6_8 其实际值为 0x18,也就是对应的UART FIFO 3/4时,会产生中断,即1~5个字节不产中断,在第6个字节时产生中断,LZ可以参考一下规格书见下图。

  • JSW-Token:

    我指的是发送中断,我把发送深度设成了UART_FIFO_TX2_8,但是只发5byte是不会进入发送中断的,发送6byte才能进发送中断。

  • LEO SU,

      不好意思,搞错了,不过发送中断也是同理的, UART_FIFO_TX2_8宏定义是0x01,其对应的是3/4时认为是没有数据的,所以1~5个字节没有中断,需要发送6个字节。

    见下图:

  • JSW-Token :

    我还是没理解明白,3/4 empty的值是多少,假设我发送5byte,那么TX FIFO应该是5吧。empty是什么意思呢?

  • 2/8在TX模式下,指的是2/8空。即当FIFO中的可用空间上升到12或者12以上时候,会触发中断。

    没有做过实验,个人的理解是这样的:

    楼主之所以发5个不会进中断,可能是因为之前写的时候就在发送,所以使用到的FIFO一直没超过4级。

    楼主可以做实验验证下,把UART TX关了再写FIFO,写好后再使能UART发送。这样也许就都会中断了。

  • empty 就是认为没有数据。

  • 根据手册,当我设置TX 中断的触发深度为2/8时,产生中断的条件是不是:

    TX_FIFO的深度(FIFO里还有的数据的数目)小于等于(3/4*16=)12时,产生发送中断,6这个关键数值是怎么运算出来的呢??

     

    还有,为什么驱动库的名字叫做2/8,而其实对应的手册又是3/4呢?很混乱。

  • 不好意思,我记错FIFO大小了,FIFO是16。所以2/8触发中断应该是,FIFO中的可用空间大于16 * (1 - 2/8) = 12时,会产生发送中断。

  • hi richard ma:

    怎么把UART TX给关了??

    我得查一下手册先~

  • UARTFIFODisable(UART0_BASE);

  • Hi, azhiking:

    我做了实验,UARTFIFODisable(UART0_BASE);是不行的,因为那样子设置了之后,FIFO就变成了单字符模式,发送一byte就进中断了。

    对于这个问题,我的理解是:

    假设发送中断触发深度设置成2/8,就是说当发送FIFO中还发剩4个byte时(注意:必须是4个,小于4或者多于4都不行,其他深度同理),进入发送中断。

    那为什么我填5个byte的时候还是没法进中断呢,我想原因在于,填的同时,也启动了发送,就是说,一边填,一边发,FIFO里面永远没有机会发剩4byte,就进不了中断,

    我改了一下代码:

    填FIFO之前,

    HWREG(UART0_BASE + UART_O_CTL) &= ~UART_CTL_TXE;   //禁止UART发送

    填完FIFO之后,

    HWREG(UART0_BASE + UART_O_CTL) |=  UART_CTL_TXE;  //使能UART发送

    这样填5byte就能进中断了,1-4byte还是进不了中断,如果理解正确的话,我觉得这应该算是M3的一个BUG吧,隐蔽的BUG。

  • 在2/8模式下,FIFO剩余空间只有从小于12,增加到大于等于12时才会触发中断。

    发送1-4个byte时FIFO剩余的空间始终大于12,所以不会触发中断。

    这个现象不是BUG。楼主可以检查下,虽然没有进入中断,但1-4byte数据都是正确发送出来的。

  • hi, richard,

    你是对的,1-4byte都能正确发送出来,只是没有进中断。

    但是像我前面所说的,如果发5byte,没有注意填FIFO的之前关发送,那就会造成进不了中断的后果,如果采用中断发送的方式发送大量数据,就有可能造成某些数据发送不出去导致丢包,这个我觉得只看datasheet的话,挺难理解的,还是要感谢大家的讨论。

  • 如数据手删所说,UART是按FIFO空(TX)或满(RX)比例产生中断。我比较喜欢收发都设成7/8,接收使用超时中断处理数据已经发送但FIFO没有达到触发条件的情况。 TI的UART这个设计确实是爽,不需要DMA就能以很少的开销发送大量数据。

    其实数据发送不一定要在中断启动。完全可以简单一点处理数据发送。即所有的数据发送调用发送函数,发送函数启动数据发送,后续在中断在自动完成。

    发送函数。

    1.把所有待发送数据写入发送队列。(队列满时需要调用第二步填允FIFO,若FIFO也满则需要等待队列有空间)。

    2.检查发送FIFO是否满,未满则读发送队列填允FIFO,直到FIFO满或队列为空为止。

    发送中断处理非常简单,

    1.提取队列数据写发送FIFO,直到FIFO为满或队列为空为止。