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.

[参考译文] TM4C129ENCPDT:未触发 UART 发送中断

Guru**** 2041660 points
Other Parts Discussed in Thread: EK-TM4C129EXL, TM4C129ENCPDT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/603001/tm4c129encpdt-uart-transmit-interrupt-not-being-triggered

器件型号:TM4C129ENCPDT
主题中讨论的其他器件:EK-TM4C129EXL

我们在 EK-TM4C129EXL 上运行 TM4C129ENCPDT、并尝试在电路板和运行 PuTTY 的 PC 之间发送和接收字符。

我们正在使用电路板的 ICDI 虚拟 UART、跳线设置正确、并且位于 C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\ek-tm4c129exl\UART_echo 的 TivaWare 示例程序工作正常。 该程序不使用中断。 它只是在循环中运行、在接收器可用时从接收器读取字符并将其写回发送器。

现在、我们要使用我们基于中断的代码。 接收中断工作正常。 发送中断永远不会被触发。 因此、字符会被正确接收和处理、但字符不会被传输。

如果我们将发送代码从中断处理程序中取出、并将其粘贴到程序的主循环中、则该程序将按预期工作、处理接收的中断处理、但轮询发送的处理。 我们还需要基于中断进行传输。 不仅如此、由于我们不是始终进行传输、而是突发传输、因此我们需要在任何内容被放入软件缓冲区后立即启用传输中断、并且在软件缓冲区变为空时需要将其禁用。 但现在我们只是告诉它始终被启用、只是为了使它正常工作。

我们已经尝试过具有各种水线位的 UARTFIFOEnable()和 UARTFIFOLevelSet(),但这没有什么不同。 我们已经尝试过 UARTFIFODisable(),但这也不起作用。

这是初始化代码:


void SetupUart0 (void)

  global.SysClockFreqHz = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、SYSTEM_CLOCK_FREQ_Hz);

  SysCtlPeripheralEnable (GPIO_Porta_base);

  SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
  while (SysCtlPeripheralReady (SYSCTL_Periph_UART0)!= true)
  {
  }

  GPIOPinConfigure (GPIO_PA0_U0RX);
  GPIOPinConfigure (GPIO_PA1_U0TX);
  GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

  UARTConfigSetExpClk (UART0_BASE、Global. SysClockFreqHz、115200、(UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | UART_CONFIG_WLEN_8));

  //将 UART 设置为在 Tx FIFO 几乎为空或接收到任何字符时中断
  //UARTFIFOEnable (UART0_BASE);
  //UARTFIFOLevelSet (UART0_BASE、UART_FIFO_TX1_8、UART_FIFO_RX1_8);

  IntEnable (INT_UART0);
  UARTIntEnable (UART0_BASE、UART_INT_RX | UART_INT_RT | UART_INT_TX);

注释代码不能通过 FIFO 尝试不同的操作。


这是中断处理程序:


空 Uart0InterruptHandler (空)

  uint32_t InterruptFlags;

  InterruptFlags = UARTIntStatus (UART0_BASE、false);
  UARTIntClear (UART0_BASE、InterruptFlags);

  IF (InterruptFlags & UART_INT_TX)
  {
    // Tx FIFO 中的空间
     while (UARTSpaceAvail (UART0_BASE))
     {
       UARTCharPutNonBlocking (UART0_BASE、BufGet (&Tx));
     }
  }

  IF (InterruptFlags &(UART_INT_RX | UART_INT_RT))
  {
    // Rx FIFO 中的数据
    while (UARTCharsAvail (UART0_BASE))
    {
      BufPut (&Rx、UARTCharGetNonBlocking (UART0_BASE));
    }
  }


正如我说过的、从中断处理程序中删除带有 UARTSpaceAvail ()和 UARTCharPutNonBlocking ()的 while 循环并将其放入主循环中会使代码正常工作、但随后会轮询发送、而不是基于中断。

