1194980_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

1194980_zh-CN

1194980_zh-CN

I2C 通信问题

大家好,


我遇到了 QN9090 与温度传感器 TM116 之间的 I2C 通信问题。

这是我第一次尝试使用 I2C 的 SDK,我不确定一切是否正确。

没有从属设备读取的示例,这里甚至没有一个话题。

根据现有的例子,我有了以下内容:


I2C_MasterGetDefaultConfig(&masterConfig);

/* Change the default baudrate configuration */
masterConfig.baudRate_Bps = I2C_BAUDRATE;

/* Initialize the I2C master peripheral */
I2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);

/* prepare for reading
 * 1. write register 2. read 2 bytes
 */
I2C_MasterStart(EXAMPLE_I2C_MASTER, I2C_SLAVE_ADDR_7BIT, kI2C_Write);
g_master_buff[0] = 0x00U;

reVal = I2C_MasterWriteBlocking(EXAMPLE_I2C_MASTER, g_master_buff, 1, kI2C_TransferDefaultFlag);
if (reVal != kStatus_Success)
{
	PRINTF(printf("Write Error! %d\n", reVal));
}
else
{
	PRINTF("Write Success\n");
}
I2C_MasterStop(EXAMPLE_I2C_MASTER);

以上工作正常。写入不会返回错误。

阅读部分从未成功:

I2C_MasterStart(EXAMPLE_I2C_MASTER, I2C_SLAVE_ADDR_7BIT, kI2C_Read);
int32_t i2c_status = I2C_MasterReadBlocking(I2C_SLAVE_ADDR_7BIT, g_slave_buff, 2, kI2C_TransferDefaultFlag);
if (i2c_status != kStatus_Success)
{
	PRINTF(printf("Read Error! %d\n", i2c_status));
}
else
{
	PRINTF("Read Success\n");
}

我遇到 i2c_status 错误 2605 - kStatus_I2C_ArbitrationLost 错误。

我相信可能会有遗漏。尽管没有错误,但不确定书写是否正常。

过几天我会用示波器检查一下。


谁能指出可能的解决方案?

谢谢!

Mike

QNRe: I2C communication issue

I2C_MasterTransferBlocking 函数可用于接收。代码示例:

static status_t I2C_Write(handle_t *handle, uint16_t memAddr,
                                     const uint8_t *data, uint32_t dataLen)
{
    i2c_master_transfer_t xfer;
    status_t status;

    memset(&xfer, 0, sizeof(xfer));

    xfer.slaveAddress   = handle->slaveAddress;
    xfer.direction      = kI2C_Write;
    xfer.subaddress     = (uint32_t)memAddr;
    xfer.subaddressSize = ADDR_SIZE;
    xfer.data           = (uint8_t *)data;
    xfer.dataSize       = dataLen;
    xfer.flags          = kI2C_TransferDefaultFlag;

    status = I2C_MasterTransferBlocking(handle->i2cBase, &xfer);

    return ConvertStatus(status);
}

关键点是"方向"

SDK I2C sample code to read LM75 on the LPCXpresso804 board

好的,这是我以前能够使用 SDK 的 I2C 库与 OM40001 LpcXpresso804 开发板上的 LM75 通信的代码。

创建项目并使用配置工具启用外设信号,使其包括 I2C0。 然后将 PIO0_7 设置为引脚标识符 I2C_SDA,将 PIO0_14 设置为引脚标识符 I2C_SCL。

首先确保包含 i2c 头文件。 在制作项目并选择 I2C 引脚时,可能已经添加了这一功能:

#include "fsl_i2c.h"  // For I2C calls

在 "包括 "之后,添加这个球状物:

#define I2C_MASTER_BASE    			(I2C0_BASE)
#define I2C_MASTER_CLOCK_FREQUENCY	(12000000)
#define I2C_MASTER 					((I2C_Type *)I2C_MASTER_BASE)
#define I2C_BAUDRATE               	100000U
#define I2C_DATA_LENGTH				16U  // Used to set the size of the buffers

