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.

[参考译文] TMS320F280025:SCI 通信字节时序

Guru**** 2551110 points
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1198816/tms320f280025-sci-communications-byte-timing

器件型号:TMS320F280025
Thread 中讨论的其他器件:SysConfigC2000WARE

我在中断模式下使用 SCI。 无 FIFO。

当我接收到 charachter (8位、9600波特、无奇偶校验、1个停止位)时、我获得了中断。 在中断例程中、我将字符从缓冲区中拉出、并将其放入我自己的 RXBuf 中、以将消息标空。 我一直在寻找一个 作为终止字符、因此我可以设置一个标志、告知主例程有一条消息就绪。 这种技术已经使用了40年左右、广泛用于各种处理器。 其中包括2406和28069。 非常基本的东西。

如果我使用超级终端等终端程序、并一次发送一个字符的消息、一切都很顺利。 我命中时、字节将放入接收缓冲区 对消息进行解码并执行相应操作。

问题:

如果我使用我的应用程序(已经使用它20多年了)、它允许我单击一次发送整个消息、中断仍然会发生在每个 charater 上、但280025 RXBUF 产生的结果是巨大的。 输出的字节与正在输入的字节不匹配。 这就好像字符尚未完全移入缓冲区一样。 很自然、我的应用程序产生的字节一个接一个地出现、但正确的起始位和停止位也存在、因此它不应该是计时数据。

知道这家伙在干什么吗?

