您好!
我正在测试这里使用的相同示例: 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);
}
一些有用的提示会非常感谢!