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.

[FAQ] 我的 C2000 SCI 未正确发送和/或接收数据,如何解决该问题?

Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

问:如果 SCI 模块在发送和接收数据时遇到问题,出现通信问题的主要原因有四个:

  1. 硬件问题
  2. 系统问题
  3. 配置问题
  4. 代码问题

如何确定这四个问题中的哪一个是问题的根源,可以执行哪些更正来解决该问题?

  • 答:

    1 简单的调试提示

    大多数情况下,追踪问题根源(以及问题发生的原因)的最简单方法是使用示波器(逻辑分析仪)对器件 SCI-TX 和 SCI-RX 引脚的捕获结果。

    该方法之所以非常有效,是因为它可以立即排除/确认几个关键原因:

    1) 通过奇怪的波形行为可立即断定硬件问题。

    2) 配置和系统级问题很容易看到,因为一条线路可以正常工作,而另一条线路无法正常工作。

    3) 缺少输出的问题可以立即显示。

    4 )如果存在数据,但在寄存器中未接收到数据,则很容易跟踪代码问题。

    5 )对于数据存在但值错误的问题,可以借助波形通过删除导致问题的代码(波形不良,数据不良)或配置(波形良好,数据不良)轻松地进行调试。

    因此,我强烈建议首先使用某种波形查看器件进行故障排除。如果这不能立即显示问题,请参阅下一节介绍的更深入的调试步骤。

    2 找到问题的根源

    观察到的实际问题是什么?在下面的列表中找到您的问题,然后使用提供的信息进一步调试。注意:某些问题可能属于多个类别/问题描述,因此应使用来自所有部分的相关信息进行调试。

    2.1 硬件问题症状和原因

    • 调试器无法正常工作(或完全无法工作)。
    • 原因:JTAG 连接问题。有关解决 JTAG 和调试器相关问题的说明,请参阅 https://www.ti.com/cn/lit/SPRACF0 以了解调试步骤的完整演示。
    • SCI-RX 引脚上的 SCI 波形不正确(不恢复至高电平)。
    • 原因:SCI-TX 路径中的电路不正确(如果其他非 C2000 器件的软件/硬件在与电路相隔离时被验证为工作正常)。
      • SCI/UART 协议器件的 RX 引脚需要在电路中使用一个上拉电阻器,以便信号无需被驱动即可恢复至高逻辑电平。必须小心选择上拉电阻器,以避免其值过大(弱),从而不会实际从另一个器件上拉三态或浮动输出。弱上拉可能也会受到噪声的影响。因此,还必须为上拉电阻器选择不是太小的值(强),以免其阻止输出信号从其他器件切换。这种上拉电阻器的确定在很大程度上取决于应用,因此说“使用 X 电阻”并不总是正确的。不过,10 千欧通常足以用于开始在应用中测试哪些电阻可以正常工作。用户必须针对特定应用和预期的系统行为对此进行测试。
      • 还值得注意的是,下拉电阻器会对正常功能产生不利的影响。因此 SCI-TX/RX 路径中不能使用用于升压/降压逻辑电平的电阻分压器,因为即使是比较微弱的下拉电阻器的 GND 基准也会在不受驱动时始终将电压拉回到 GND。这会导致标记 BRKDT 和系统中的其他错误。
    • SCI-TX 引脚或系统中其他器件的 RX 引脚上的 SCI 波形不正确(不恢复至高电平)。
    • 原因:SCI-TX 路径中的电路不正确(如果已验证不是软件问题)。
      • 与 SCI-RX 引脚类似,SCI-TX 引脚期望另一个器件的 RX 引脚在另一端具有一个上拉电阻器,以便能够抗噪和强制恢复至高逻辑电平。如果缺少该上拉电阻器,则另一个器件可能无法恢复至适当的逻辑电平,并且会接收到不正确的信号。请注意,当模块启用时,C2000 SCI-TX 引脚将恢复至高逻辑电平,但 C2000 器件和其他器件之间的任何收发器在没有上拉电阻器的情况下可能无法强制恢复至高电平。
      • 还值得注意的是,下拉电阻器会对正常功能产生不利的影响。因此 SCI-TX/RX 路径中不能使用用于升压/降压逻辑电平的电阻分压器,因为即使是比较微弱的下拉电阻器的 GND 基准也会在不受驱动时始终将电压拉回到 GND。这会导致标记 BRKDT 和系统中的其他错误。
    • 可以在引脚上看见正确的数据,但其他器件完全接收不到这些数据。
    • 原因 1:C2000 器件缺少收发器:
      • 首先必须注意的是,任何与 PC(个人计算机)通信的 C2000 器件都必须具有一个收发器,以便在 USB (PC) 协议和 UART(C2000 SCI 模块)协议之间进行转换。USB 和 UART 之间可能存在中间协议,例如 RS232。无论如何,PC USB 信号必须转换为 UART 协议,才能由 C2000 器件的 SCI 模块(或任何其他 UART 器件)进行解析。某些 C2000 LaunchPad 和 ControlCARD 开发板具有连接到特定 GPIO/SCI 引脚的板载收发器。通常,这些收发器和 USB JTAG 调试仿真器一起内置在开发板中,但并非在所有 C2000 器件上都可用。有关收发器是否内置在开发板中的详细信息,请参阅特定开发板的用户指南(位于产品页面上)。可以在用户指南中搜索“UART”、“COM 端口”或“SCI”关键字。
    • 原因 2:收发器电路不正确(假设存在收发器)。
      • 应确保在 RX 引脚上提供上拉电阻器,这一点至关重要。这适用于任何 C2000 器件的 RX 引脚,也适用于系统中从收发器接收信息的任何其他基于 UART 协议的器件。这是因为某些收发器不会在数据包之间强制电压恢复至高电平。这可能导致行为不正常的浮动电压,即在数据包之间保持低电平或者随着环境中的噪声进行随机切换。通过查看 C2000 器件的 RX 引脚或系统中其他器件的 RX 引脚上的波形,可以观察到这一点。在大多数情况下,必须在系统中所有 UART 协议器件的 RX 引脚上连接一个上拉电阻器。
    • 在该器件或其他器件的 SCI 模块中出现一致的 BRKDT(中断检测)错误。
    • 原因:SCI-RX/TX 路径中的电路不正确。
      • 对于该问题,上述任何(或所有)硬件问题都可能是导致该问题的根本原因。有关调试推理的详细信息,请查看上述硬件问题。该问题的根本原因可以归结为 SCI-RX 引脚上需要一个上拉电阻器,以提供适当的恢复至高电平信号行为和抗噪性能。

    2.2 系统问题症状和原因

    • C2000 器件或其他连接的器件随机标记 BRKDT(中断检测)错误。
    • 原因:如果在该 C2000 器件中观察到 BRKDT(并且上面的“硬件问题”一节中的所有问题都已得到解决),那么这很可能是系统中其他器件的软件中的问题。在 C2000 SCI-RX 线路上放置一个示波器,观察是否存在大于 9.625 位宽的低电平信号。如果发现该信号,请更正向该 C2000 器件发送信息的另一个器件中的软件。C2000 器件的 SCI-RX 线路上的低电平信号宽度不得超过 9.625 位。
    • 在该 C2000 器件(不是系统中的另一个 SCI 器件)上接收到乱码/随机数据值。
    • 原因 1:另一个器件上的数据包或终端配置不正确。另一个器件必须与该 C2000 器件中的以下所有项匹配:
      • (1) 波特率
      • (2) 数据位的数量
      • (3) 是否存在奇偶校验位
      • (4) 停止位的数量
      • (5)“硬件”或“流量”控制 = 无(在某些系统中为 XON/XOFF)
    • 原因 2:发送到该 C2000 器件的是 ASCII 数据,但需要的是十六进制数据(或者相反)。
      • 如果另一个器件向该 C2000 器件发送字符数据,C2000 提供的示例和函数会将这些数据存储为单独的字符。例如,代码不会自动将接收到的字符数组“100”转换为整数 100,而是将其存储为三个字符:[“1”、“0”、“0”]。必须使用 C 函数(如“strtol()”)将字符数组转换为整数。
    • 两个器件中都出现乱码/随机数据
    • 原因:配置设置不匹配。另一个器件必须与该 C2000 器件中的以下所有项匹配:
      • (1) 波特率
      • (2) 数据位的数量
      • (3) 是否存在奇偶校验位
      • (4) 停止位的数量
      • (5)“硬件”或“流量”控制 = 无(在某些系统中为 XON/XOFF)

    2.3 配置问题症状和原因

    • 在系统中的其他 SCI 器件(不是该 C2000 器件)上接收到乱码/随机数据值。
    • 原因 1:配置设置不匹配。另一个器件必须与该 C2000 器件中的以下所有项匹配:
      • (1) 波特率
      • (2) 数据位的数量
      • (3) 是否存在奇偶校验位
      • (4) 停止位的数量
      • (5)“硬件”或“流量”控制 = 无(在某些系统中为 XON/XOFF)
    • 原因 2:缺少“_LAUNCHXL_F28XXXX”预定义符号。
      • 某些 C2000 板需要一个预定义符号来正确设置器件上的时钟和其他配置设置。请查看工程的“device.h”文件并查看是否存在任何使用与上述预定义符号类似的符号的 #ifdef 行。
      • 如果存在类似“_LAUNCHXL_F28XXXX”的符号,并且该符号是您用于测试的电路板,则需要添加该预定义符号。
      • 在 CCS 中,右键点击使用的工程,选择“Properties”→“Build”→“C2000 Compiler”→“Predefined Symbol”,然后选择加号按钮(“添加”)符号。为 device.h 文件中找到的特定器件添加给定的预定义符号(如“_LAUNCHXL_F280025C”)。
    • 中断未在预期时间触发(或完全不触发)。
    • 原因 1:多路复用不正确(如果完全不触发)。必须正确配置 GPIO 多路复用器选项。
      • 尝试使用SysConfig 工具(内置在新版本的 CCS 和 C2000Ware 中)来配置 SCI 模块及其 PinMux 选项。这提供了用于轻松配置引脚的图形界面
      • 或者,确保在 driverlib 中正确设置以下内容:
        • 使用如下所示的 driverlib 调用设置 RX 和 TX 引脚配置:
          • GPIO_setPinConfig(GPIO_17_SCIA_RX);
          • GPIO_setPinConfig(GPIO_16_SCIA_TX);
        • 或者,确保使用您的代码正确设置以下内容:
          • 确保在所用引脚的 GPIO 配置中启用上拉(在 GP@PUD 寄存器中)
          • 确保在所用引脚的 GPIO 配置中将限定条件设置为仅限异步输入(在 GP@QSEL# 寄存器中)
          • 确保选择正确的 GPIO 多路复用器选项(在 GP@MUX# 寄存器中),以允许 SCI-TX 和 RX 通过 GPIO
    • 原因 2:ePIE 或 FIFO 的配置不正确(如果间歇性不触发或完全不触发)。
      • 尝试使用 SysConfig 工具(内置在新版本的 CCS 和 C2000Ware 中)来快速设置中断和/或 FIFO 配置。
      • 或者,确保在初始化过程中执行以下过程来配置 SCI 模块(按顺序执行这些操作):
        • 首先,确保禁用所有 SCI 中断。
        • 接下来,清除所有 SCI 中断的中断状态(RXFF、TXFF、FE、OE、PE、RXERR、BRKDT、TXRDY),方法是清除然后设置 SCI 的 CTL1.SWRESET 位,然后设置 SCI 的 FFTX.TXFFINTCLR 和 FFRX.RXFFINTCLR 位。
        • 接下来,通过设置 SCI 的 FFRX.RXFFOVRCLR 位来清除溢出状态位。
        • 接下来,通过清除然后设置 FFTX.TXFIFORESET 来重置 RX 和 TX FIFO。
        • 接下来,通过清除然后设置 FFTX.SCIRST 位来重置器件的 TX 和 RX 通道。
        • 接下来,为您的系统实际配置所有 SCI 设置,例如波特率(SCIHBAUD + SCILBAUD 寄存器)、奇偶校验 + 数据长度 + 停止位(SCICCR 寄存器)。
        • 接下来,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 来启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。
        • 接下来,如果使用 FIFO,则设置相应的 FIFO 中断级别,方法是在 FFTX.TXFFIL 和 FFRX.RXFFIL 字段中设置这些级别。必须选择 FIFO 级别,以便在 FIFO 溢出之前为中断提供足够的时间来处理数据请求。对于较长的 SCI ISR,应确保足够早地发出中断,或者将处理移出 ISR,并且仅在 SCI ISR 中执行数据移动(建议)。
        • 最后,如果使用 FIFO,则通过设置 FFTX.SCIRST(如果未设置,但可以安全地重新设置)、FFTX.SCIFFENA、FFTX.TXFIFORESET 和 FFRX.RSFIFORESET 位来启用 FIFO。
        • 最后,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 位重新启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。
    • 原因 3:中断发生冲突或无法获得服务。
      • 当优先级较高的中断频繁发生(或允许嵌套在 SCI ISR 内)时,这些中断可能会阻止 SCI 模块接收所有数据。这些中断具有更高的优先级,并且始终在 SCI 模块有机会启动之前得到处理,从而基本上使 SCI 中断“无法获得服务”。
        • 例如,如果 ADC 中断持续触发并中断 SCI ISR,SCI ISR 可能永远不会(或缓慢地)到达其移动数据的部分。如果缓冲区或 FIFO 在 SCI 开始移动数据之前填满,则可能会导致数据丢失以及缓冲区或 FIFO 溢出。这需要 ISR 之间进行谨慎的交互,以便 ADC ISR(例如)和 SCI ISR 都不会缺少处理时间。
      • 其他非嵌套中断也可能需要很长的时间才能完成,从而使 SCI 缓冲区/FIFO 填满并导致其他数据丢失。这种情况很少见,因为 SCI 发送速度通常比处理速度慢很多。但在其他 ISR 中有一些计算可能需要很长时间,因此在遇到这些 ISR 时也必须十分小心。
    • 输出在 SCIA/B/C 上正常工作,但在 SCIC/B/A 上无法正常工作。
    • 原因 1:多路复用器配置不正确。
      • 尝试使用 SysConfig 工具(内置于新版本的 CCS 和 C2000Ware 中)来配置 SCI 模块及其 PinMux 选项。这提供了用于轻松配置引脚的图形界面
      • 或者,确保在 driverlib 中正确设置以下内容:
        • 使用如下所示的 driverlib 调用设置 RX 和 TX 引脚配置:
          • GPIO_setPinConfig(GPIO_17_SCIA_RX);
          • GPIO_setPinConfig(GPIO_16_SCIA_TX);
        • 或者,确保使用您的代码正确设置以下内容:
          • 确保在所用引脚的 GPIO 配置中启用上拉(在 GP@PUD 寄存器中)
          • 确保在所用引脚的 GPIO 配置中将限定条件设置为仅限异步输入(在 GP@QSEL# 寄存器中)
          • 确保选择正确的 GPIO 多路复用器选项(在 GP@MUX# 寄存器中),以允许 SCI-TX 和 RX 通过 GPIO
    • 原因 2:ePIE 配置不正确(如果使用中断)。
      • 尝试使用 SysConfig 工具(内置在新版本的 CCS 和 C2000Ware 中)来快速设置中断和/或 FIFO 配置。
      • 或者,确保在初始化过程中执行以下过程来配置 SCI 模块(按顺序执行这些操作):
        • 首先,确保禁用所有 SCI 中断。
        • 接下来,清除所有 SCI 中断的中断状态(RXFF、TXFF、FE、OE、PE、RXERR、BRKDT、TXRDY),方法是清除然后设置 SCI 的 CTL1.SWRESET 位,然后设置 SCI 的 FFTX.TXFFINTCLR 和 FFRX.RXFFINTCLR 位。
        • 接下来,通过设置 SCI 的 FFRX.RXFFOVRCLR 位来清除溢出状态位。
        • 接下来,通过清除然后设置 FFTX.TXFIFORESET 来重置 RX 和 TX FIFO。
        • 接下来,通过清除然后设置 FFTX.SCIRST 位来重置器件的 TX 和 RX 通道。
        • 接下来,为您的系统实际配置所有 SCI 设置,例如波特率(SCIHBAUD + SCILBAUD 寄存器)、奇偶校验 + 数据长度 + 停止位(SCICCR 寄存器)。
        • 接下来,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 来启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。
        • 接下来,如果使用 FIFO,则设置相应的 FIFO 中断级别,方法是在 FFTX.TXFFIL 和 FFRX.RXFFIL 字段中设置这些级别。必须选择 FIFO 级别,以便在 FIFO 溢出之前为中断提供足够的时间来处理数据请求。对于较长的 SCI ISR,应确保足够早地发出中断,或者将处理移出 ISR,并且仅在 SCI ISR 中执行数据移动(建议)。
        • 最后,如果使用 FIFO,则通过设置 FFTX.SCIRST(如果未设置,但可以安全地重新设置)、FFTX.SCIFFENA、FFTX.TXFIFORESET 和 FFRX.RSFIFORESET 位来启用 FIFO。
        • 最后,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 位重新启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。
    • 环回示例正常工作,但在引脚上看不到输出。
    • 原因 1:多路复用器配置不正确。
      • 尝试使用 SysConfig 工具(内置于新版本的 CCS 和 C2000Ware 中)来配置 SCI 模块及其 PinMux 选项。这提供了用于轻松配置引脚的图形界面
      • 或者,确保在 driverlib 中正确设置以下内容:
        • 使用如下所示的 driverlib 调用设置 RX 和 TX 引脚配置:
          • GPIO_setPinConfig(GPIO_17_SCIA_RX);
          • GPIO_setPinConfig(GPIO_16_SCIA_TX);
        • 或者,确保使用您的代码正确设置以下内容:
          • 确保在所用引脚的 GPIO 配置中启用上拉(在 GP@PUD 寄存器中)
          • 确保在所用引脚的 GPIO 配置中将限定条件设置为仅限异步输入(在 GP@QSEL# 寄存器中)
          • 确保选择正确的 GPIO 多路复用器选项(在 GP@MUX# 寄存器中),以允许 SCI-TX 和 RX 通过 GPIO
    • 原因 2:ePIE 配置不正确(如果使用中断)。
      • 尝试使用 SysConfig 工具(内置在新版本的 CCS 和 C2000Ware 中)来快速设置中断和/或 FIFO 配置。
      • 或者,确保在初始化过程中执行以下过程来配置 SCI 模块(按顺序执行这些操作):
        • 首先,确保禁用所有 SCI 中断。
        • 接下来,清除所有 SCI 中断的中断状态(RXFF、TXFF、FE、OE、PE、RXERR、BRKDT、TXRDY),方法是清除然后设置 SCI 的 CTL1.SWRESET 位,然后设置 SCI 的 FFTX.TXFFINTCLR 和 FFRX.RXFFINTCLR 位。
        • 接下来,通过设置 SCI 的 FFRX.RXFFOVRCLR 位来清除溢出状态位。
        • 接下来,通过清除然后设置 FFTX.TXFIFORESET 来重置 RX 和 TX FIFO。
        • 接下来,通过清除然后设置 FFTX.SCIRST 位来重置器件的 TX 和 RX 通道。
        • 接下来,为您的系统实际配置所有 SCI 设置,例如波特率(SCIHBAUD + SCILBAUD 寄存器)、奇偶校验 + 数据长度 + 停止位(SCICCR 寄存器)。
        • 接下来,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 来启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。
        • 接下来,如果使用 FIFO,则设置相应的 FIFO 中断级别,方法是在 FFTX.TXFFIL 和 FFRX.RXFFIL 字段中设置这些级别。必须选择 FIFO 级别,以便在 FIFO 溢出之前为中断提供足够的时间来处理数据请求。对于较长的 SCI ISR,应确保足够早地发出中断,或者将处理移出 ISR,并且仅在 SCI ISR 中执行数据移动(建议)。
        • 最后,如果使用 FIFO,则通过设置 FFTX.SCIRST(如果未设置,但可以安全地重新设置)、FFTX.SCIFFENA、FFTX.TXFIFORESET 和 FFRX.RSFIFORESET 位来启用 FIFO。
        • 最后,通过设置 CTL1.TXENA、CTLA.RXENA 和 CTL1.SWRESET 位重新启用该模块。这还会对 SCI 模块执行软件复位,以使其为运行做好准备。

    2.4 代码问题症状和原因

    • 某些数据丢失(其余数据看起来是正确的)
    • 原因 1:数据或中断溢出
      • 如果缓冲区(或 FIFO,如果使用)满后 SCI 中断未被处理,则进入的任何额外数据都会丢失。这会导致数据丢失。解决方案是确保在下一组数据进入之前有足够的时间为缓冲区或 FIFO 提供服务。同样的解决方案适用于 SCI 轮询,其中不使用中断,因为在额外的数据进入之前仍然必须清空已满的缓冲区或 FIFO,以防止数据丢失。
    • 原因 2:中断无法获得服务
      • 当优先级较高的中断频繁发生(或允许嵌套在 SCI ISR 内)时,这些中断可能会阻止 SCI 模块接收所有数据。这些中断具有更高的优先级,并且始终在 SCI 模块有机会启动之前得到处理,从而基本上使 SCI 中断“无法获得服务”。
        • 例如,如果 ADC 中断持续触发并中断 SCI ISR,SCI ISR 可能永远不会(或缓慢地)到达其移动数据的部分。如果缓冲区或 FIFO 在 SCI 开始移动数据之前填满,则可能会导致数据丢失以及缓冲区或 FIFO 溢出。这需要 ISR 之间进行谨慎的交互,以便 ADC ISR(例如)和 SCI ISR 都不会缺少处理时间。
      • 其他非嵌套中断也可能需要很长的时间才能完成,从而使 SCI 缓冲区/FIFO 填满并导致其他数据丢失。这种情况很少见,因为 SCI 发送速度通常比处理速度慢很多。但在其他 ISR 中有一些计算可能需要很长时间,因此在遇到这些 ISR 时也必须十分小心。