i2c_master_config_t masterConfig;
uint8_t g_master_txBuff[I2C_DATA_LENGTH];
uint8_t g_master_rxBuff[I2C_DATA_LENGTH];

// The OM40001 documentation says: NXP LM75BDP temperature sensor
// JP4 and JP23 need to be installed, which they are by default
// Temperature sensor (LM75, circuit ref U7)
// The I2C address is 0x1001100.
// From I2C_temperature_main.c
//#define LM75_ADDR			(0x90 >> 1) // = 0x48 72d ('H')
#define LM75_ADDR			0x48  // Should be the same as (0x90 >> 1)
#define LM75_CONFIG			0x01
#define LM75_TEMPERATURE	0x00

int32_t init_LM75(void);
uint32_t read_LM75(void);

在 BOARD_InitBootPeripherals() 之后的 main() 中,要添加这个 glob:

    BOARD_InitI2CPins();  // Enable the I2C pins
    CLOCK_Select(kI2C0_Clk_From_MainClk);  // Select the main clock as the source clock for I2C0
    I2C_MasterGetDefaultConfig(&masterConfig);  // Load the default values into masterConfig
    masterConfig.baudRate_Bps = I2C_BAUDRATE;  // Change the default baudrate in the configuration to our value
    I2C_MasterInit(I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);  // Initialize the I2C master peripheral using our masterConfig
    init_LM75();  // Initialize the sensor

我创建了两个与 LM75 有关的函数。 init_LM75()和read_LM75()。 它们在这里:

int32_t init_LM75(void)
{
    status_t retVal = kStatus_Fail;

    // The write only process is done by:
    //  I2C_MasterStart()
    //  I2C_MasterWriteBlocking() with kI2C_TransferDefaultFlag flag
    //  I2C_MasterStop()
	if (kStatus_Success == I2C_MasterStart(I2C_MASTER, LM75_ADDR, kI2C_Write))
    {
    	g_master_txBuff[0] = LM75_CONFIG;
    	g_master_txBuff[1] = 0x00;  // Set the default operating mode

        retVal = I2C_MasterWriteBlocking(I2C_MASTER, g_master_txBuff, 2, kI2C_TransferDefaultFlag);

        if (retVal != kStatus_Success)
        {
            return -1;
        }

        retVal = I2C_MasterStop(I2C_MASTER);

        if (retVal != kStatus_Success)
        {
            return -1;
        }

        retVal = kStatus_Success;
    }

	return(retVal);
}


uint32_t read_LM75(void)
{
    status_t retVal = kStatus_Fail;
    uint8_t deviceAddress = LM75_TEMPERATURE;

    memset(g_master_rxBuff, 0, I2C_DATA_LENGTH);

    // The combination write/read is done by:
    //  I2C_MasterStart()
    //  I2C_MasterWriteBlocking() with kI2C_TransferNoStopFlag flag
    //  I2C_MasterRepeatedStart()
    //  I2C_MasterReadBlocking() with kI2C_TransferDefaultFlag flag
    //  I2C_MasterStop()
	if (kStatus_Success == I2C_MasterStart(I2C_MASTER, LM75_ADDR, kI2C_Write))
	{
		// We're writing one byte, the register value of 0x00 to immediately read temperature data from.
		// We set the flag to kI2C_TransferNoStopFlag since we're doing a read right after this.
		retVal = I2C_MasterWriteBlocking(I2C_MASTER, &deviceAddress, 1, kI2C_TransferNoStopFlag);

		if (retVal != kStatus_Success)
		{
			return -1;
		}

		retVal = I2C_MasterRepeatedStart(I2C_MASTER, LM75_ADDR, kI2C_Read);

		if (retVal != kStatus_Success)
		{
			return -1;
		}

		// Now we're reading two bytes of the temperature data from the slave device, into g_master_rxBuff
		retVal = I2C_MasterReadBlocking(I2C_MASTER, g_master_rxBuff, 2, kI2C_TransferDefaultFlag);

		if (retVal != kStatus_Success)
		{
			return -1;
		}

		retVal = I2C_MasterStop(I2C_MASTER);

		if (retVal != kStatus_Success)
		{
			return -1;
		}
	}

	uint32_t temperatureValue = 0;

	// NXP's LM75B data sheet shows the format of the data https://www.nxp.com/docs/en/data-sheet/LM75B.pdf
	if ((g_master_rxBuff[0] & 0x80) > 0) {  // This is the sign bit
		temperatureValue = 0xffffff00;
	}

	temperatureValue |= (g_master_rxBuff[0] & 0x7f) << 1;
	temperatureValue |= ((g_master_rxBuff[1] >> 7) & 1);

	// Since we're not using the half degrees, just shift right by one and lose that piece of data
	temperatureValue = temperatureValue >> 1;

	return(temperatureValue);
}