一如既往,所有精彩的建议和愚蠢的想法欢迎...

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

    尊敬的 David:

      

    非常感谢您的问题和简洁的解释、非常感谢。 所以 SCI 模块实际上有几个原因可能导致这个问题(诚然、由于一些非典型的行为、这一点比其他 UART 外设"复杂"一些、我们希望在未来的器件中可以纠正)。

       

    1.首先要注意的是可能导致这种情况的原因:

    缓冲器中断(实际上是任何 SCI 中断)在中断之间需要有效的2个停止位。 说明:

    每次在 SCI 上触发中断时、中断直到检测时间的停止位1/8才会启动。 确切数字为:中断触发(停止位结束)与 ISR 实际启动之间的延迟=((7*波特_CLK_PERIOD)/8+3* SYSCLK_PERIOD)。 这意味着中断只有1/8的位周期来执行。 波特率为9600时、这也许没问题、除非 ISR 本身很长。

    这是 SCI 本身的一个问题。 因此、中断之间总共需要大约7/8位周期检测时间。 这并不是大多数其他器件 UART 的典型情况、也是在考虑到所有正常情况(波特率不匹配、噪声等)时导致 C2000器件出现大量误差的最常见原因。 是的、这并不理想、因为它需要其他器件(本例中为 PC)在字节之间插入延迟。 如果字节之间有足够的延迟(用户手动点击听起来应该有足够的延迟)、则下一个可能的问题可能就是原因。 听起来你已经将其与诸如28069的 C200器件上的其它"SCI"模块一起使用、所以这也不是原因。

      

    2.另一种可能的情况是波特率不匹配。 我很确定您可能已正确设置、并且在9600等低波特率下、有足够的粒度。 但如果将280025上的 LSPCLK 设置为非常低的值、则可能会出现问题。 这更属于"愚蠢的想法"类别,但它仍然值得健全的检查

      

    3.可能是软件问题吗? 您是否偶然为 config 设置 sysconfig -和- driverlib 函数? 我担心的是、在使用 driverlib 手动写入之后、使用 SysConfig 意外地设置配置。 默认情况下、大多数新 C2000Ware 软件包在示例中都包含 SysConfig 文件、因此、如果您最近基于另一个工程启动了一个新工程、其中可能会设置 SysConfig。

      

    上述问题之一可能是问题的根本原因、但可能不是。 能否向器件的 RX 引脚发送一个输入数据的示波器捕获、以便我进行完整性检查? 它可能不是一个物理的东西,但它总是值得检查一下。


    此致、

    Vince

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

    感谢您的回复。  

    这里是两个示波器屏幕截图。 青色迹线是数据。 输入接收中断后、黄色快速变为低电平(在我包含的代码中可看到)。 它在接收中断退出前变为高电平。 它只是一个小"尖峰"、所以你可以看到中断很短。

    我还在右下角展示了缓冲器的存储器内容。

     

    该信息是"/111. "。 缓冲区中的数据应为3个0x41和1个0x0D。

    有趣的是、这里是/1UUU 。 我选择了位模式以获得010101... pattern 持续下去。 在这种情况下、缓冲区数据是正确的。  

    数据似乎正在被移动。 在触发中断时、数据是否可能还没有实际到达硬件 RX 缓冲区? 也许芯片设计人员掩盖了这种情况、假设人们只使用 FIFO 类型通信?

    //receive interrupt
    __interrupt void SCIRXINTA_ISR(void)
    {
    asm(" CLRC INTM"); /* enable global interrupts */
    // PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
    
    if(boolComLEDStatus == 0)//if LED is on
    {
    boolComLEDStatus = 1;//LED
    GPIO_writePin(DEVICE_GPIO_PIN_COMM_LED, 0);//turn ON COMM status LED <<<<<--------yellow trace goes low
    LEDComCounter = LEDComRate;
    }
    // asm(" CLRC INTM"); /* enable global interrupts */
    if(SCI_isDataAvailableNonFIFO)
    {
    
    if (RXState != OEMCheckSum)
    // SER_IN = SciaRegs.SCIRXBUF.all & 0x7F;
    SER_IN = SCI_readCharNonBlocking(SCIA_BASE);
    else
    // SER_IN = SciaRegs.SCIRXBUF.all;
    SER_IN = SCI_readCharNonBlocking(SCIA_BASE);
    }
    else
    {
    return;
    }
    if (!CommunicationsFlags.xmiting)
    {
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    switch (RXState)
    {
    case 0: //we're looking for the very first start character after
    //we\\'ve been reset. We'll also set the unit address from here.
    {
    
    if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    }
    else if (SER_IN == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = STX;
    }
    // SCI_clearInterruptStatus(SCIA_BASE,SCI_INT_RXRDY_BRKDT);//clear rx int flag
    // SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag
    // PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
    break;
    
    }
    
    //===================================
    //DT PROTOCOL
    
    case DTStart:
    {
    if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    // for (xser=0;xser<5;xser++)//prevent running old commands
    // {
    // RCV_BUF[xser] = 0xFF;
    // }
    
    }
    break;
    }
    
    case DTAddress:
    {
    ADDRESS = SER_IN;
    if (ADDRESS == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    // for (xser=0;xser<5;xser++)//prevent running old commands
    // {
    // RCV_BUF[xser] = 0xFF;
    // }
    
    }
    else
    {
    //set the receive state to look for the <CR>
    //, address decoding will be done in the command decode section
    // if (ADDRESS == UnitAddress)
    RXState = DTCR;
    // else
    // RXState = DTStart;
    }
    break;
    }
    case DTCR:
    {
    
    if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    
    }
    else if (SER_IN == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = SER_IN;
    }
    else if (SER_IN == cstBackSpace)
    {
    if (RCV_PNT != 0)
    RCV_PNT --;
    }
    else
    {
    RCV_BUF[RCV_PNT] = SER_IN;
    if (SER_IN == 0x0D)
    {
    CommunicationsFlags.DTProtocol = 1;
    CommunicationsFlags.OEMProtocol = 0;
    CommunicationsFlags.MSG_Here = 1;
    RXState = 0;//wait for either start character
    }
    RCV_PNT ++;
    if (RCV_PNT > cstRXBufLength -1)
    {
    ErrorCode = cstCommandOverFlow;
    RCV_PNT--;
    
    }
    }//end else
    break;
    }//end case
    
    
    
    //=====================================
    // OEM PROTOCOL
    case OEMStart: //wait for start of transmition
    {
    if (SER_IN == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = SER_IN;
    }
    else if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    }
    break;
    }
    
    case OEMAddress: //wait for address
    {
    ADDRESS = SER_IN;
    RXSum = RXSum ^ SER_IN;
    if (ADDRESS == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = SER_IN;
    }
    else if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    }
    else
    {
    //set the receive state to look for the sequence byte
    //, address decoding will be done in the command decode section
    // if (ADDRESS == UnitAddress)
    RXState = OEMSequence;
    // else
    // RXState = 0;//wait for either start character
    }
    break;
    }
    
    case OEMSequence: //wait for sequence number
    {
    Sequence = SER_IN;
    RXSum = RXSum ^ SER_IN;
    
    if (Sequence == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = SER_IN;
    }
    else
    {
    RXState = OEMETX;
    }
    break;
    }
    
    
    case OEMETX: //receive characters until ETX
    {
    RXSum = RXSum ^ SER_IN;//xor
    
    if (SER_IN == STX)
    {
    RXState = OEMAddress;
    RCV_PNT = 0;
    RXSum = SER_IN;
    }
    else if (SER_IN == '/')
    {
    RXState = DTAddress;
    RCV_PNT = 0;
    
    }
    else
    {
    RCV_BUF[RCV_PNT] = SER_IN;
    if (SER_IN == ETX)
    {
    RXState = OEMCheckSum;
    }
    RCV_PNT ++;
    if (RCV_PNT > cstRXBufLength -1)
    {
    ErrorCode = cstCommandOverFlow;
    RCV_PNT--;
    
    }
    }//end else
    break;
    }//end case
    
    case OEMCheckSum: //wait for checksum
    {
    if (RXSum == SER_IN)
    {
    
    CommunicationsFlags.MSG_Here = 1;
    CommunicationsFlags.DTProtocol = 0; //set the protocol
    CommunicationsFlags.OEMProtocol = 1;
    }
    RXState = 0;//wait for either start
    break;
    }
    default:
    {
    ErrorCode = cstCommunicationsError;
    }
    }//end switch
    // RI = 0;
    SCI_clearInterruptStatus(SCIA_BASE,SCI_INT_RXRDY_BRKDT);//clear rx int flag
    GPIO_writePin(DEVICE_GPIO_PIN_COMM_LED, 1);//turn OFF COMM status LED Debug stuff<<<<<<-----Yellow Trace goes high
    boolComLEDStatus = 0;//LED
    }
    else
    {
    ErrorCode = ErrorCode;
    }
    // RI = 0;
    // LED2 = 1;
    
    
    // PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
    // GpioDataRegs.GPACLEAR.bit.GPIO24 = 1;
    return;
    } //end receive interrupt

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

    上一封邮件中有拼写错误。 "111"当然应该是0x31等。

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

    尊敬的 David:

      

    这绝对是我在上面提到的问题。 这些是在镜像中接收的背靠背字节(只有1个停止位)、并且每个中断 ISR 所花费的时间可能超过1/8位周期(指定 ISR 的时间长度)。

    我建议将大部分代码移动到 ISR 外部、这样 ISR 只会将数据移动到普通存储器中、以便在主程序中处理前一个中断时可以触发下一个中断(而不会阻止下一个中断的移动)。

    此致、

    Vince

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

    导致该问题的 UART 有何不同之处?

    请再次查看照片。 当中断例程启动时、黄色变为低电平、当中断例程退出时、黄色变为高电平。 它会在下一个开始位之前完成整个例程。  

    从我使用8080、8031的 Z80的2406、28069等的时候开始、(是的、我已经老了) UART 被双缓冲了、 也就是说、当检测到停止位时、传入的位流将进入移位寄存器、将整个字节放入 RXBuf、并触发中断。 只要在下一个完整的字节移入 RXshift 寄存器之前从 RXBuf 寄存器中提取字节、就没有问题。 这使您可以用1毫秒 (9600波特)  来获得字节、坦率地说到处乱七八糟、而不会丢失数据。  

    此外、我看到的数据实际上并不是"giberish"、它的外观是我发送的位模式、我仅从应该移位的位置偏移了大约4位。

    所以有人认为打破一些几十年来行之有效的方法是一个好主意吗? 这真的让我头痛不已。

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

    尊敬的 David:

    [编辑、在完成句子之前发送]

    抱歉、我曾认为您将其排除在捕获范围之外、分辨率大幅降低、并且使其看起来像噪音  

    如果这实际上与您之前在其它器件上使用的程序是一样的、那么它的运行方式应该与28069相同(只更改16级 FIFO)。 与 F280025x 通信的硬件与与与与 F28069通信的硬件是否相同? 如果是、所提供的 F280025x 硬件上有一些不同之处。 问题是、我看不到数据本身有任何直接错误。

    器件是否正确处理非中断代码? 这意味着、如果您进行轮询、它是否正常工作?

    此致、

    Vince

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

    您好、Vince。  

    我不使用 FIFO、因为我对传入的每个字符都进行限定。 是的、这基本上是我在1983年为8031 8位微控制器编写的代码。 我一直在使用什么是基本相同的东西,从那时起,十几个不同的模型的微处理器。 其中三个是不同的 TI DSP。 唯一改变的是访问硬件的实际方法。  

    只是对于 grins、我的确将停止位设置为2、这样就行了。 我真的不喜欢这样做、因为我们所有的东西都默认为9600、N、8、1……

    但是、这告诉我、280025中确实有一些不同的东西、并且在进入中断时对 RXBUF 进行仿真读取会得到尚未完全移入的数据。 即使图表显示输入移位寄存器和 RXBUF 寄存器之间的数据路径是并行的、这是真的吗?

    我正在思考做另一个测试,我只是在一个:浪费一些时间"循环,然后再读取 RXBUF 和看看什么做.  

    如果您有任何其他好想法、请与我们分享。

    此致、

    大卫

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

    尊敬的 David:

    很高兴2个停止位可以正常工作、但我知道不喜欢这一点(这是中断方案中的一个严重限制、您可以打赌我们已经提出了这个问题、需要针对下一代器件进行重新设计)。 具体来说是因为我们知道大多数器件并不像您正确提到的那样缺省为2个停止位。

    这里只是为了说明发生中断的原因:中断的检测机制本质上是此处的瓶颈。 数据像预期的那样位于移位寄存器和缓冲器中。 只是中断在" 100%确定"后才会触发。它是接收到的停止位、需要完整的~7/8位时间。 对于大多数 ISR 长度来说、此波特率为9600应该是合适的。 但有时不是。

     

    现在、如果您可以为它留出 CPU 周期、这里有一个额外的权变措施可以发挥作用:如果您进行轮询(因此、完全禁用中断、仅读取 SCI 的状态位以查看是否收到任何结果)、则这个问题不存在。 基本上、在实际中断触发前、已接收数据的状态位会被置位。 因此、您可以通过执行轮询来避免数据丢失/未对齐。 但很显然、这并不适用于每个应用、并且会占用 CPU 大量资源。

      

    感谢调试、如果有任何其他相关问题、请告诉我。

    此致、

    Vince

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

    您好、Vince。  

    我仍然不理解我所看到的解释。 如果在确定 RXBUF 寄存器中的数据之前中断不会触发、那么当我进入我的处理例程并从寄存器中抓取该数据时、这应该是正确的。  

    不过、经过更多的测试后、串行数据似乎正在直接移入 RXBUF 寄存器。 最初我认为数据没有完全加载到 RXBUF 寄存器中。 我在读取字符之前添加了一个"for"循环、想在 ISR (中断服务例程)中浪费时间。 这只改变了寄存器中的位模式。  

    我还进行了测试、其中我将280025中的 UART 设置保留在1个停止位、但将发送器更改为2个停止位。 工作原理。 从这两个测试中可以看出、根本没有数据的"双缓冲"。  

    我确实在数据表中看到 它声称串行数据被"缓冲"。 我还认为有一个8深缓冲器配置的东西、但我不确定这是否与"LIN"类型的串行硬件有关。  

    除了传输2个停止位外、您能想到什么也不能让该处理器正常工作吗? 我正在尝试用这款处理器取代2406(这是很难来的时代),但应用程序必须是"插入兼容"...

    此外、尽管您有所注意、但在之前的代码版本中、我从未使用过"API"、我使用了直接引用硬件、如:

    SciaRegs.SCIHBAUD =0x0001;// 9600波特@LSPCLK = 20MHz (80MHz SYSCLK)。
    SciaRegs.SCILBAUD = 0x0003;

    当我在当前项目中获取该值时、我会收到错误。 有任何方法可以轻松实现该目标? 我无论如何都不是编译器专家...

    大卫

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

    尊敬的 David:

    我仍然不理解我所看到的解释。 如果在确定 RXBUF 寄存器中的数据之前中断不会触发、那么当我进入我的处理例程并从寄存器中抓取该数据时、这应该是正确的。  [/报价]

    如果我理解您看到的内容、请解释一下我的意思:问题是启动 ISR 之前的延迟会导致下一个字节(而不是第一个字节)和后续字节被移位、因为它直到太晚才重新启动 RX 轮询。 因此、就像 RX 开始在其起始位的中途查看下一个字节一样。 然后是其后的下一个字节、它现在不是从起始位开始的。 它开始在第一个数据位中读取它。 那么您也可能会遇到错误。

    您能想到传输2个停止位会使此处理器正常工作吗?

    我之前提到的另一种权变措施可能可行、但可能不适合您的项目、具体取决于系统:

    现在、如果您可以为它留出 CPU 周期、这里有一个额外的权变措施可以发挥作用:如果您进行轮询(因此、完全禁用中断、仅读取 SCI 的状态位以查看是否收到任何结果)、则这个问题不存在。 基本上、在实际中断触发前、已接收数据的状态位会被置位。 因此、您可以通过执行轮询来避免数据丢失/未对齐。 但很显然、这并不适用于每个应用、并且会占用 CPU 大量资源。

      

    [/报价]

      

    要回答下一个问题:

    此外、尽管您有所注意、但在之前的代码版本中、我从未使用过"API"、我使用了直接引用硬件、如:

    SciaRegs.SCIHBAUD =0x0001;// 9600波特@LSPCLK = 20MHz (80MHz SYSCLK)。
    SciaRegs.SCILBAUD = 0x0003;

    当我在当前项目中获取该值时、我会收到错误。 有任何方法可以轻松实现该目标?

    [/报价]

    是的、有两种方法:

    如果您希望继续使用 driverlib (推荐使用、因为许多 API 调用可能非常有用)、那么您可以使用 hw_memmap.h 和 hw_sci.h 文件对给定的寄存器进行直接读取/写入。

    因此、您在 hw_memmap.h (SCIA_BASE)中获得了 SciaRegs 等效文件。 这是 SCIA 寄存器的基地址

    您在 hw_sci.h 中获得了等效的 SCIHBAUD (SCI_O_HBAUD)。 这是 SCI 寄存器空间内 HBAUD 寄存器的偏移量。

    然后、您可以将其整合在一起:

    HWREGH(SCIA_BASE + SCI_O_HBAUD) = 0x0001; // or some value you want to write

      

    [编辑:忘记输入第二种方式,见下文]

    第二种方法是使用 C2000Ware 中的"device_support"文件夹(而不是"driverlib"文件夹)作为代码库。 "device_support"文件夹都是直接寄存器读取/写入操作。 我们不建议这样做的原因有很多、其中一个原因是最初编写代码和稍后进行调试会困难得多。

    此致、

    Vince

    此致、

    Vince

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

    您好、Vince。  

    我很理解这种说法、但对中断产生这一根本原因的解释是因为它需要是"认证"、对于为什么 RXBUF 中的数据混乱这一说法还是没有道理的。

    当中断触发时(请注意多久)数据被阻止从 RX 移位寄存器传输到 RXBUF、原因是在 ISR 消耗数据前、CPU 禁用了 RXENA。  

    如果没有人过来从 RXBUF 获取数据、则移位寄存器将一直移入数据、直到出现下一个停止位、在这种情况下、将生成"溢出"错误、让编写代码的人员知道他误用了一个字节。  

    因此、这是 ISR 长度的唯一问题。 只要 ISR 的长度少于转移到下一个字符所需的时间、一切都很顺利。至少它已经过去40年左右了...  

    我的小 Pacman UART 视频显示,即使是 Pacman (我的 RXISR)需要一点时间消耗从 RXBUF 的数据,而数据仍然被移入,但仍然应该没有理由数据损坏。

    此外、如果根本原因是 ISR 响应时间、那么启用 FIFO 也应该解决这个问题。 在这种情况下、只要您的消息少于16个字节、到您准备读取消息时、一切都应该很好。 这里、我再次尝试启用 FIFO、但数据的损坏程度与不使用 FIFO 时相同。  

    此致、

    大卫

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

    尊敬的 David:

    [编辑:更正了图像以显示7/8停止位问题、错误地显示6/8停止位]

    感谢这个回复,和平动画是一个非常好的触摸  

    假设 RX 在正确的时间开始正常读取字节、则以下说法是完全正确的:

    我的小帕克曼 UART 视频显示,即使是 Pacman (My RXISR)需要一点时间消耗从 RXBUF 的数据,而数据仍然被移入,但仍然应该没有理由数据损坏。

    正确。 假设 SCI 模块再次正常读取数据、RXBUF 中的所有数据都不应包含任何损坏的数据。

      

    现在我有一个关于你提到的这一评论的问题,这将导致两个答案中的一个取决于你的回答:

    在这里,我再次尝试启用 FIFO,但数据损坏情况与没有 FIFO 时相同。  [/报价]

      


    问题:数据损坏是否发生在第一组16字节中的末尾(FIFO 中断发生之后)? 请告诉我以下哪一项是正确的:


    答案#1:不、在 FIFO 中间、初始化后发送到 SCI 的前16个字节数据内的数据会损坏。

    根本原因#1:如果是这种情况,并且在初始化之后,在数据损坏发生的前16个字节(在第一个 FIFO 中断触发之前)内,您可以确定这是我以前没有看到的。 我们需要采用与当前不同的方式对此进行调试。 这可能与初始化期间没有完全清除 SCI 有关。 但我不认为这是它。


    答案#2:是的,数据损坏在第一次 FIFO 中断(或随后的 FIFO 中断之一)后立即发生。

    根本原因2:请参见下图、希望这幅图能够说明问题所在。 基本上、ISR 可导致 SCI 选通脉冲在每次中断时被移动1。 这就导致检测到我们要查看的位最终发生偏斜。 最后存储在其中一个字节中、 SCI 模块将认为数据位#1是起始位 。 它认为数据位2是数据位1。 它将很高兴地移入 RXBUF 中。 因此数据已损坏。

    此致、

    Vince

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

    2号门...

    似乎280025中有一些独特的东西与 UART 历史上之前介绍的 UART 不同。  

    我可以看到在大约第3或第4个字节后、同步丢失。 您可以看到黄色迹线、出现第一个低电平脉冲 此测试为"非 FIFO"、但没关系。 它符合你给"T"的描述。

    所以,大问题!!

    如何修复/解决此问题。 我有5000个这样的芯片、计划重新设计我们使用2406的旗舰产品。 如果不能跟板上交流、这些芯片就是这么多的报废芯片。

    硬件正需要什么、以实现数据重新同步?

    是否有一个我可以在 ISR 中快速清除的标志、该标志允许正确同步到下一个起始位?

    这仅与 SCI 上的中断有关吗? 如果我(不高兴)想通过轮询 RXRDY 位来处理数据接收、并假设我经常这么做、那么这个同步问题是否消除?  

     

    还有其他相关问题。 整个中断结构是否可能成为这种情况的受害者? CAN 接口是否会出现相同的问题? SPI 呢? I2C?

    我的所有通信技术都是由中断驱动的、此错误会使我的产品无法正常工作。

    您的 UART 设计人员是否了解根本原因以及如何解决该问题?

    如果是、那么何时将该修复应用到芯片设计中? 这是一个非常重要的问题。。。

    大卫

    P.S.,我很高兴你喜欢的 Pacman GIF ...

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

    Dave、

    Vince 已经外出几天了、如果上面涉及到这一点、很抱歉、但您能不能建议您将哪些 GPIO 用于 F28002x 器件上的 SCI?  您是否可以尝试在所使用的所有引脚(GPyQSEL#控制寄存器)上将同步更改为异步模式。  SCI 将同步到其本地时钟、因此我想确保我们也不会将信号同步到 CPU 时钟。

    从根本上说、对于使用 SCI 的 F28002x 器件、与 F28069器件没有变化。

    此致!

    Matthew

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

    Matthew 您好!  

    我将 GPIO 28引脚4用于 SCIA RX。  

    通常、我会打开"查看寄存器"来查看您所讨论的设置。 但是、出于某种原因、我的"registers"窗口不再显示在 CCS12中。 我可能会在某个地方点击某个隐藏的按钮、但无法找回...有任何想法?

    大卫

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

    尊敬的 David:

     [编辑:澄清了中断注释并添加了中断嵌套链接]

    非常感谢对这一问题的跟进和确认。 我将直接回答、尽量完整/简洁(因为我今天不在办公室、下周一回来、所以请延迟回复、直到那时)。

    对于硬件中发生的情况:

    这是否仅与 SCI 上的中断有关? 如果我(不高兴)想通过轮询 RXRDY 位来处理数据接收、并假设我经常这么做、那么这个同步问题是否消除?  [/报价]

    可能的重新同步块1:我可以向设计人员进行彻底的检查、但我相信(不能确定)硬件会等待 SCI 内部中断标志被清除、特别是在这种情况下、与 RX 相关的中断标志被清除。 可以通过在 ISR 中执行立即读取+软件复位或(如果使用 FIFO) RXFFINTCLR 而不是软件复位来测试此情况。

    可能的重新同步块#2:但我需要再次检查 SCI 是否正在查看 PIE 中断(不太可能但可能)并等待它被清除。 如果是这种情况、我们也许可以实现一些软件中断嵌套来解决这个问题。 不理想、但在这种情况下、从技术角度而言可能会有所帮助。 这里是一个到中断嵌套的链接、如果你想脱机尝试的话、我也可以提供这方面的帮助: https://software-dl.ti.com/C2000/docs/c28x_interrupt_nesting/html/index.html

     

    现在关于投票的问题:

    这是否仅与 SCI 上的中断有关? 如果我(不高兴)想通过轮询 RXRDY 位来处理数据接收、并假设我经常这么做、那么这个同步问题是否消除?  [/报价]

    是的、这仅与 SCI 的中断有关。 如果您执行轮询、这将消失、而这一点我们已经过测试、可以正常工作。 很不理想,有很多原因。 但它起作用了。

      

    现在来看看有关其他接口和完整中断结构的问题:

    整个中断结构是否可能成为这种情况的受害者? CAN 接口是否会出现相同的问题? SPI 呢? I2C?

    我的所有通信技术都是由中断驱动的、此错误会使我的产品无法正常工作。

    [/报价]

    否、这只是 SCI 中的一个限制。 其他通信中的中断不会出现此问题。

    我将研究这一点、但我认为在2806x 和28005x 中对 SCI 进行了更改、以增加 SCI FIFO 大小、这也无意中对 SCI 的内部中断架构产生了一些影响。 PIE 方案与此无关。

      

    您的 UART 设计人员是否了解根本原因以及如何解决该问题?

    如果是、那么何时将该修复应用到芯片设计中? 这是一个非常重要的问题。。。

    [/报价]

    设计人员知道、并且更新请求已提交。

    采用 SCI 的现有器件系列不会得到任何应用修复。

    应注意的一点是、SCI 模式(还能够进行 UART 通信)下的 LIN 外设不会出现此问题、因为它基于不同的设计。

      

    如果对此有任何问题、请告诉我、我将在周一与您联系! 同时、其他 TI 专家可协助解决其他相关问题。 感谢您的耐心!

    此致、

    Vince

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

    大家好、Matthew、我再次看到了寄存器视图。 我加载了代码、并手动将 GPIO28的输入限定类型更改为"11"=异步。 这是无效的、因为我的串行数据仍然被收集、我可以通过 COMRX 例程中的测试位的响应看到、在传输几个字节的数据后、中断会前后发生。 非常确信它具有上述场景2中 Vince 所述的行为。 输入"开始/停止位"检测中的某些内容将被丢弃。

    如前所述、这与我数十年来一直使用的代码基本相同。 这里只是关于所涉及硬件寄存器的不同命名规则的调整。  

    我正在对已插入到扩展坞的其中一个280025控制卡进行此开发。  

    如果您能向我展示一个100%运行的接收中断服务例程、即使在下一个字节需要一半的时间才能到达那里、我也会很乐意使用它。  

    此致、

    大卫

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

    您好、Vince。  

    正如我不想做的那样、我在20kHz 计时器循环结束时标记了查看 RXStatus。 如果表明有一个字符已准备就绪、我会调用我的旧 RX 例程(在删除了所有与中断相关的事务之后)并照常处理这些事务。 我还保留了 TX 中断。 由于它长而短、现在的通信波特率达到115200、这对目前来说已经足够好了。

    我希望你们在 UART 中修正这个错误、因为它实际上不应该以这种方式工作。

    下次见...

    大卫

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

    尊敬的 David:

    感谢在 SCI 模块中跟进此问题并道歉。 这当然是我们要求在未来的设备中修复的问题、因为这显然不仅仅是一个小的不便。 我很高兴您能够使用权变措施、但我们也在研究如何在外设的未来版本中纠正此问题。 我们可能会改用 LIN-SCI 和较新的 HS-UART 外设来替换这个较旧的 SCI 外设。 但这也适用于未来的器件。

    此致、

    Vince