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.

[参考译文] TMS320F280023C:SCI 模块在溢出错误后停止运行。

Guru**** 2524550 points
Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error

器件型号:TMS320F280023C
主题中讨论的其他器件:C2000WARE

您好!

我使用微控制器的 SCI-A 外设与 THVD1450DGK 连接。 我观察到、外设遇到溢出错误(OE) 大约10-15次后、它停止生成中断。

通过检查外设寄存器可以看到 SCIRXST 寄存器中的所有 RXRDY 和 OE 标志都被置位、RXBKINTENA 和 RXERRINTENA 位也被置位。 中断也在 PIE 级别启用。

以下是我的 RX 中断的代码。 感谢您的帮助。

__interrupt void sciaRX_isr(void)
{
// Check if interrupt was entered because of an error. In that case put SCI module into a reset state.
    if (SciaRegs.SCIRXST.bit.RXERROR == 1)
    {
        //check which error happened.
        if (SciaRegs.SCIRXST.bit.OE)
            sciOEErrorCountThvd++;
        if (SciaRegs.SCIRXST.bit.PE)
            sciPEErrorCountThvd++;
        if (SciaRegs.SCIRXST.bit.FE)
            sciFEErrorCountThvd++;
        if (SciaRegs.SCIRXST.bit.BRKDT)
            sciBRKDTErrorCountThvd++;

        //SW_RESET SCI
        SciaRegs.SCICTL1.bit.SWRESET = 0;
        SciaRegs.SCICTL1.bit.SWRESET = 1;


        sciErrorCountThvd++;
        enter_mute();
    }
    /*enter this if the errors have not caused the interrupt*/
    else if (SciaRegs.SCIRXST.bit.RXRDY) //rx caused the interrupt
    {
        if (SciaRegs.SCIRXST.bit.RXWAKE == 1) // Address byte has been received. RXWAKE is set when address bit is detected in the word.
        {
            rxIndexThvd = 0;
        }
        rxPackThvd[rxIndexThvd] = SciaRegs.SCIRXBUF.bit.SAR;
        switch (rxIndexThvd)
        {
            case 0: //Looking for address byte.
            {
                if (rxPackThvd[0] == SENSOR_ID) // If address byte matches sensor_id
                {

                    rxIndexThvd++; //increase rxIndexthvd to accept next character.
                    SciaRegs.SCICTL1.bit.SLEEP = 0; //bring the uart peripheral out of sleep as it is being addressed!
                    break;
                }
                else
                {
                    rxIndexThvd = 0; //reset rxindexThvd
                    enter_mute(); //if the address byte received doesn't match the one set by software stay in sleep
                }

                break;
            }
            case 1:
            {
                //index 1 will be the instruction type.
                //insert code here to evaluate rxPackLenThvd based on isntruction type.
                //if rxPackLenThvd is fixed leave this if statement empty.
                rxIndexThvd++;
                break;

            }
            default:
            {
                if (rxIndexThvd == (rxPackLenThvd - 1))            //last byte in packet has been received.
                {
                    if (calculate_crc(rxPackThvd, rxPackLenThvd)
                            == ((rxPackThvd[rxPackLenThvd - 2] | (rxPackThvd[rxPackLenThvd - 1] << 8)))) //crc check over here
                    {
                        rxPackCount++;

                        // Return type code Start
                        /*
                         * */
                        // Return Type Code End
                        if (txPackLenThvd > 0) // means that data has to be sent back to the uC
                        {
                            GpioDataRegs.GPBSET.bit.GPIO33 = 1;      //NRE
                            GpioDataRegs.GPASET.bit.GPIO16 = 1;      //DE

                            thvd_copy_shdbuff(); // functions copies shadow buffer into main transmit buffer.
                            SciaRegs.SCICTL1.bit.RXENA = 0;
                            SciaRegs.SCICTL1.bit.RXERRINTENA = 0;
                            SciaRegs.SCICTL2.bit.RXBKINTENA = 0; // disable RX interrupts and RX

                            SciaRegs.SCICTL1.bit.TXENA = 1;// enable TX and TXINT
                            SciaRegs.SCICTL2.bit.TXINTENA = 1;

                            SciaRegs.SCITXBUF.bit.TXDT = txPackThvd[0]; //put the first packet of data to be sent
                            txIndexThvd = 1; //set txIndexThvd to 1 as first byte has already been loaded.
                        }
                        else //if there is nothing to transmit then enter mute again.
                        {
                            enter_mute();
                        }
                        break;

                    }
                    else //crc failed
                    {
                        crcErrorCountThvd++;
                        enter_mute();
                        break;
                    }

                }
                rxIndexThvd++;
            }
        }

    }

    //acknowledge Group interrupt
    PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}


ENTER_MUTE()函数

void enter_mute(void)
{
    GpioDataRegs.GPBCLEAR.bit.GPIO33 = 1; // clear NRE
    GpioDataRegs.GPACLEAR.bit.GPIO16 = 1; // clear DE

    SciaRegs.SCICTL1.bit.SWRESET = 0; // reset

    SciaRegs.SCICTL1.bit.RXENA = 1;   //enable rx
    SciaRegs.SCICTL1.bit.RXERRINTENA = 1;  //enable rx error interrupt
    SciaRegs.SCICTL2.bit.RXBKINTENA = 1;  //enable rxrdy/ break detect interrupt
    SciaRegs.SCICTL1.bit.TXENA = 0; // Disable transmistter

    SciaRegs.SCICTL1.bit.SWRESET = 1; //bring out from reset

    SciaRegs.SCICTL1.bit.SLEEP = 1; //set the UART module in sleep mode till the module receives a stream of data is addressing it
}


