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.

[参考译文] TM4C1294NCPDT:RTOS I2C 驱动程序:需要使用不同的 I2C 总线(枚举中定义的除外)

Guru**** 2578945 points
Other Parts Discussed in Thread: EK-TM4C1294XL, TMP006, TCA9555, TM4C1292NCPDT, TM4C1294NCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1266080/tm4c1294ncpdt-rtos-i2c-driver-need-to-use-a-different-i2c-bus-other-than-defined-in-enum

器件型号:TM4C1294NCPDT
主题中讨论的其他器件:TMP006TCA9555TM4C1292NCPDT、EK-TM4C1294XL

您好!

我有一个针对我的项目的运行参考代码、在其中3个不同的 I2C 总线被用于运行项目、即 I2C1、I2C2、I2C9总线、它们在枚举中定义如下:

typedef enum EK_TM4C1294XL_I2CName {
    EK_TM4C1294XL_I2C1 = 0,
    EK_TM4C1294XL_I2C2,
	EK_TM4C1294XL_I2C9,

    EK_TM4C1294XL_I2CCOUNT
} EK_TM4C1294XL_I2CName;

但是、如果我想使用附加的 I2C 总线、即 I2C5、而不干扰现有的 I2C 通信(即 I2C1、2和9)、我该怎么做? 它未在枚举中定义。

RTOS 中的用法如下:

 stI2cConfig.vui8I2cBus = Board_I2C9;

其中  

#define Board_I2C1 EK_TM4C1294XL_I2C1
#define Board_I2C2 EK_TM4C1294XL_I2C2
#define Board_I2C9 EK_TM4C1294XL_I2C9

上述内容在 Board.h 文件中定义、而 I2C5总线未定义。

请帮助实现 I2C5通信。

此致、

