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 GPIO 常见问题解答

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/942389/faq-c2000-gpio-faq

这篇文章解决了有关 F28x 器件上 GPIO 的常见问题。  一些信息可能会随着时间的推移而发生变化。  请始终参阅特定器件的最新技术参考手册和数据表。  

问:即使 MUX 配置为使用外设、我能否读取引脚(DAT 寄存器)的状态?

  • 281x:否 在该器件上、GPIODAT 寄存器反映了 GPIODAT 输出锁存器的状态。
  • 在其他设备上:是。 读取 GPIODAT 寄存器实际上反映了引脚上的值。

问:背靠背 DAT 寄存器写入不能按预期工作

  • 应用手册《使用 C/C++对 TMS320x28xx 外设进行编程》(SPRAA85)中也对此进行了介绍。
  • 请考虑以下示例。 运行该代码时、绿色 LED (A17)会按预期切换、但红色 LED (A16)会永久熄灭。 设置断点并单步执行代码即可正常工作。
for (;;)
{
/*使 LED 呈绿色*/
GpioDataRegs.GPADD.bit.GPIO16 = 1;//RED_LED_OFF;
GpioDataRegs.GPADD.bit.GPIO17 = 0;//green_LED_ON;
delay_loop();
/*使 LED 变为红色*/
GpioDataRegs.GPADD.bit.GPIO16 = 0;//RED_LED_ON;
GpioDataRegs.GPADD.bit.GPIO17 = 1;//green_LED_OFF;
delay_loop();
} 

上述代码将对 DAT 寄存器执行读-修改-写操作。 DAT 寄存器反映引脚本身的状态(281x 器件除外)。 但是、写入 DAT 寄存器和在引脚上看到结果值、然后反射回 DAT 之间会有一些延迟。 在这种情况下、"green_LED_ON"会将 GPIO16读为低电平并将该值写回。 因此、红色 LED 永远不会改变状态。

一种解决方案是在此示例中使用清除/设置寄存器。 另一种方法是在读取-修改-写入指令之间放置 NOP 或其他指令。

注意: 在281x 上、DAT 寄存器反映的是输出锁存、而不是引脚的状态。 在这种情况下、上述代码将起作用。

问:GPIO 的切换速度似乎比它应该慢-第1部分

GpioDataRegs.GPACLEAR.bit.GPIO18 = 1;
GpioDataRegs.GPASET.BIO18 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO18 = 1;
GpioDataRegs.GPASET.BIO18 = 1;GpioDataRegs.GPO18
= 1;GpioDataReg.GPIO18 = 1 

尝试尽快切换 GPIO18。 所示的位方法执行读-修改-写操作。 读取部分为等待状态、由于外设帧具有"写后读流水线保护"、因此在上一次写入完成之前不会发生下一次读取。 使用.all 写入整个寄存器将消除等待状态的读取和流水线保护的影响。 应用手册《使用 C/C++对 TMS320x28xx 外设进行编程》(SPRAA85)中也对此进行了介绍

问:GPIO 的切换速度似乎比它应该慢-第2部分

for (;;)
{
GpioDataRegs.GPADAT.bit.GPIO18=1;
GpioDataRegs.GPADAT.bit.GPIO18 = 0; 

上述代码具有与之前讨论的问题类似的问题。 此方法使用读-修改-写操作。 由于读取部分是等待状态、并且由于外设帧具有"写后读保护"、因此在前一个读取完成之前不会发生下一个读取。 另一个问题是 for 循环将引入一个需要4个周期的分支。 因此、即使将此代码更改为使用 GPBTOGGLE 寄存器、您也会看到来自分支的开销。

问:如何在 C 语言中尽快切换 GPIO 引脚?

最快的方法是对切换寄存器执行背靠背写入:
如果在 for ()循环中完成此操作、则循环将引入一个分支指令、该指令在每个循环的开始处花费4个周期。 在浮点器件上、您可以使用重复块指令(RPTB)执行类似的操作、而不是使用分支来消除分支开销。 此外、对该外设帧的背靠背写入将引入等待状态。 这是一次切换将需要一个周期、但背靠背切换将在写入之间增加一个额外的周期。

for (;;)
{
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
GpioDataRegs.GPBTOGGLE.ALL = 0x0002;
重复...等
} 

问:此 C 指令切换 GPIO 引脚需要多长时间?

请看一下 Code Composer Studio 窗口中生成的反汇编代码。 通常、将有一条指令用于设置数据页指针和一条指令用于写入 GPBTOGGLE 寄存器。 这些指令各自采用一个 SYSCLKOUT 周期。

如果对 GPBTOGGLE 寄存器进行了另一次写入、则不必为第二次写入设置数据页。 但是、连续(背靠背)对 GPIO 寄存器的写入会遇到1周期管道命中(1周期延迟)。

注意:表中的器件专用数据手册中记录了等待状态、该表描述了器件存储器映射区域中各个空间的等待状态。 这可能不适用于您正在使用的器件。  请务必查看文档。

问:2833x/2823x:GPIOB MUX1寄存器在复位后被正确设置为0x00000000、但在加载代码时被设置为0XFFFFFFC0?

GEL 文件 TI 电源可能正在为文件加载时的 XINTF 功能设置 GPIO。 这允许 Code Composer 将调试代码直接加载到 XINTF 中。 查看'on file PRELOAD '函数并删除使能 XINTF 调用以停止此行为。

问:可在复位时启用或禁用 ePWM 输出的引脚上的上拉电阻器吗?

  • 在 F281x 器件上、如果 GPIO 引脚具有上拉电阻、则在复位时启用、并且无法在软件中禁用它们。
  • 在 F280x、F2802x、F2803x、F2805x、F2806x、 F2823x、F2833x 和 C2834x 器件、最好参考文档(见下面)。 但是、存在一些一般准则:
    • 如果 GPIO 引脚通常用作 ePWM (例如 GPIO-00)、则在复位时禁用上拉电阻。 然后可通过软件启用。
    • 如果 GPIO 引脚不常用作 ePWM、则在复位时启用上拉电阻。 然后可通过软件禁用它
  • 在较新的器件上、例如 F2807x 和 F2837x 器件上、所有引脚在复位时都将其内部上拉电阻器禁用。 它们可在以后通过软件启用。

每个 GPIO 上拉禁用(GPxPUD)寄存器的文档将提供每个位的状态、因此每个上拉电阻器在复位时的状态。 这些信息可在特定器件的系统控制和中断指南(或某些器件中的 TRM)的 GPIO 部分中找到。

问:当输入专用于外设时、是否可以使用 GPIO 的鉴定功能?

  • 无论 GPIO 多路复用器的设置如何、鉴定电路都处于激活状态。 因此、是的、您可以使用外设功能的限定条件。

问:我正在寻找鉴定逻辑的时序信息。

  • 请参阅器件的数据手册。 这将与其他 GPIO 时序参数一同列出。

 

C2000培训视频:https://training.ti.com/search-catalog/field_language/ZH-CN?keywords=C2000&start%5Bdate%5D=&end%5Bdate%5D=

C2000培训小程序码