我们在main()中添加的代码已经调用了init_LM75(),您只需在要读取温度时调用read_LM75()。 (您可能不需要调用init_LM75(),因为传感器似乎一开始就以正确的模式启动)。我的演示程序只是从一秒间隔的SysTick_Handler()调用read_LM75( ),并使用该代码显示数值:

	int32_t temperatureReading = read_LM75();
	char console_string[128];

	// Bit 16 is the sign (1 is negative, 0 is positive) after the temperature conversion
	if (temperatureReading & 0x10000) {
		snprintf(console_string, 128, "Current temperature is -%d degrees C.\r\n", (temperatureReading & 0xFFFF));
	}
	else {
		uint16_t temperature_farenheit = (temperatureReading * 9 / 5) + 32;  // Create the farenheit temperature value for positive temperatures
		snprintf(console_string, 128, "Current temperature is %d degrees C and %d degrees F.\r\n", temperatureReading, temperature_farenheit);
	}

	PutTerminalString(USART0, (unsigned char *)console_string);

我没有做太多的返回值检查,但你应该明白我的意思。 上面的PutTerminalString()函数只是我用来在 USART0 端口上发送字符串的一个函数。 将其替换为您正在使用的诊断打印。

尽情享受!

Re: I2C communication issue

当然,在发布这篇文章十分钟后,我想出了如何使用 lpcxpresso804_lpc_i2c_polling 示例 项目中的代码并对其进行修改以正确读取板载 L M75 传感器的温度...


我稍后会整理好我的代码并发布在这里,希望能帮助其他想这样做的人。

Re: I2C communication issue

我知道这已经有一段时间了,但你有没有可能分享一下你的代码,因为我也注意到没有一个简单的示例可以使用 API(fsl_i2c)来做类似的事情:

从 Slave 0x78 的寄存器 0x01 读取 2 字节。

我正在尝试读取 OM40001 lpcXpresso804 板上的 LM75 传感器,尽管我的示例 " i2c_Temperature " 项目正在运行,但该项目没有使用 fsl_i2c SDK API 调用。

当我尝试使用I2C_MasterWriteBlocking()和I2C_MasterReadBlocking()调用来实现它时,I2C_MasterReadBlocking() 调用失败了。

它没有获得 I2C_STAT_MSTCODE_RXREADY 的master_state值(值 = 1),因此无法读出数据,而是看到了一个值 2,这使得代码落入默认情况:情况,并设置err = kStatus_I2C_UnexpectedState;

有人有一个简单的 I2C 代码示例,它只使用来自 fsl_i2c SDK API 的 i 2c_MasterWriteBlocking () 和 i 2c_masterReadBlocking () 调用从属 SPI 设备读取两个字节 吗?

lpcxpresso804_lpc_i2c_polling示例项目过于通用。 恩智浦为什么不创建示例项目来与I2C设备(LM75)通信,该设备位于该项目命名的实际电路板上,据说也是一个项目?


Re: I2C communication issue

大家好,

这不是从从属设备读回数据的正确方法。

令人失望的是,SDK 中没有类似的简单示例:

从 Slave 0x78 的寄存器 0x01 读取 2 字节。

不过,我花了一些时间才弄明白该怎么做,现在一切正常。

干杯

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎03-26-2026 05:30 AM
更新者: