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.

[参考译文] TMS320F28386D:RTC 示例

Guru**** 2457760 points
Other Parts Discussed in Thread: TMS320F28386D

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1322801/tms320f28386d-rtc-example

器件型号:TMS320F28386D

您好!

我正在测试这里使用的相同示例: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1306409/tms320f280025c-ds3231n

我尝试从 RTC 读取、但无法读取数据:

我正在使用不同的 C2000微控制器(TMS320F28386D)、RTC (ISL12022M)、并且从数据表中我不清楚要使用的地址是什么:我认为正确的地址是0x6f:

器件寻址

在一个 START 条件之后、主器件必须输出一个从器件地址字节。 7个 MSB 是器件标识符。 这些位对于 RTC 寄存器为"1101111"、对于用户 SRAM 为"1010111"。

从器件地址字节的最后一位定义了要执行的读取或写入操作。 当这个 R/W 位为一个"1"时、一个读取操作被选择。 一个"0"选择一个写入操作

但我不清楚如何在代码中设置读取/写入位。 在本例中、我必须为读取操作设置1、但我要在哪里设置此值?

//#############################################################################
//
// FILE:   i2cLib_FIFO_polling.c
//
// TITLE:  C28x-I2C Library source file for FIFO using polling
//! <h1> C28x-I2C Library source file for FIFO using polling </h1>
//
//#############################################################################
//#############################################################################
//
//
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

#include "i2cLib_FIFO_polling.h"

uint16_t I2CBusScan(uint32_t base, uint16_t *pAvailableI2C_targets)
{
    uint16_t probeTargetAddress, i;

    //Disable interrupts on Stop condition, NACK and arbitration lost condition
    I2C_disableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

    i = 0;
    for(probeTargetAddress=1;probeTargetAddress<=MAX_10_BIT_ADDRESS;probeTargetAddress++)
    {
        //Check I2C bus status
        status = checkBusStatus(base);
        if(status)
        {
           ESTOP0;
           return status;
        }

        I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE));

        //Enable 10-bit addressing if probeTargetAddress is greater than 127U
        if(probeTargetAddress > MAX_7_BIT_ADDRESS)
        {
            //10-bit addressing
            I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
        }

        // Setup target address
        I2C_setTargetAddress(base, probeTargetAddress);


        I2C_sendStartCondition(base);

        //Wait for the target address to be transmitted
        while(!(I2C_getStatus(base) & I2C_STS_REG_ACCESS_RDY));

        //Generate STOP condition
        I2C_sendStopCondition(base);

        //Wait for the I2CMDR.STP to be cleared
        while(I2C_getStopConditionStatus(base));

        //Wait for the Bus busy bit to be cleared
        while(I2C_isBusBusy(base));

        uint16_t I2CStatus = I2C_getStatus(base);

        //If target address is acknowledged, store target address
        //in pAvailableI2C_targets
        if(!(I2CStatus & I2C_STS_NO_ACK))
        {
            pAvailableI2C_targets[i++] = probeTargetAddress;
        }
        //Clear NACK bit in I2CSTR
        I2C_clearStatus(base,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
    }

    I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
    I2C_setAddressMode(base, I2C_ADDR_MODE_7BITS); //7-bit addressing
    I2C_enableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
    return SUCCESS;
}

uint16_t I2C_TransmittargetAddress_ControlBytes(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount=1;

    uint32_t base = I2C_Params->base;

    status = 1;

    while(status & (attemptCount <= I2C_Params->NumOfAttempts))
    {
        status = checkBusStatus(base);
        attemptCount++;
        DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    if(status)
    {
        return status;
    }

    I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE|I2C_REPEAT_MODE));

    if((I2C_Params->TargetAddr) > MAX_7_BIT_ADDRESS)
    {
        //10-bit addressing
        I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
    }

    // Setup target address
    I2C_setTargetAddress(base, I2C_Params->TargetAddr);


    int16_t  i;
    uint32_t temp = *(I2C_Params->pControlAddr);

    for(i=I2C_Params->NumOfAddrBytes-1;i>=0;i--)
    {
        I2C_putData(base, (temp >> (i*8U)) & 0xFF);
    }

    I2C_sendStartCondition(base);

    DEVICE_DELAY_US(150U);

    status = handleNACK(base);
    if(status)
    {
      if(attemptCount <= (I2C_Params->NumOfAttempts))
      {
          attemptCount++;
          I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
          I2C_sendStartCondition(base);
          DEVICE_DELAY_US(I2C_Params->Delay_us);
      }
      else
      {
          return status;
      }
	}

    attemptCount = 1;

    while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_Params->NumOfAddrBytes + 2U))
    {
       status = handleNACK(base);
       if(status)
       {
          return status;
       }
       attemptCount++;
       DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    return SUCCESS;
}

uint16_t I2C_ControllerTransmitter(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount;

    uint32_t base = I2C_Params->base;

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmittargetAddress_ControlBytes(I2C_Params);

    if(status)
    {
        return status;
    }

    I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes));

    I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);

    I2C_enableInterrupt(base, I2C_INT_TXFF);

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    uint16_t i,count = 0,buff_pos=0;

    while(count < numofSixteenByte)
    {
        for(i=1;i<=I2C_FIFO_LEVEL;i++)
        {
            I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
        }

        attemptCount = 1;
        while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_FIFO_LEVEL + 2U))
        {
            status = handleNACK(base);
            if(status)
            {
              return status;
            }
            attemptCount++;
            DEVICE_DELAY_US(I2C_Params->Delay_us);
        }

        count++;
    }

    for (i=0; i < remainingBytes; i++)
    {
        I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
    }

    attemptCount = 1;
    while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (remainingBytes + 2U))
    {
        status = handleNACK(base);
        if(status)
        {
          return status;
        }
        attemptCount++;
        DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    I2C_sendStopCondition(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U)
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    return SUCCESS;
}

uint16_t I2C_ControllerReceiver(struct I2CHandle *I2C_Params)
{
    uint16_t status;
    uint16_t attemptCount;

    uint32_t base = I2C_Params->base;

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmittargetAddress_ControlBytes(I2C_Params);

    if(status)
    {
        return status;
    }

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    I2C_setConfig(base, (I2C_CONTROLLER_RECEIVE_MODE|I2C_REPEAT_MODE));

    I2C_sendStartCondition(base);

    uint16_t i,count = 0,buff_pos=0;
    while(count < numofSixteenByte)
    {
        status = handleNACK(base);
        if(status)
        {
          return status;
        }

        count++;

        attemptCount = 1;
        while(!(I2C_getRxFIFOStatus(base) == I2C_FIFO_RXFULL) && attemptCount <= 9 * (I2C_FIFO_RXFULL + 2U))
        {
            DEVICE_DELAY_US(I2C_Params->Delay_us);
            attemptCount++;
        }

        for(i=0; i<I2C_FIFO_LEVEL; i++)
        {
            I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
        }
    }

    attemptCount = 1;
    while(!(I2C_getRxFIFOStatus(base) == remainingBytes) && attemptCount <= 9 * (remainingBytes + 2U))
    {
       DEVICE_DELAY_US(I2C_Params->Delay_us);
       attemptCount++;
    }

    I2C_sendStopCondition(base);

    for(i=0; i<remainingBytes; i++)
    {
        I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
    }

    status = handleNACK(base);
    if(status)
    {
      return status;
    }

    I2C_disableFIFO(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U);
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    return SUCCESS;

}


uint16_t checkBusStatus(uint32_t base)
{

    if(I2C_isBusBusy(base))
    {
        return ERROR_BUS_BUSY;
    }

    if(I2C_getStopConditionStatus(base))
    {
        return ERROR_STOP_NOT_READY;
    }

    return SUCCESS;
}

uint16_t handleNACK(uint32_t base)
{
    if(I2C_getStatus(base) & I2C_STS_NO_ACK)
    {
        I2C_clearStatus(base, I2C_STS_NO_ACK);
        I2C_sendStopCondition(base);

        return ERROR_NACK_RECEIVED;
    }

    return SUCCESS;
}

代码滞留在此处:

 状态= I2C_ControllerReceiver (&RTC);在该函数中,发生了以下事件:      while (I2C_getStopConditionStatus (base)&& quertCount <= 3U);

//*****************************************************************************
//
//! Get stop condition status.
//!
//! \param base is the base address of the I2C instance used.
//!
//! This function reads and returns the stop condition bit status.
//!
//! \return Returns \b true if the STP bit has been set by the device to
//! generate a stop condition when the internal data counter of the I2C module
//! has reached 0. Returns \b false when the STP bit is zero. This bit is
//! automatically cleared after the stop condition has been generated.
//
//*****************************************************************************
static inline bool
I2C_getStopConditionStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(I2C_isBaseValid(base));

    //
    // Check the stop condition bit and return appropriately.
    //
    return((HWREGH(base + I2C_O_MDR) & I2C_MDR_STP) != 0U);
}

一些有用的提示会非常感谢!  

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

    您好 Gianni、

    Unknown 说:
    我正在使用不同的 C2000微控制器(TMS320F28386D)、RTC (ISL12022M)、并且从数据表中我还不清楚要使用的地址是什么:我认为正确的地址是0x6f:

    根据我从说明中了解的内容、这似乎是正确的。

    Unknown 说:
    、但我不清楚如何在代码中设置读/写位。 在本例中、我必须为读取操作设置1、但我要在哪里设置此值?

    这是通过 I2C_setConfig 函数完成的、该函数将配置 I2C 外设以进行发送或接收。 您正在寻找的总线扫描功能只是用于扫描总线以查看连接了什么、它不会发送/接收任何东西(我相信不应该)。

    代码滞留在此处:

     状态= I2C_ControllerReceiver (&RTC);在该函数中,发生了以下事件:      while (I2C_getStopConditionStatus (base)&& quertCount <= 3U);

    [/报价]

    这意味着没有检测到 STOP 条件。 您是否确保总线扫描函数为提供的地址返回成功? 否则、可能是 器件未正确通信或 使用了不正确的地址。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    可通过 I2C_setConfig 函数完成此操作,该函数将配置 I2C 外设以进行发送或接收。 你正在寻找的总线扫描功能只是为了扫描总线以查看连接什么,它不会发送/接收任何东西(我相信它不应该)。[/报价]

    您是说此函数会自动设置 r/w 位吗? 所以、我不必设置 r/w 位、正确吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的意思是此函数自动设置 r/w 位吗? 因此,我不必设置 r/w 位,它是否正确?

    正确、I2C 外设是一个外设、因此在您设置寄存器时它会为您执行许多此类配置(在本例中、 I2C_setConfig 函数将设置 TRx 位以确定它是发送还是接收数据)。 有关详细信息、请参阅参考手册。