Kiran

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

    尊敬的 Charles:

    您能否共享用于 I2C 读取的示例代码(超过1个字节)?

    谢谢。

    Kiran

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

    请返回到我昨天写的所有内容。 在您最新修改的代码中、有一件事是关于  I2CMasterBus 的错误操作。 再次参见下面的内容。  

    替换代码中的所有位置:

    while (I2CMasterBusy (pI2cData->ui32I2cBus)
    {

    复选框。  

    while (! I2CMasterBusy (pI2cData->ui32I2cBus) //您必须使用此行才能解决某些已知问题(由于某些竞争)

                                          //硬件中的条件。
    {

    while (I2CMasterBusy (pI2cData->ui32I2cBus) //您也必须保留此值。 但在最新代码中将其删除。  
    {

    I aleady 用 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl-boostxl-sensub\HUMIDITY_sht21_simple 提供了一个读示例。 为什么不仔细阅读呢? 下面是从从器件读取三个字的序列。

    //*****************************************************************************
    //
    // This function will read three 8-bit data from the I2C slave. The first
    // two 8-bit data forms the humidity data while the last 8-bit data is the
    // checksum.  This function illustrates three different I2C burst mode
    // commands to read the I2C slave device.
    //
    //*****************************************************************************
    void
    I2CReadCommand(uint32_t * pui32DataRx)
    {
        //
        // Modify the data direction to true, so that seeing the address will
        // indicate that the I2C Master is initiating a read from the slave.
        //
        MAP_I2CMasterSlaveAddrSet(I2C7_BASE, SHT21_I2C_ADDRESS, true);
    
        //
        // Setup for first read.  Use I2C_MASTER_CMD_BURST_RECEIVE_START
        // to start a burst mode read.  The I2C master continues to own
        // the bus at the end of this transaction.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    
        //
        // Wait until master module is done transferring.
        // The I2C module has a delay in setting the Busy flag in the register so
        // there needs to be a delay before checking the Busy bit.  The below loops
        // wait until the Busy flag is set, and then wait until it is cleared to
        // indicate that the transaction is complete.  This can take up to 633 CPU
        // cycles @ 100 kbit I2C Baud Rate and 120 MHz System Clock.  Therefore, a
        // while loop is used instead of SysCtlDelay.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
    
        //
        // Read the first byte data from the slave.
        //
        pui32DataRx[0] = MAP_I2CMasterDataGet(I2C7_BASE);
    
        //
        // Setup for the second read.  Use I2C_MASTER_CMD_BURST_RECEIVE_CONT
        // to continue the burst mode read.  The I2C master continues to own
        // the bus at the end of this transaction.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
    
        //
        // Wait until master module is done transferring.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
    
        //
        // Read the second byte data from the slave.
        //
        pui32DataRx[1] = MAP_I2CMasterDataGet(I2C7_BASE);
    
        //
        // Setup for the third read.  Use I2C_MASTER_CMD_BURST_RECEIVE_FINISH
        // to terminate the I2C transaction.  At the end of this transaction,
        // the STOP bit will be issued and the I2C bus is returned to the
        // Idle state.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
        //
        // Wait until master module is done transferring.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        
        //
        // Note the third 8-bit data is the checksum byte.  It will be
        // left to the users as an exercise if they want to verify if the
        // checksum is correct.
        pui32DataRx[2] = MAP_I2CMasterDataGet(I2C7_BASE);
    }

    我不能帮你,如果你不读应用手册,我今天上午回复了下面的截图。 你为什么不回去我今天早上回答的。  

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

    尊敬的 Charles:

    很抱歉、我将仔细查看这个示例并尝试您建议的方法。

    谢谢。

    Kiran

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

    只是需要澄清一下。

    如以下代码片段中所示、如果我们 在每次读取操作之前初始化时钟、不会导致问题吗?

     I2CMasterEnable(pI2cData->ui32I2cBus);
    
        //if true - 400Khz, False - 100Khz
        I2CMasterInitExpClk(pI2cData->ui32I2cBus, 120000000, true);
    

    此致、

    Kiran

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

    尊敬的 Charles:

    我阅读了示例代码和应用手册、并根据它更改了 i2c 读取代码。

    对于 tca9555上单个的读操作:

    • IN 必须发送第一字节从器件地址。
    • 在第二个字节中、必须发送寄存器地址(从中读取)。
    • 在第三个字节中、 重复起始后从器件地址再次发送。  
    • 在第4字节中、从内部寄存器读取的数据从从器件传输到主器件。

    因此、在读取代码中、我将首先发送内部寄存器地址(在设置从器件地址之后)。 之后、我将启动突发读取、以从地址为0x00和0x01的2个内部寄存器进行读取。

    void DiI2cRead(I2cStructType *pI2cData)
    {
        uint32_t ui32Index = 0;
        uint32_t ui32ErrCount;
    
        I2CMasterEnable(pI2cData->ui32I2cBus);
    
        //if true - 400Khz, False - 100Khz
        I2CMasterInitExpClk(pI2cData->ui32I2cBus, 120000000, true);
    
        I2CMasterSlaveAddrSet(pI2cData->ui32I2cBus,
                                             pI2cData->i2cSlaveAddress, false);//false for write transaction
    
        //specify register to be read
        I2CMasterDataPut(I2C0_BASE, pI2cData->pui8DataTx[0]);
    =
        I2CMasterControl(pI2cData->ui32I2cBus,  I2C_MASTER_CMD_BURST_RECEIVE_START);
    
        while(!I2CMasterBusy(pI2cData->ui32I2cBus))
        {
    
        }
        while(I2CMasterBusy(pI2cData->ui32I2cBus))
        {
        }
    
        ui32ErrCount = I2CMasterErr(pI2cData->ui32I2cBus);
        if(ui32ErrCount != I2C_MASTER_ERR_NONE)
        {
            Event_post(Event_Fault_Handler, Event_Id_00);
        }
        *(pI2cData->pui8DataRx + 0) =   I2CMasterDataGet(pI2cData->ui32I2cBus);
    
        I2CMasterControl(pI2cData->ui32I2cBus,  I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
        while(!I2CMasterBusy(pI2cData->ui32I2cBus))
        {
    
        }
        while(I2CMasterBusy(pI2cData->ui32I2cBus))
        {
        }
    
        ui32ErrCount = I2CMasterErr(pI2cData->ui32I2cBus);
        if(ui32ErrCount != I2C_MASTER_ERR_NONE)
        {
            Event_post(Event_Fault_Handler, Event_Id_00);
        }
    
        *(pI2cData->pui8DataRx + 1) =   I2CMasterDataGet(pI2cData->ui32I2cBus);
    
        I2CMasterDisable(pI2cData->ui32I2cBus);
    }

    我在该中断中获得了以下示波器捕获。

    请注意、它是一个小而宽的脉冲、而不是窄 ACK 尖峰。 为什么会这样呢? 发送内部寄存器地址后、不会出现读取数据。

    对为什么会出现这种宽脉冲有什么建议吗?

    此致、

    Kiran

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

    尊敬的 Charles:

    我尝试在现有的工作项目中更改 i2cread 功能。

    在现有的工作项目中、代码如下(在中断处理程序中正常工作)。 请注意、现有项目只有一个用于数字输入的 IO 扩展器和一个用于 LED 的 IO 扩展器、因此具有一个中断处理程序。

    中断处理程序的代码为:

    void ISRHandler1()
    {
    //    GPIO_toggle(BOARD_PORTL_PIN4);
        I2cStructType stI2cData;
        int Key;
    
        GPIO_disableInt(BOARD_PORTF_PIN0);
        GPIO_clearInt(BOARD_PORTF_PIN0);
    
        stI2cData.ui32I2cBus = I2C9_BASE;
        stI2cData.i2cSlaveAddress = DI_SLAVEADDRESS;
        stI2cData.ui32TxCount = 1;
        stI2cData.ui32RxCount = 2;
        stI2cData.pui8DataRx = ui8DiRxBuf;
        ui8DiTxBuf[0] = 0x00;
        stI2cData.pui8DataTx = ui8DiTxBuf;
    
        // Read DI Status
        DiI2cRead(&stI2cData);
        pui8DiRawStatus1 = (uint8_t*)stI2cData.pui8DataRx;
    
        //Schedule Even Post to process the digital input status
        Event_post(Event_Digital_Input_Handler, Event_Id_00);
        GPIO_enableInt(BOARD_PORTF_PIN0);
    
        if(bDebounceTimerFlag == TRUE)
        {
            // de-bounce timer start
            Key = Hwi_disable();
            Timer_stop(Di_Debounce_Timer_Handler);
            Timer_setPeriodMicroSecs(Di_Debounce_Timer_Handler,
                                     (ui16DebounceMin * 1000));
            Timer_start(Di_Debounce_Timer_Handler);
            Hwi_restore(Key);
    
            ui16DebounceCount = ui16DebounceMaxCount;
        }
    }

    上面 ISR 中使用的 DiI2cRead (&stI2cData)函数为:

    void DiI2cRead(I2cStructType *pI2cData)
    {
        uint32_t ui32Index = 0;
        uint32_t ui32ErrCount;
    
        I2CMasterEnable(pI2cData->ui32I2cBus);
    
        /*if true - 400Khz, False - 100Khz */
        I2CMasterInitExpClk(pI2cData->ui32I2cBus, 120000000, true);
    
        I2CMasterSlaveAddrSet(pI2cData->ui32I2cBus,
                                             pI2cData->i2cSlaveAddress, false);
    
        I2CMasterBurstLengthSet(pI2cData->ui32I2cBus, pI2cData->ui32TxCount);
    
        I2CMasterControl(pI2cData->ui32I2cBus,
                                    I2C_MASTER_CMD_FIFO_BURST_SEND_START);
        for(ui32Index = 0; ui32Index < pI2cData->ui32TxCount; ui32Index++)
        {
    
            I2CFIFODataPut(pI2cData->ui32I2cBus,
                                           *(pI2cData->pui8DataTx+ui32Index));
        }
    
        while(I2CMasterBusy(pI2cData->ui32I2cBus))
        {
    
        }
    
        ui32ErrCount = I2CMasterErr(pI2cData->ui32I2cBus);
        if(ui32ErrCount != I2C_MASTER_ERR_NONE)
        {
            Event_post(Event_Fault_Handler, Event_Id_00);
        }
        I2CMasterDisable(pI2cData->ui32I2cBus);
    
        I2CMasterEnable(pI2cData->ui32I2cBus);
    
        /*if true - 400Khz, False - 100Khz */
        I2CMasterInitExpClk(pI2cData->ui32I2cBus, 120000000, true);
    
        I2CMasterSlaveAddrSet(pI2cData->ui32I2cBus,
                                             pI2cData->i2cSlaveAddress, true);
        I2CMasterBurstLengthSet(pI2cData->ui32I2cBus, pI2cData->ui32RxCount);
    
        I2CMasterControl(pI2cData->ui32I2cBus,
                         I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE);
    
        while(I2CMasterBusy(pI2cData->ui32I2cBus))
        {
    
        }
        ui32ErrCount = I2CMasterErr(pI2cData->ui32I2cBus);
        if(ui32ErrCount != I2C_MASTER_ERR_NONE)
        {
            Event_post(Event_Fault_Handler, Event_Id_00);
        }
        for(ui32Index = 0; ui32Index < pI2cData->ui32RxCount; ui32Index++)
        {
    
            *(pI2cData->pui8DataRx+ui32Index) =
                                         I2CFIFODataGet(pI2cData->ui32I2cBus);
        }
        I2CMasterDisable(pI2cData->ui32I2cBus);
    }
    

    上述代码片段在当前参考项目中正常运行。 放大和缩小范围捕捉请见下方(在上述代码片段的中断处理程序中)。

               

               

    黄色-> LED SCL、绿色-> LED SDA、蓝色->数字输入 SCL、粉色->数字输入 SDA

    但是、当我在自定义板中针对超过1个 ISR (增加 IO 扩展器的数量)使用这些扩展器时、相同的代码无法正常运行。

    此外,如果在上面的工作项目 i2cread 代码,如果我做你建议的更改(作为我的前一篇文章的代码片段)。

    然后我得到下面所说的非常奇怪的东西。

                   

    我是否可以将第二条中断线路(第二个 IO 扩展器的第二条中断线路)与第一条中断线路相结合、并提供一个组合中断作为微控制器的输入?

    我应该如何进行? 请提供建议。  

    此致、

    Kiran

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

    尊敬的 Charles:

    非常感谢、它很有效。

    以下是第1个和第2个中断处理程序(对应于数字输入的第一个和第二个 IO 扩展器)中读取事务的示波器捕获。

                  

    第1个中断处理程序(0-11个数字输入)                                     第2个中断处理程序(12-23个数字输入)。

    我将数字输入应用于两个 IO 扩展器上的全部12个输入、因此这两个都读取 FF FF (在所有通道上都为"1")、现在还没有挂起。

    但相应的 LED 仍然没有通过第二个中断处理程序发光。

    需要您的帮助。 以下是2个 LED IO 扩展器(由上述 ISR 驱动)的示波器捕获结果。  

                                              

    第1个 LED IO 扩展器

                      

    第2个 LED IO 扩展器

                            

    根据上面的原理图、 (IO 扩展器的) LED 输出(即 DIOx_LED_CTRL)必须为低电平才能使 LED 导通。

    因此、在上面的示波器捕获中、第一个 LED IO 扩展器的输出为00 00、因此当在所有通道上应用相应的数字输入(0-11)时、所有 LED 都会发光。 但第二个 IO 扩展器 LED 的输出为零。  

    不知道是否正在应用正确的逻辑来发送13-24个数字输入通道的通道状态、以便使第二个 LED IO 扩展器的 LED 发光。

    我刚刚在私人消息中共享了详细信息(请忽略之前发送的消息)、因为我无法公开共享这些信息。

    您能指导一下吗?

    谢谢。

    Kiran

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

    在您的第一次 LED IO 扩展器捕获中、您有27wa -> 02a -> 00a -> c0a。 这意味着您要向 I/O 的低12位写入0。 这就是它们发光的原因。 再次查看您自己的捕获。  

    在您的第二个 LED 扩展器捕获中、有26wa -> 02a -> FFA -> 0Fa。 您将向所有1写入第二个 LED 扩展器的低12位。 这就是它们不发光的原因。 如果您的硬件需要一个零来发光 LED、通过观察捕获、我认为这显然是错误的。 请查看您自己的捕获。 您需要弄清楚为什么要写入 F 而不是0。  

     在调用 DILEDUpdate2 (DILEDUpdate2)之前、为何不要单步执行以了解 ui16ChannelStatus 最终变为什么。 我不知道   DILEDUpdate2是否是您用于将 I2C 命令发送到第二个 LED 扩展器的函数。  

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

    尊敬的 Charles:

    感谢您的答复。 事情似乎也在发光 LED 的进展,只是需要更深入的逻辑工作.

    还有一个问题。 在初始化数字输入 IO 扩展器的配置寄存器0x06时、它在 I2C 事务期间处于等待状态。 请参阅下面的示波器捕获

        i2cConfigbus stI2cConfig;
        uint8_t aui8txBuffer[4];
        uint8_t aui8rxBuffer[4];
       
        /* Configuring IO expander port as input for digital input and
         * output for Source sink selection
         */
        stI2cConfig.ui8regaddr = 0x06;
        stI2cConfig.vui8slaveAddress =  DI_SLAVEADDRESS;
        stI2cConfig.vui8I2cBus = Board_I2C9;
        aui8txBuffer[0] = 0x06;
        aui8txBuffer[1] = 0xFF;
        aui8txBuffer[2] = 0x0F;
        stI2cConfig.pui8txbuffer = aui8txBuffer;
        stI2cConfig.pui8RxBuffer = aui8rxBuffer;
        stI2cConfig.vui8writeCount = 3;
        stI2cConfig.vui8readCount = 0;
        DII2CTransfer(&stI2cConfig);

     DI2CTransfer (&stI2cConfig)函数如下所示。 如果需要更正此函数中的任何内容、请告诉我。

    void DII2CTransfer(i2cConfigbus *stI2cConfig)
    {
        I2C_Handle      i2c;
        I2C_Params      i2cParams;
        I2C_Transaction i2cTransaction;
    
        Semaphore_pend(Sem_DI_I2c_Handle, BIOS_WAIT_FOREVER);
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz;
        i2c = I2C_open(stI2cConfig->vui8I2cBus, &i2cParams);
        if (i2c == NULL) {
            DRIVER_ERR("Error Initializing I2C\n");
        }
        else {
            DEBUG_DRIVER("I2C Initialized!\n");
        }
    
        i2cTransaction.slaveAddress = stI2cConfig->vui8slaveAddress;
        i2cTransaction.writeBuf = stI2cConfig->pui8txbuffer;
        i2cTransaction.writeCount = stI2cConfig->vui8writeCount;
        i2cTransaction.readBuf = stI2cConfig->pui8RxBuffer;
        i2cTransaction.readCount = stI2cConfig->vui8readCount;
    
        /* Print the Data send through the I2C */
        if(I2C_transfer(i2c, &i2cTransaction))  {
        }
        else {
            DRIVER_ERR("I2C Bus fault\n");
        }
    
        /* De-initialized I2C */
        I2C_close(i2c);
        DEBUG_DRIVER("I2C closed!\n");
        DEBUG_DRIVER_FLUSH();
        stI2cConfig->pui8RxBuffer = i2cTransaction.readBuf;
        Semaphore_post(Sem_DI_I2c_Handle);
    }

    谢谢。

    Kiran

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

    我有一些评论。

    -请显示每个信号的标签。 蓝色时钟出现问题还是黄色时钟?  

    -没有一个缩放镜头,我真的不能知道发生了什么。 如果蓝色是时钟、则表示它正在拉伸。 根据 I2C 标准、从器件可以通过将 SCL 保持为低电平来延展时钟。 会发生这种情况吗?  

    -这是您第一次看到一个具有等待状态的波形吗?

    -您的最新代码显示您正在使用 TI-RTOS I2C 驱动程序、而在您的前一个代码中有很多星期都在使用 TivaWare I2C driverlib。 你为什么要来回变换。 我很难帮助你。 你说我们过去几周尝试的一切都浪费了吗? 您在 最后几个帖子中显示了 IOC_DiI2cRead (),现在您正在切换到 DI2CTransfer ()。 哪一个用于什么? 我真的很困惑。

     -您真的需要以400Khz 的频率操作吗? 为什么不首先尝试100kHz 的基本 I2C 模式? 在您冒险进入快速模式之前、请始终让简单的东西正常工作。  

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

    尊敬的 Charles:

    蓝线是问题所在。

    您最新的代码显示您使用的是 TI-RTOS I2C 驱动程序,而在您之前的代码中有许多星期都是使用 TivaWare I2C driverlib。 你为什么要来回变换。 [/报价]

    在现有的工作工程中、Tiva ware driverlib 函数在中断处理程序中使用、而 TI-RTOS I2C 函数在代码的其他任何地方使用。

    我将尝试对现有工作项目进行最小的更改、这就是使用类似函数的原因。

    此致、

    Kiran  

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

    尊敬的 Charles:

    I2C 通信正常。 我需要帮助解决另一个问题。

    在我的原理图中、我有一个拉电流/灌电流逻辑 GPIO 引脚、IO 扩展器的极性基于该引脚相反。  

    因此、我们之前解决的读取操作问题是针对 受电方逻辑的。  在我的 接收器逻辑中、I2C 读取操作和工程(LED 和通过 GUI 进行数据通信)可以很好地工作。  请参阅下面的灌电流逻辑示波器捕获

                       

        第1个中断处理程序(0-11个数字输入)                                           第2个中断处理程序(12-23个数字输入)

    但在 源逻辑中、读取的 I2C 值与预期值不同(应该与在源逻辑中读取的值相反、因为我正在设置 TCA9555的内部极性反转寄存器中的极性反转位)。 但是、当我向数字输入 IO 扩展器的所有12位提供输入时(采用与上述 Source 逻辑情况类似的方式)、读取的值(反相极性后)应该为00 F0 (根据 ME)。 但范围结果如下:

                 

     第1个中断处理程序(应用0-11个输入时)                                   第1个中断处理程序(删除0-11个输入后)

                          第2个中断处理器(应用12-23个输入时)                           第2个中断处理程序(删除12-23个输入后)        

    我将在专有消息中发布该代码、以便在使用源逻辑的情况下设置极性反转位。

    请指导 源代码逻辑的问题在哪里。

    谢谢。

    Kiran

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    因此,我们先前解决的读操作问题是针对 受电方逻辑的。  在我的 接收器逻辑中、I2C 读取操作和工程(LED 和通过 GUI 进行数据通信)可以很好地工作。  查看下方灌电流逻辑的示波器捕获[/引号]

    很高兴取得了一些进展。  

    但在 源代码逻辑中、读取的 I2C 值与预期值不同(由于我正在 TCA9555的内部极性反转寄存器中设置极性反转位、因此应该与在源逻辑中读取的值相反)。 但是、当我向数字输入 IO 扩展器的所有12位提供输入时(采用与上述 Source 逻辑情况类似的方式)、读取的值(反相极性后)应该为00 F0 (根据 ME)。 但范围结果是:

    Source_Sink_Sel 1的值是什么?为什么需要先右移一位?  

    能否展示一下写入反转寄存器的示波器电容?

    写入反转寄存器后、为什么不再次读取反转寄存器看看数据是否真正被写入。

    您说过、您有一个用于确定拉电流/灌电流逻辑的 GPIO 引脚。 这个 GPIO 引脚是什么? 显示了一个示波器屏幕截图、其中显示该引脚实际上改变了状态。

    第一个中断处理程序(删除0-11个输入后)

    在示波器电容标题中、您说过您删除了0-11个输入。 删除是什么意思? 虽然我不熟悉 TCA9555、但我认为您不应该删除输入、在某种意义上让输入悬空。 对于实验、您仍应将输入连接到 GND、但应用反相逻辑。 我想您会读出高电平。  

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

    您好  

    [报价 userid="93620" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1266080/tm4c1294ncpdt-rtos-i2c-driver-need-to-use-a-different-i2c-bus-other-than-defined-in-enum/4834580 #4834580"] Source_Sink_Sel 1的价值何在?为什么需要先右移一位?  [/报价]

    GPIOPinRead (GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1)和0x02) Source_Sink_Sel;

    它位于引脚 PN1上、因此右移1位、  

    在示波器电容标题中、您说过您删除了0-11个输入。 删除是什么意思? 虽然我不熟悉 TCA9555、但我认为您不应该删除输入、在某种意义上让输入悬空。 对于实验、您仍应将输入连接到 GND、但应用反相逻辑。 我想您会读出高电平。  

    --是的,实际上有一定的电压范围,在源/接收逻辑中输入被视为开/关。

    将在实验后为您提供其他输入。 同时、如果您有任何其他建议、请告诉我。

    谢谢。

    Kiran

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

    尊敬的 Charles:

    问题已解决并正常工作。  

    反转极性后、其工作方式应与灌电流逻辑完全相反、并且仅以该方式工作。

    非常感谢您的支持。

    非常感谢。

    谢谢。

    Kiran

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

    尊敬的 Kiran:

     很高兴您的问题现已解决。  

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

    尊敬的 Charles:

    我还有一个与此相关的问题。

    在第三个电路板中、我有2个数字输入 IO 扩展器(1个有12个输入、第二个有4个数字输入)、1个 LED IO 扩展器有16个 LED、对应于上述两个 IO 扩展器的数字输入。

                  

                                            2个数字 IO 扩展器

                       LED IO 扩展器(对应于上述2个 IO 扩展器的16个数字输入)

    对于 LED 更新、由于2个数字输入 IO 扩展器的通道状态、我已经为发光 LED (在单个 IO 扩展器上)编写了以下代码

    void DILEDUpdate5(uint16_t channelStatus)
    {
        i2cConfigbus stI2cConfig;
        uint8_t aui8TxBuffer[4];
        uint8_t aui8RxBuffer[3];
    
        /* Configuration of Digital Input LED*/
        DEBUG_DRIVER("\nDigital Input LED Update\n");
        DEBUG_DRIVER_FLUSH();
    
        channelStatus = ~channelStatus;
    
        //aui8TxBuffer[1] = aui8TxBuffer[2] | ((channelStatus << 12) & 0xC0);
        aui8TxBuffer[1] = (channelStatus | 0xFF00 );
        aui8TxBuffer[2] = (channelStatus | 0x00FF );
    
        aui8TxBuffer[0] = DIO_OUTPUTREG_PORTONE;
        stI2cConfig.ui8regaddr = DIO_OUTPUTREG_PORTONE;
        stI2cConfig.vui8slaveAddress =  DI_LED_SLAVEADDRESS3;
        stI2cConfig.vui8I2cBus = Board_I2C2;
        stI2cConfig.pui8txbuffer = aui8TxBuffer;
        stI2cConfig.pui8RxBuffer = aui8RxBuffer;
        stI2cConfig.vui8writeCount = 3;
        stI2cConfig.vui8readCount = 0;
        DigitalLEDI2CTransfer(&stI2cConfig);
    
    }

    其中 channelStatus 是从两个数字输入 IO 扩展器的输入寄存器读取的16位值。

    我将分别从第1个和第2个中断处理程序的2个事件调用、如下所示:

    IoC_DILEDUpdate5(ui16RawChannelStatus4);

    其中

    ui16RawChannelStatus3 =(*(pui8DiRawStatus3 + 0)和0xFFFF)|
    ((*(pui8DiRawStatus3 + 1)<< 8)和0xFFFF);

    ui16RawChannelStatus4 =(*(pui8DiRawStatus4 + 0)& 0x000F);

    此外、  

    pui8DiRawStatus3 =(uint8_t*) stI2cConfig.pui8RxBuffer;//从第一个 dig 输入 IO 扩展器的输入寄存器端口0读取数据

    pui8DiRawStatus4 =(uint8_t*) stI2cConfig.pui8RxBuffer;//从 第二个 dig 输入 IO 扩展器的输入寄存器端口0读取数据

    但在最后4个输入时没有 LED 亮起、开始的8个 LED 会跟随活动的数字输入通道亮起。

    要读取的 DIG 输入和写入 LED IO 扩展器的数据的示波器捕获为:

    DIG IO 扩展器数据读取

     \

    LED IO 扩展器(输出)

    因此、根据该信息、只有一个输出将在 LED IO 扩展器中发光、但没有 LED 亮起

    如果需要更改 LED 代码中的任何内容、请提供指南。

    此致、

    Kiran

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

    我认为您需要根据示波器捕获首先回答问题。 捕获可以帮助您进行调试。 同样、我只能从 MCU 端提供帮助、不能在 I2C 从器件上提供帮助。 如果您认为 MCU 发送了正确的命令、而从器件未按预期响应、则需要自己进行一些调试或向接口论坛团队寻求一些指导。   

    捕获显示您正在将值0xFE_FF 写入寄存器0x2。 您想要的结果。 寄存器0x2是否是您要写入的地址? 跟踪并单步执行您的代码、以查看 FEFF 是否是您需要写入的数据值。  

    在数字 IO 扩展器中、示波器捕获显示您正在从寄存器0x0读取、而寄存器的返回值为0xF1FF。 预期读取的 F1FF。 如果不是、您需要调试它为什么不返回预期值。