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.

[参考译文] CC3220S-LAUNCHXL:在 I2C 和 GPIO 模式之间切换

Guru**** 2540720 points
Other Parts Discussed in Thread: CC3220S, CC3220SF

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/829053/cc3220s-launchxl-changing-between-i2c-and-gpio-mode

器件型号:CC3220S-LAUNCHXL
主题中讨论的其他器件:CC3220SCC3220SF

我正在尝试弄清楚如何在 CC3220S 上的相同引脚上更改 I2C 和 GPIO 模式。  目前、我可以使用在 CC3220S_LAUNCHXL.h 和 CC3220S_LAUNCHXL.c 文件中配置的 I2C。  但是、我需要实现一个阻塞总线例程、该例程将引脚切换到 GPIO、以便我可以强制 i2c 时钟引脚上的时钟脉冲释放总线。  我该怎么做?  我可以在微控制器上轻松地执行此操作、但我不确定在使用 TI-RTOS 时如何更改引脚模式。

背景: 我遇到了噪声或其他因素导致 CC3220 "锁定"的情况。  我发现 SCL 和 SDA 一直处于低电平。  如果我拔下从器件、两条线都将悬空为高电平。  我猜从器件会将 SDA 保持在低电平、CC3220会以时钟低电平锁定、因为从器件无法将时钟驱动为低电平。