初始化后、寄存器包含以下内容:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果很重要、我们将使用 CCSv7 7.1.0.00016版、工具链是 gcc-arm-none-eabi-4_9-2015q3和 ti-cgt-arm_16.9.3.LTS。 程序在两个工具链下的行为相同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在这里没有看到任何东西来启动传输。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是如何实现的? 我不熟悉 TM4C。

    我熟悉的平台采用这种方式工作:一旦启用发送中断、发送中断就会生效、因为 FIFO 为空或低于水印。 发送中断处理程序将尽可能多的字节放入 FIFO 中。 如果 FIFO 满、发送中断处理程序退出并等待中断再次生效。 如果发送中断处理程序耗尽了放入 FIFO 的字节、它将禁用发送中断。 之后、当软件调用"发送"函数来发送更多数据时、该发送函数会启用发送中断、并再次开始处理。

    TM4C 中的工作方式似乎有所不同。 我们必须采取什么额外步骤才能让它开始传输?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此处有两种 UART (源自 IIRC、Motorola 和 National Semiconductor)。 如您所述、使用电平敏感中断的中断(如果可能进行传输、则中断始终处于活动状态、必须持续启用/禁用中断)和使用边沿触发中断的中断(中断仅在有发送空间时触发一次、发送过程必须启动传输)。 后一类实际上更多。 电平触发 UART 中断类型仅在 Motorola 很常见。

    处理边沿触发中断的方法是在必要时开始传输。 通常称为"注油泵"、原因显而易见。

    那么、在发送中断中

    •  如果队列为空、则发出标志
    •  否则从队列中填充 FIFO

    例程中

    • 将字符串放入队列中
    • 如果队列已满或字符串已完全放入队列检查标志中
    • 如果 FLAG 置位、则清除标志并将第一个字节放置在 UART FIFO 中

    Joseph Campbell 提供了一个旧的 DOS 参考"C 编程人员串行通信指南"、其中对此进行了很好的介绍。 不再适合 PC、但仍然是一个很好的嵌入式参考。

    Robert

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

    您好!
    您需要以某种方式启动 UART 以生成中断。 您需要先通过所需的中断 FIFO 级别选择对 FIFO 进行一些写入(如果您使用 FIFO 功能)。 例如、您可以配置1/8 FIFO 电平。 这意味着您需要使用两个写入 FIFO 的数据快速启动主系统中的 UART。 一旦两个数据被写入 FIFO、UART 将产生中断。 在 ISR 中、您可以将后续数据写入 FIFO。 如果你不这样做,你就会遇到鸡和蛋的情况。 FIFO 中没有数据、因此没有中断。

     实验课程 Lab12中还有一个基于 UART 中断的中断。

     另请确保:

     IntMasterEnable();//启用处理器中断

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

    [报价用户="Charles Tsaaa">例如,您可以配置1/8 FIFO 级别。 这意味着您需要使用两个写入 FIFO 的数据快速启动主系统中的 UART。 一旦两个数据被写入 FIFO、UART 将生成中断[/引用]

    一个人应该足够了,不应该是查尔斯? 至少在我使用过的每个 UART 上、如果不进行审阅、我很确定我的当前 TM4C 代码也是这样做的。 UART 模块不仅在 FIFO 深度低于 FIFO 深度时产生中断、而且在 FIFO 为空时产生中断。

    Robert

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

    您好、Robert、

     谢谢。 根据数据表、 在 FIFO 模式下、中断是在数据的可编程触发电平被写入后产生的。 如果 FIFO 被禁用、并且发送器中没有数据、那么也会产生中断。 下面是数据表的摘录。

    发生以下事件之一时、发送中断将改变状态:

    ■如果 FIFO 被使能、并且发送 FIFO 在经过编程的触发条件下前进

    TXRIS 位被置位。 因此、发送中断基于电平转换

    FIFO 必须写入超过设定的触发深度、否则不再发送中断

    将会生成。 发送中断通过向发送 FIFO 中写入数据来清除、直到发送 FIFO 中写入数据为止

    大于触发电平、或通过向 TXIC 位写1清除中断来清除中断。

    ■如果 FIFO 被禁用(具有一个位置的深度)、并且中没有数据存在

    发送器单个位置时、TXRIS 位被置位。 通过对执行一次写操作可以清除该位

    发送 FIFO、或通过向 TXIC 位写1清除中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗯、这是坏的。 很高兴您提请我注意。 使用 EOT 触发器时有一些变通方法。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您提供非常明确的答案。 了解这两种类型(边沿与电平触发的发送中断)确实有助于我了解这里发生的情况。 在阅读您的解释之后、我注意到 TivaWare 附带了 uartstdio 模块(在 TivaWare_C_Series-2.1.4.178\utils 下)、并确保它包含一个函数 UARTPrimeTransmit()、该函数将尽可能多的字节填充到发送 FIFO 中。

    不幸的是,当 FIFO 被使用时(UARTFIFOEnable()被调用),就像查尔斯·蔡指出的那样,一个字节似乎不足以让事情发生。 我用1/8 FIFO 电平对其进行了设置、但它不起作用。 只有在我至少放置2个字节后、它才起作用、如果您使用更高的 FIFO 级别、则需要放置更多字节来启动 UART。 关闭 FIFO (UARTFIFODisable())后,一个字符就足够了,因为一个字符就是您拥有的传输缓冲区。

    我让这起作用、但我说"不幸的"、因为这会使代码变得很丑!

    我们移植了我们过去开发的库。 它在多个8位、16位和32位器件上运行良好。 它的工作方式是、所有发送操作最终归结为单个函数、该函数每次将一个字符排入我们的软件队列。 通过这种方法,我们可以将无锁 ISR 安全队列代码封装在一个位置,然后将所有需要发送数据的其他代码封装到一个位置,无论是 printf()还是其他任何代码,只需为每个字符调用此函数,而无需担心。 但这意味着我们的 UART 库不知道何时有一个完整的"字符串"排队。 它只知道有一个字符要发送、不知道是否有更多字符要发送。 对于这些系统的电平触发 UART、字节排队功能只需确保启用发送中断、并且如果队列中没有更多字节、中断处理程序将禁用该中断。 现在、在这种边沿触发的情况下、仅因为需要多个字节来填充泵、这意味着我们无法在字符排队函数中进行填充、因为它不知道是否有足够的字符。 如果您发送简短的消息、则在需要发送更多字节之前不会完全发送这些消息、这可能会晚很多。 因此、这反过来意味着我们需要检查主循环中的 FIFO 填充、不断轮询标志并在必要时填充 FIFO。 因此、我们的实现最终会进行轮询和基于中断、在两个位置重复功能。 由于主代码最终完成的工作只有一半、因此我根本看不到使用发送中断有什么好处。 嗯、当你发送非常长的字符串或整个文件时、有一个优势。 在我提到的 uartstdio 模块中、除了您必须对 FIFO 执行的所有其他管理之外、他们仍然会打开和关闭 TX 中断、因此我也继续这么做了。 它现在似乎工作正常。

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

    超越"破裂"----这是目前提出的最具酷刑的著作之一。
    每个"弯曲"后面都有多个" gotchas "-只是等待我们(轻微)的失误!

    虽然有人提到(就在这里/现在)有一个"基于中断的 UART 示例、其中包含在"车间实验室12 "中-是否可以拒绝"在这里为一个合格的、更具(即某种程度上)的可公布/可确定的代码示例"?

    这里不是这些(现在)的错-但这应该已经达到(某人的)"待办事项"列表。   (避免并不总是"最佳"选项。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、这个外设似乎是为少数情况而设计的、正如12月12日指出的、它不是为最常见的用途而设计的。 至少接收超时的古怪行为很容易处理、即使它几乎能吸引所有人的警惕、您也可以假装它很有用。

    两者都打破了"最低惊喜原则"

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

    [引用 user="CB1_MOBILE "]是否可以拒绝"在此处搜索合格的、更多(即某种程度上)已公布/可确定的代码示例"? [/报价]

    事实上,这样一个例子应该能够说明如何处理以下情况

    • 4字节 FIFO 阈值
    • 两个字节被写入 FIFO
    • 一些未知的字符数、之后3个字节将被写入 FIFO
    • 问题:发送中断是否会触发? 我们如何知道?

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哦、什么是"接收超时模式"?! 如何避免这种情况呢?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    至少接收超时模式很容易处理。

    与我使用过的每一个 UART 不同、TI 将接收超时分离为不同于接收中断的单独中断。 您只需将其视为接收中断即可。

    IE
    
    
    开关(状态)
    
    案例 Receive_timeout:
    案例接收:
    (笑声)
    中断;
    

    如此简单、出乎意料。

    我没有看到这种分离的有用应用,尽管有人试图提出正当理由。

    Robert

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

    Robert Adsett 说:
    嗯、这是坏的。 很高兴您提请我注意。 使用 EOT 触发器时有一些变通方法。[/QUERT]

    实际上、解决此问题的唯一方法是将发送中断更改为在传输结束时触发。 可能会使通信量略有增加、但您不应错过发送中断、您仍然可以使用接收 FIFO。  到目前为止、我还没有看到任何其他保证工作的东西。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有趣。 我认为我在示例代码中看到了这一点、并以同样的方式实施了我的代码。 感谢你们把这点清理了:-)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果在中断结束时还有一个额外的中断、那么是否可以启用这两个中断并为它们提供与"接收模式"相同的处理方式?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm"]如果在中断结束时有一个额外的中断,那么是否可以启用这两个中断并为它们提供相同的处理方式,就像"接收模式"一样?

    不是我能看到的。 EOT 中断替代 FIFO 阈值中断。 如果它是额外的、它将解决大部分问题。 因为这是我唯一能看到的工作情况、但性能会有轻微下降。 在许多不太可能重要的应用中。

    可能会忽略中断吗?

    Robert

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

    在某种程度上,我们"囚犯"(似乎)是在管理庇护的(有些)吗?     这是否能够证明是最佳的?    

    是否敢问、"在这里、需要"UART 架构/管理"专家?"

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

    更重要的是、您是否已将 DMA 与 TM4C 上的 UART 结合使用? UART0上的代码仅用于诊断。 但我们已经准备好旋转具有多个 TM4C 的电路板、这些 TM4C 通过 UART 相互通信。 我现在不确定确切的数字、但我想他们会每秒交换1KB 数据、每秒100次、我希望以4MHz 的频率运行 UART。 如果它不能有效工作、那么我想整个设计都是开窗的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Robert、
    当 UARTCTL 寄存器的 EOT 位置位时、一旦 FIFO 完全为空且包括停止位在内的所有数据都已从移位寄存器中发出、就会产生发送中断。 为了产生 EOT 中断、您仍然需要首先向主程序中的 FIFO 写入一个数据。 我想说的是、如果没有先将一些数据写入 FIFO、就无法等待 EOT 中断发生。 但是、正确的做法是、这是另一种通过使用 EOT 而不是 FIFO 阈值来继续基于中断的重新传输的方法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12PM">更重要的是、您是否在 TM4C 上使用了 DMA 和 UART? [/报价]

    不、鉴于串行通信的性质、我从未见过这样一个有意义的案例(考虑如果一个字节被丢弃或被添加会发生什么情况)。

    [引用 user="12ve12pm">但我们已准备好旋转具有多个 TM4C 的电路板、该 TM4C 通过 UART 相互通信。 我不确定确切的数字、但我想他们会每秒交换1千字节的数据、每秒100次、我希望以4 MHz 的频率运行 UART。[/引述]

    什么类型的数据? 您确定可以获得4MHz 收发器吗?

    Robert

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

    [引用用户="Charles Tsaaaa">当 UARTCTL 寄存器的 EOT 位置位时、一旦 FIFO 完全为空且包括停止位在内的所有数据都已离开移位寄存器、就会产生发送中断。 [/报价]

    是的。 我曾经使用过的所有其他 FIFO 的 UART 都提供了一个在 FIFO 清空时发生的中断。 TI 不提供此类服务是例外。

    [引用用户="Charles Tsaa"]。 要生成 EOT 中断、您仍需要首先将一个数据写入主函数中的 FIFO。[/QUERP]

    当然、与所有其他边沿触发 UART 一样

    [引用 USER="Charles Tsaa"]但您是对的。这是另一种通过使用 EOT 而不是 FIFO 阈值来继续基于中断的重新传输的方法。[/引用]

    我可以说、这是唯一安全的方法。 至少没有提出其他安全方法。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    它们位于同一电路板上、布线相对较短、因此它们不会穿过收发器。 数据将是在多个处理器之间发送的命令、响应和其他状态信息。 必须有一种方法来检测错误、至少是 CRC32。 我现在所知道的是、它肯定需要大量测试、如果它在4MHz 下不可靠、那么我们必须降低它。 我认为它应该是可靠的、因为我们过去已经完成了更快的处理器间通信、尽管这是通过 SPI 和其他 MCU 实现的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我更想了解数据和命令的类型以及重复的数量。 该带宽超过饱和可能、但如果有足够的重复流量、则可能适合该带宽。 我还听说有人使用以太网来处理这种流量。

    不过、我想知道要使用的接口是否不是 FIFO、甚至可能是共享存储器。 这样就会获得很大的带宽、但您必须为 FIFO IC 付费。

    解释了为什么您不担心收发器、尽管我想检查开销。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们过去使用过 FIFO。 在一个项目上、我们尝试使用共享双核存储器。 它从未正常工作、但这是因为项目提前报废。 无论如何、双核存储器成本高昂、任何外部存储器都将大量 MCU 引脚用于所有地址、数据和控制引脚、因此会进一步增加成本。 TM4C129ENCPDT 数据表显示、您可以将 UART 启动至7.5MHz (或15MHz、用于"高速")、我们仅需几英寸... 如果我们不得不越过房间或更远的距离、我将直接使用以太网。 我希望我们不会将所有 CPU 带宽仅用于通信! 了解它的工作原理肯定会很有趣。 我故意想使用4MHz、因为这是最大值的一半(稍高一点)、而且我们在该速度(更快)下非常可靠地完成了 SPI。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm"]……数据表显示您可以将 UART 启动至7.5MHz[/quot]

    然而、如果不提及任何添加的"错误率"或(实际)操作条件、或数据有效载荷、此类索赔可能无法证明是完全令人信服的。

    曾担任过工程经理。 在一个"类似的、半巨人"的场合、有人指出、"乐观的发现"是在"远程设备(完美)"处于"拨入"状态(即精心设置的频率)时产生的、而这种情况不会与您的情况重叠。    此外、在现实世界中、一个 MCU 可以"快速运行"、另一个 MCU "缓慢"、那怎么办?   (此类频率误差是累加的)     

    和-由"PVT"(过程变化、电压、温度)和简单老化强制执行的偏差-必须预先考虑-和防护带。   所有这些都需要(更加)保守的方法-以及可靠的测试/验证。

    在4MHz 频率下、我们发现电路板布局非常重要-短距离、直接布线以及与其他潜在影响信号的良好"分离"-所有这些都"推动您取得成功"。   然而、"注意"应该靠近、 数据完整性应该高速。

    另请注意-此处(较小)的 MCU (4C123)通常在 TX 线路上需要"上拉 R"、这可能会影响最大速度...   (此类需求也可能会溢出到您的设备中...)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    @CB1_MOBILE、很高兴您提到了上拉电阻器。 我向设计人员介绍了这一点、结果我们的设计中有10k 至 VCC 的电流。 一个 MCU 的 TX 是另一个 MCU 的 RX、因此实际上两条线路都具有上拉电阻。 他说、他将每个上拉电阻器放置在最靠近它所进入的 RX 引脚的位置。

    现在、至少在我看来、UART 应该比 SPI 更可靠、因为 UART 对每个位进行16次采样、而 SPI (据我所知)只对每个位进行一次采样。 UART 还为每个字节提供组帧、因此有更多机会检测错误。 但这只是我。 可能 SPI 包含不同类型的魔术烟雾。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm"] UART 对每个位进行16次采样

    我是否可以不同意-我相信(只是) 3个这样的"投票样本"是"选择的样本"。    (这个议题是最近提出的(这里)--我记得"3"数字----这是(最后)商定的。)

    e2e.ti.com/.../588322

    您"抓住"上拉-但您的"对速度的需求"-减去精心选择的"注意事项"-似乎没有什么顾虑-警报...

    至于 UART (异步)与 SPI (同步)、我会每次投票选择时钟数据(几乎)。    回忆一下我之前的帖子-您的互联 MCU 之一可能"快速"运行-而另一个则"缓慢!"    这如何提高可靠性?    容忍"额外"信号线(即数据时钟)这一事实必须用"SPI"表示某种优势、即"信号可靠性/稳健性!"    

    您可以通过调查"附件 IC"的出现情况(为每种串行格式提供服务)、深入了解"SPI 与 UART 的价值"。    SPI -压倒性优势-获胜!    (" 宰杀规则"经常被称为...)

    我应该注意到、FIRM/I 是 UART 的"风扇"、尤其是当通信流过(超过)电路板时、并且部署了适当的收发器/电平转换器(甚至无线电模块)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    SPI 的优势不是稳健性。 如果有任何问题、它的稳健性就会降低。 用于从器件的 SPI 的优势是简单易用的时钟移位寄存器由芯片选择控制。 从器件需要一个 UART 接口来提供一个时钟、该时钟对于微型器件是自然的、但对于许多从器件来说则不是如此。

    与 UART 相比、芯片选择的简单性使 SPI 的微处理器实现更加复杂、这一点有点令人困惑。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、通常是3或1个投票时间。 16x 来自用于查找这3个中心采样时间点的16x 波特率时钟。

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

    [引用 user="12ve12pm"]我看不到使用发送中断的任何好处。

    只需在这次漫长的对话中添加我的两分...

    我们实施的方式、并且我理解、缓冲器传输控制器必须注意:

    -是否仍有字节要发送(从缓冲区到 FIFO)

    如果有空间将字节放入 FIFO 中

    因此、我发现不需要 EOT 中断!

    假设您有3个字节要传输、FIFO 为空。 传输控制器会像 while 那样执行某项操作(FIFO_FASH_ING_INOPEN_BUSCK_RED_TO_BE_BE_SENT);

    这三个字节将立即发送、故事结束。 这适用于1个字节、16个字节、等等。 由于缓冲器已完全传输、环路将退出、因此在应用程序端不必再担心、它可以假设"所有数据都已传输"。 您真的需要知道、这里最后一个字节实际上离开了硬件吗? 正确的传输需要其他方法、确认协议等。

    现在、假设您有25个字节。 前16个字节将立即发送、您可以返回到 MCU 需要执行的任何操作-您将在这些字节的"部分"离开 FIFO 后获得中断(例如、其中一半字节在默认配置下)。 当您获得该中断时、您有一些时间为其提供服务、只需使用相同的逻辑再次调用该"控制器"即可。 当您开始发送剩余的9个字节时、很可能会有一个额外的字节离开硬件、因此所有9个字节都将在第二个调用中消失。 否则、没有问题-最后一个字节将在控制器的第三次调用中简单地发送。

    微调中断的 FIFO 水平。 如果在离开 FIFO 2个字节后立即设置中断、您将经常调用控制器。 如果您将其设置为在剩余14个字节后中断、您将在下一个控制器调用中获得"大量 FIFO 空间"的好处-但如果您的代码正忙于执行其他操作、 您可能会浪费传输时间、因为最后2个字节在您能够发送更多字节之前已发送。

    使用流程图可以更容易地解释这一点,但我希望文本是有意义的。 我们发现、此类策略提供了非常可靠的 UART 传输、不会与接收端发生混乱、也不需要太多的处理。

    布鲁诺

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

    [引用用户="Bruno Saraiva"]

    我们实施的方式、并且我理解、缓冲器传输控制器必须注意:

    -是否仍有字节要发送(从缓冲区到 FIFO)

    [/报价]

    这是我认为的部分、总的来说很难做到。 实际上、我通常唯一能看到的方法是添加一个计时器、以减少字符留在 FIFO 中的时间。 依靠概率只会使您很难跟踪错误。

    [引用用户="Bruno Saraiva"-如果有空间将字节放入 FIFO 中

    此器件很普通

    [引用 user="Bruno Saraiva">假设您有3个字节要传输、FIFO 为空。 [/报价]

    第一个问题、您如何知道 FIFO 为空?

    [引用 user="Bruno Saraiva"]三个字节将立即发送,结束故事

    只是故事的开始。 第二个问题何时/将触发中断? 如果您向队列中添加更多字符、您是否需要将它们发送到 FIFO、或者是否可以依赖中断?

    [引用用户="Bruno Saraiva"]。 您真的需要知道、这里最后一个字节实际上离开了硬件吗? 正确的传输需要其他方法、确认协议等。

    您还如何知道何时向 FIFO 中添加更多字节?

    [引用 user="Bruno Saraiva">现在、假设您有25个字节。 前16个字节将立即发送、您可以返回到 MCU 需要执行的任何操作-您将在这些字节的"部分"离开 FIFO 后获得中断(例如、其中一半字节在默认配置下

    是的

    [引用 USER="Bruno Saraiva"]当您得到该中断时,您有一些时间来为它提供服务,只需再次使用相同的逻辑调用该“控制器”即可。 当您开始发送剩余的9个字节时、很可能会有一个额外的字节离开硬件、因此所有9个字节都将在第二个调用中消失。

    一般而言、依赖概率并不会导致可靠的软件。

    [引用 USER="Bruno Saraiva"]如果不是,没有问题-最后一个字节将在控制器的第三次调用中发送。

    好的、如果您在最后一个字节离开队列后立即排队等待另外3个字节、会发生什么情况?

    如果在 FIFO 中断触发后立即排队3个字节、会发生什么情况?

    我想我看到一两种方法可以解决这个问题、但需要注意防止比赛条件。

    Robert

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

    [引用 user="Robert Adsett"](-是否仍有要传输的字节(从缓冲区到 FIFO)。 我认为这一部分一般很难做到。[/引述]

    不客气。 您误解了。 控制器需要知道缓冲区中是否有挂起的字节、这些字节需要放置在 FIFO 中。 当它们处于 FIFO 中时、任务就完成了。 那么、这只是一个缓冲指针问题。

    [引用 user="Robert Adsett"]第一个问题:如何知道 FIFO 为空?

    就该示例而言、从定义上讲、它是空的。 为了知道 FIFO 是空的、我们有这个奇怪的东西、我甚至不想重新理解:

    (!(HWREG (Serial_UART[uarted][serial_base]+UART_O_FR)和 UART_FR_TXFF))

    [引用 user="Robert Adsett"]您还如何知道何时向 FIFO 中添加更多字节?[/quot]

    在收到 TX 中断后、您可以立即向 FIFO 添加更多字节! 同样、您不需要知道是否所有字节都通过了线缆。

    [引用 user="Robert Adsett"]好的,如果您在最后一个字节离开队列后立即再排队3个字节,会发生什么情况?[/quot]

    您永远不会排队3个字节、8个字节或任何字节。 当 FIFO 中有空间时、您会逐个排队。 您可以控制缓冲区的指针:一个指向已发送到 FIFO 的内容、另一个指向需要发送的最后一个字节。

    [引用 user="Robert Adsett"]依赖概率通常不会导致强大的软件。

    这是一个平均评价! 你在阅读其余的之前写的!!! 反对!!!!

    希望这些附加的注释能清除一些问题!

    布鲁诺

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

    [引用用户="Bruno Saraiva"]

    就该示例而言、从定义上讲、它是空的。 为了知道 FIFO 是空的、我们有这个奇怪的东西、我甚至不想重新理解:

    (!(HWREG (Serial_UART[uarted][serial_base]+UART_O_FR)和 UART_FR_TXFF))

    [/报价]

    是否没有一个能做到这一点的整洁 TivaWare 函数?

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

    [引用 user="Bruno Saraiva">就本示例而言,它按定义为空。 [/报价]

    这是我的观点。 您必须同时考虑空和非空条件。 您只考虑了空条件。

    [引用 user="Bruno Saraiva"]要知道 FIFO 是空的,我们有这个奇怪的东西,我甚至不想重新理解:

    这决定了是否会发生中断、因此必须绝对考虑该条件及其影响。

    [引用用户="Bruno Saraiva"]

    Robert Adsett
    一般而言、依赖概率并不会导致可靠的软件。

    [/报价]

    我是这样做的。

    [引用用户="Bruno Saraiva"]

    Robert Adsett
    好的、如果您在最后一个字节离开队列后立即排队等待另外3个字节、会发生什么情况?

    [/报价]

    这不能回答问题。 它会在不寻址的情况下将其侧翻。

    我提到过、我认为我看到了一个清晰的方法、我认为我确实做到了。 它确实需要一些工作来避免竞争、与传统 UART FIFO 相比、这会显著增加延迟

    首先从传统 UART 开始

    应用程序代码

    TransmitByte (char byte)
    {
    
    
    如果 PrimePumpFlag set 为、则向队列添加字节{
    禁用中断
    将字节放入 UART FIFO
    清除 PrimePumpFlag
    启用中断
    }
    } 

    在某些情况下、您可以在启动时放弃中断保护。 不过、如果您希望防止将来发生更改、那么即使现在适用这种情况、中断保护也应该仍然存在。 请注意、此处的操作顺序很重要。

    中断代码

    UARTTransmit()
    {
    如果! queue_empty{
    将队列复制到 FIFO,直至队列为空或 FIFO 已满
    }
    否则{
    设置 PrimePumpFlag
    }
    } 

    这将不适用于 TI UART、因为在未填充 UART FIFO 超过 FIFO 阈值的情况下、将不会发生中断、并且将永远不会设置 PrimePumpFlag、因此传输永远不会重新开始。

    修复此问题的简单安全方法是将发送中断转换为 EOT 中断、并使一些话务员带宽损失。 不过,我认为我有一个更好的方法。

    从中断代码开始。 它实际上简化了、因为无法设置启动标志。

    UARTTransmit()
    {
    如果! queue_empty{
    将队列复制到 FIFO,直至队列为空或 FIFO 已满
    }
    } 

    应用代码现在需要额外的保护、至少可以说更复杂

    TransmitByte (char byte)
    {
    
    如果
    队列为空且!FIFO 已满,则禁用中断{
    将字节放入 UART FIFO
    }
    否则{
    将字节添加到队列
    }
    启用中断
    } 

    扩大保护期是防止种族状况的必要条件。  我认为我没有留下任何比赛条件、但需要回顾一下、我只是对它进行了初步检查。

    它的两个副作用

    1. 延迟增加
    2. 增加发送中断的数量、无需执行任何操作。

    关于中断保护的注释、只要发送的优先级永远不会高于发送中断、那么禁用只需要阻止发送中断。 如果不是、禁用必须更具包容性、并且中断代码中也需要额外的块。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我实际上并不这么认为!!!
    如果我回忆一下,这里的 xmas-tree 是从 UartCharPut()函数中复制的。 由于这个是阻塞式的、它必须检查 FIFO 空间、这正是 TivaWare 作者所使用的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Bruno Saraiva"]由于这个中断,它必须检查 FIFO 空间

    只需进行 FIFO 完全检查。 请参阅 UARTSpaceAvail。 应归结为简单的标志检查。

    Robert

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

    [引用 USER="CB1_MOBILE "]

    您"抓住"上拉-但您的"对速度的需求"-减去精心选择的"注意事项"-似乎没有什么顾虑-警报...

    至于 UART (异步)与 SPI (同步)、我会每次投票选择时钟数据(几乎)。    回忆一下我之前的帖子-您的互联 MCU 之一可能"快速"运行-而另一个则"缓慢!"    这如何提高可靠性?    容忍"额外"信号线(即数据时钟)这一事实必须用"SPI"表示某种优势、即"信号可靠性/稳健性!"    

    [/报价]

    现在我很紧张!

    关于同步通信优势的观点。 (顺便提一下、您对 USART 有什么看法? 它可以为您提供组帧和时钟! TM4C 太糟糕了。)

    我必须进一步研究、并运行一些测试...

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

    [引用 user="12ve12PM"]意外地、您对 USART 有何看法? 可为您提供组帧和时钟![/引述]

    真的、有一个指针? 我看到的所有 USART 都不在同步模式中提供任何组帧(我认为这有点像一个催产的组帧)。 它们只是一种提供类似 SPI 接口的方法。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    出于某种原因、我的眼睛没有找到 UARTSpaceAvail。

    无论采用哪种方式、内容都是相同的:

    UARTSpaceAvail:
    return ((HWREG (ui32Base + UART_O_FR)和 UART_FR_TXFF)? false:true);

    上述代码:
    (!(HWREG (ui32Base +UART_O_FR)和 UART_FR_TXFF))
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这不是您之前提到的 FIFO 空函数;)

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、是的! 我刚刚替换了 ui32Base 参数以获得更清晰的读数、因为其中一个参数是我的代码的特定变量。 除此之外、如果 Tx FIFO 有可用空间、则读取的寄存器掩码完全相同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    布鲁诺,我的最后一个回答有点偏。 我想你写错了。

    但是 、FIFOEMpty 和 SpaceAvailable 有很大不同。 实际上、您可以使"可用空间"与 SpaceUSED 更接近(而不是 FIFOEMpty)。 考虑16字节 FIFO

    • FIFO 中可用的空间为1到16字节
    • FIFO 空16字节 FIFO 可用
    • FIFO 中使用的0到15字节的空间可用
    • FIFO 满 0字节可用

    逻辑反向关系

    • 可用空间=!FIFO 已满
    • 已用空间=!FIFO 为空

    FIFO 满标志是现成可用的标志、也是您所检查的标志。

    我怀疑可以通过检查发送保持寄存器是否为空来近似计算 FIFO 为空、但我尚未验证标志是否可用。

    Robert