calculate_crc()函数
uint16_t calculate_crc(volatile uint16_t *packet, uint16_t packLen)
{
    uint16_t index = 0;
    uint16_t crc = 0;
    for (int h = 0; h < packLen - 2; h++)
    {
        index = ((crc >> 8) ^ ((int16_t) packet[h])) & 0xFF;
        crc = (crc << 8) ^ crc_table[index];
    }
    return crc;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的提问。 如果您不清除先前的错误中断、则不会触发其他中断。

    我想、如果你在最后一个 ISR 的末尾(恰好在中断停止发生之前)检查、错误位仍将被置位(这意味着它们在 ISR 中没有被正确清除)。

    此致、

    Vince

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Vincent:

    感谢您的回复。 我将检查您描述的情况、然后返回给您。 同时,我对这一问题有一些怀疑,因为我对中断应该如何发挥作用有一些误解。

    1. 我应该如何防止此问题? 根据您对错误的猜测检查并在 ISR 的末尾而不是开始处理这些错误、应该解决这个问题、对吧?
    2. 您描述的情况会在何时出现? 我可以想到的一种情况是、由于 RX 就绪标志被设置、我进入了 RX ISR、但在我为 ISR 提供服务时发生了溢出错误(即在 ISR 中的错误检查完成后)。 在这种情况下、SCI 外设不应在当前中断已完成执行后再次发出中断(这一次是为了达到溢出状态)?
    3. 我查看了《技术参考手册 》(第3.5节和第26.11节)、找不到任何对我所描述问题的引用、如中的处理错误标志的规则。 您能给我一个参考、在这里有一些有关这方面的文献吗?

    此致、
    Parth。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Parth、

    感谢您的跟进。 按顺序回答问题:

    [引用 userid="519048" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error/4486275 #4486275]\n 应该如何防止此问题? 根据您对错误的猜测检查并在 ISR 的末尾而不是开始处理这些错误、应该解决这个问题、对吧?

    这是解决它的一种方法。 如果在退出 ISR 之前清除中断、并且它们仍在 PIE 级别设置、则中断将重新进入 ISR。 基本上、一旦您退出 ISR、下一个 ISR 就会被处理、如果特定错误标志仍然被设置、它将重新进入中断。

    [引用 userid="519048" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error/4486275 #4486275]\n 您描述的条件何时会出现? 我可以想到的一种情况是、由于 RX 就绪标志被设置、我进入了 RX ISR、但在我为 ISR 提供服务时发生了溢出错误(即在 ISR 中的错误检查完成后)。 在这种情况下、SCI 外设不应在当前中断已完成执行后再次发出中断(这一次是在溢出情况下)?

    在第一个 ISR 返回后(假设一个更高优先级的中断没有等待)、SCI 确实会在您描述的条件下再次发出中断。 这正是我所假设的发生情况、也是您设置重复 OES 的原因。

    [引用 userid="519048" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error/4486275 #4486275)]我查看了《技术参考手册》(第3.5节和第26.11节)、 找不到任何对我所描述的问题的引用、如中处理错误标志的规则。 您能否给我一个参考、其中有一些相关文献?[/引述]

    我们通常建议使用 C2000Ware 中使用的方法、我们有一个 SCI 回送中断示例、其中包含一个用于清除溢出/中断的 ISR 代码示例。 如果需要以不同的方式处理这些情况、您可以在清除溢出之前添加错误检查。

    {c2000ware_root}\driverlib\f28002x\examples\sci\sci_ex2_loopback_interrupts.c

    此致、

    Vince

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Vince:
    感谢您的澄清。

    [引用 userid="370573" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error/4489485 #4489485"]如果在退出 ISR 之前清除这些中断、并且它们仍在 PIE 级别设置、则它们将重新进入 ISR。 基本上、一旦您退出 ISR、就会立即处理下一个 ISR、 如果特定的错误标志仍然置1、它将重新进入中断。
    Unknown 说:
    SCI 确实会在第一个 ISR 返回后立即在您所述的条件下再次发出中断(假设更高优先级的中断没有等待)。 这正是我所设想的情况,以及为什么要设置重复的 OES [/报价]

    这是否意味着如果一个外设级错误标志在 ISR 中保持未被清除、那么如果没有其他更高优先级的中断挂起、它应该重新进入 ISR?  因为这不是发生的情况。  

    同时、我将签出您所引用的代码。

    此致、
    Parth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Parth、

    [引用 userid="519048" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1190036/tms320f280023c-sci-module-stops-operating-after-overflow-error/4489906 #4489906"]\n 这是否意味着如果 ISR 中的外设级别错误标志保持未清除状态、则如果没有其他更高优先级的中断待处理、应重新进入 ISR?  因为这不是发生的情况。  
    [/报价]

    我想我误解了你的最初帖子。 我想您的意思是它被困在 ISR 中、而不是离开它。 您能否确认该过程在代码中停止接收中断时的位置? 基本上:CCS 中堆栈跟踪和代码窗口的屏幕截图、调试器在停止接收数据时暂停。

    此致、

    Vince

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Vincent:

    因为我不好,我无法回到办公室。 因此会延迟。 我会尽快回复您。

    此致、Parth