谢谢

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

    您好!

    您对 I2C 总线问题的理解是正确的。 我有一个相同的问题。 问题的修复完全符合您的建议。

    在这种情况下,您需要在使用适当的参数调用 GPIO_setConfig()之后调用 I2C_Close() API。 之后、您可以切换 SCL 引脚。 在几个脉冲之后,您可以使用 I2C_OPEN()切换回 I2C。 我现在不是100%、是否应该在 I2C 打开之前调用 I2C_init()。

    1月

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

    1月、

    感谢您提供信息。  您是否有 GPIO_setConfig()的任何使用示例?  我找不到任何合适的用法示例。   

    此外,I2C_open()是否会将引脚配置回 I2C 外设?  我想我担心将多路复用器的状态恢复到 I2C

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

    您好!

    我在项目 driverlib 中使用 TI-Drivers、因此我不是 TI-Drivers 的专家。 但看起来许多 SDK 示例都使用 GPIO_setConfig() API。 在示例中使用此函数看起来非常明显。 Resource Explorer SimpleLink Academy 中介绍了 TI-Drivers 的使用方法、但在这种情况下、我认为没有多大用处。

    I2C 的配置在 I2C_open() API 中传递给用户结构。

    如果您需要有关 TI-Drivers 工作原理的详细说明、可以等待 TI 的回答。

    1月

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

    您好!

    正如 Jan 所提到的,在调用 GPIO_init()后,您可以使用 GPIO_setConfig() API 将引脚复用为 GPIO。 在与您的类似用例中执行此操作的示例可在以下位置找到: https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/t/632665

    使用 GPIO_setConfig()函数重置 I2C 总线后,如果仍遇到问题,请告诉我。

    此致、

    Michael

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

    Michael、

    那么、我应该执行以下操作?  我猜不清楚我为 GPIO_setConfig 的第一个参数设置了什么。  它要求一个索引、但我看不到我从哪里得到它。  GPIO_14是 I2C 时钟。

    void i2cbusclear (void)
    {
    I2C_close();
    
    for (i=0;i<=10;i++)
    {
    GPIO_setConfig (我在此放置什么?、GPIOCC32XX_GPIO_14 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_STD_LOW);GPIO_CC32XX_INIT
    
    
    
    
    
    (I2C_LET_INIT);(what_INT_GPIO_INIT) 1);GPIO_INIT_GPIO_INIT (1)(what_GPIO_INIT)(what_GPIO_INIT);GPIO_INIT (1)(what_INT_GPIO_INIT 1)
    
    
    
    
    
    

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

    您好!

    应将 GPIO 枚举索引作为 GPIO_setConfig 的第一个参数。 如果您查看 CC3220S_LAUNCHXL.h 文件、则会看到 一个 CC3220SF_LAUNCHXL_GPIOName 枚举 typedef。  

    假设您的项目基于 SDK 示例、则 有许多预定义的 GPIO 枚举、例如 CC3220S_LAUNCHXL_GPIO_SW2、这些枚举基于 CC3220 Launchpad 外设命名。 虽然所有这些外设都具有 CC3220S_LAUNCHXL.c gpioPinConfigs 中定义的 GPIO_init()函数的默认设置,但如果要在 GPIO_init()之后动态重新配置其中一个 GPIO,则会将该枚举传递给 GPIO_setConfig()。 如果您需要有关如何使用该 API 的进一步指导,则 spimaster SDK 示例中使用了 GPIO_setConfig()示例。

    此致、
    Michael

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

    Michael

    抱歉、我仍在尝试了解该项目的所有层。  这是缺失的部分。  我不太了解它是如何映射引脚名称的。  我想这就是我需要做的所有事情。

    来自 CC3220S_LAUNCHXL.c

    typedef 枚举 CC3220S_LAUNCHXL_GPIOName{
    CC3220S_LAUNCHXL_GPIO_SW3 = 0、
    CC3220S_LAUNCHXL_GPIO_P、
    CC3220S_LAUNCHXL_GPIO_LED_D7、
    CC3220S_LAUNCHXL_GPIO_OUTPUT、
    CC3220S_LAUNCHXL_GPIO_F、
    CC3220S_LAUNCHXL_GPIO_A、
    CC3220S_LAUNCHXL_GPIO_CPU、
    CC3220S_LAUNCHXL_GPIO_C、
    CC3220S_LAUNCHXL_GPIO_L、
    CC3220S_LAUNCHXL_GPIO_FA、
    CC3220S_LAUNCHXL_GPIO_SCL、
    CC3220S_LAUNCHXL_GPIO_SDA、
    
    CC3220S_LAUNCHXL_GPIOCOUNT
    }CC3220S_LAUNCHXL_GPIOName; 

    然后从 CC3220S_LAUNCHXL.h 下载

    GPIO_PinConfig gpioPinConfigs[]={
    /*带有回调的输入引脚*/
    GPIOCC32XX_GPIO_13 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_RISING、
    
    /*输出引脚*/
    GPIOCC32XX_GPIO_09 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_28 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_10 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_08 | GPIO_CFG_IN_pu | GPIO_CFG_IN_INT_NONE、
    GPIOCC32XX_GPIO_11 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_12 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_30 | GPIO_CFG_IN_NOPULL、
    GPIOCC32XX_GPIO_00 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW、
    GPIOCC32XX_GPIO_16 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_HIGH、
    GPIOCC32XX_GPIO_14 | GPIO_CFG_IN_STD、// SCL
    GPIOCC32XX_GPIO_15 | GPIO_CFG_IN_STD,// SDA
    
    }; 

    那么、我只需执行以下操作:

    void i2cbusclear (void)
    {
    I2C_Close ();
    
    对于(i=0;i<=10;i++)
    {
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SCL、GPIOCC32XX_GPIO_14 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW);
    
    WAIT_ms (1);
    
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SCL、GPIOCC32XX_GPIO_14 | GPIO_CFG_IN_STD);
    
    wait_ms (1);
    }
    
    I2C_init();
    I2C_open();
    
    } 

    谢谢

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

    您好!

    您拥有的 i2cbusclear 函数应该会切换 I2C SCL 线路。 GPIO_setConfig 切换后,您不需要 I2C_init(),只需要 I2C_open()。

    此致、

    Michael

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

    Michael、

    我一直在研究这个问题、感觉我已经接近了、但是我现在挂起变量 I2C_Handle i2cHandle、我已经在 out_for_box.c 中将其声明为全局变量。

    因此、我从 out_for_box.c 中的 mainThread 中调用 i2cHandle = I2C_open (Board_I2C0、&i2cParams)、并使用位于 my_iRead2c.c 中的 out_for_box.c 进行一些调用

    但是,我想在 ReadRegisterValue()中处理总线清除。  问题是 I2C_Handle 仅传递给这些函数。   

    例如、在中

    int ReadRegisterValue (I2C_Handle i2cHandle、unsigned char ucRegAddr、unsigned char * pucRegValue、unsigned char i2caddress)

    如果出现错误, 我会 在特定的错误条件下调用 I2C_BusClear (),该错误条件将执行以下操作:

    void I2C_BusClear (I2C_Handle i2cHandle)
    {
    I2C_Close (i2cHandle);
    
    uint8_t i;
    
    对于(i=0;i<=9;i++)
    {
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SCL、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW);
    Task_sleep (1);
    
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SCL、GPIO_CFG_INPUT);
    Task_sleep(1);
    }
    
    //在时钟为高电平时将 SDA 驱动为低电平
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SDA、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW);
    
    //驱动 SDA 高电平、ile 时钟为高电平以创建停止条件
    GPIO_setConfig (CC3220S_LAUNCHXL_GPIO_SDA、GPIO_CFG_INPUT);
    
    i2cHandle = I2C_open (Board_I2C0、&i2cParams);
    
    if (i2cHandle ==空)
    {
    UART_PRINT("[链路本地任务]初始化 I2C\n\r")时出错;
    }
    } 

    我的问题是 I2C_open。  如何传递句柄 I2C_open 返回。  我假设这是一个唯一的数字、在调用 I2C_open 后、我需要以某种方式更新全局变量、以便需要传递句柄的 out_for_box.c 中的所有后续函数调用获得正确的值?  或者,当我调用 I2C_open()并且只能忽略该值时,我是否可以假设它将是相同的值?

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

    您好!

    您可能希望更新全局 I2C_Handle。 即使您现在恰好在 I2C_BusClear ()函数的 I2C_Close()和 I2C_open()之间获得相同的句柄,也不能保证将来的 SDK 更新中仍会出现这种情况。  

    如果已经将 I2C_handle i2C_handle 作为全局变量,则应该能够在 I2C_BusClear ()函数中自由分配其值。 不是让 I2C_BusClear ()将 I2C_Handle 作为输入,而是只需使用全局 I2C_Handle 即可。 更巧妙的解决方案是通过引用传递 I2C_Handle*来传递 I2C_Handle,然后根据需要修改指针处的数据。 在您的程序中执行此操作是否存在一些问题?

    此致、

    Michael

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

    您好、Michael、

    我让它正常工作。  我对如何正确使用句柄感到困惑。  如您所知、可能有几种方法可以正确编码某些内容、但有数百种或更多的方法可以错误处理。  我也找不到太多关于处理的文档、这可能会使我的困惑更加严重。

    感谢你的所有帮助。  非常感谢。