cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0 uses I2C to send the slave address, it gets stuck at ISR=0x8001.

Tokit
Associate II

STM32L051K8U6 

Tokit_1-1710815396009.png

The code always gets stuck here

Tokit_0-1710815209928.png

This situation is likely due to the slave not responding to the address, but with the same hardware, using software-simulated I2C communication works perfectly fine.I have already checked, the slave addresses sent out by both sets of code are the same.

I2C has been enabled with a frequency of 200kHz,The pull-up resistor is 2.7kΩ.and the initialization code was generated by CubeMX. I don't think there should be any issues with this part

The software I2C partial code below

#define I2C_SCL_Pin  LL_GPIO_PIN_6
#define I2C_SDA_Pin  LL_GPIO_PIN_7

#define VL_SDA_IN()  LL_GPIO_SetPinMode(GPIOB, I2C_SDA_Pin, LL_GPIO_MODE_INPUT)
#define VL_SDA_OUT() LL_GPIO_SetPinMode(GPIOB, I2C_SDA_Pin, LL_GPIO_MODE_OUTPUT)

#define I2C_SDA_SET  LL_GPIO_SetOutputPin(GPIOB, I2C_SDA_Pin)
#define I2C_SDA_CLR  LL_GPIO_ResetOutputPin(GPIOB, I2C_SDA_Pin)
#define I2C_SCL_SET  LL_GPIO_SetOutputPin(GPIOB, I2C_SCL_Pin)
#define I2C_SCL_CLR  LL_GPIO_ResetOutputPin(GPIOB, I2C_SCL_Pin)
#define I2C_SDA_READ (((GPIOB->IDR)&I2C_SDA_Pin)?1:0)

uint8_t VL_IIC_Read_nByte(uint8_t SlaveAddress, uint8_t REG_Address,uint16_t len,uint8_t *buf)
{
	VL_IIC_Start();
	VL_IIC_Send_Byte(SlaveAddress);
	if(VL_IIC_Wait_Ack()) 
	{
		VL_IIC_Stop();
		return 1;
	}
	VL_IIC_Send_Byte(REG_Address);
	VL_IIC_Wait_Ack();

	VL_IIC_Start();
	VL_IIC_Send_Byte(SlaveAddress|0x01);
	VL_IIC_Wait_Ack();
	while(len)
	{
		if(len==1)
		{
			*buf = VL_IIC_Read_Byte(0);
		}
		else
		{
			*buf = VL_IIC_Read_Byte(1);
		}
		buf++;
		len--;
	}
  VL_IIC_Ack();
	VL_IIC_Stop();
	return 0;
}

This is the first I2C read-write function called in my program. As you can see, the function names are the same, and I only replaced the underlying read-write operations. Therefore, the issue can be localized to the underlying I2C communication.

1 ACCEPTED SOLUTION

Accepted Solutions

You are expecting things to happen that aren't grounded in the reference manual. Look through the reference manual to understand when TC is set. It is very explicit about it. Or look at HAL code to understand how it's done there.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

8 REPLIES 8
Danish1
Lead II

You say “the pull-up resistor is 2.7k”. Please clarify if there is just the one resistor (on SDA) or if there are two - one on SCL and the other on SDA.

From the code you posted, it is not clear if you have implemented open-drain driving for SCL and SDA when you do I2C in software. This is a fundamental aspect of I2C, which requires pull-ups on both SCL and SDA. You might wonder why the standard has SCL open-drain. This is to allow multi-master operations and also let a peripheral stretch / slow-down the clock where necessary.

TDK
Guru

You're in the middle of a transfer. The master is holding SCL low while waiting for you to send it data in which case BSY will stay set. Why are you waiting for it or expecting it to be cleared?

If you feel a post has answered your question, please click "Accept as Solution".
Tokit
Associate II

Thanks for replay

I want to wait for it to send the slave address, or does he wait until he sends the first data before appending the slave address? Now I've commented out the code waiting for busy. But now it gets stuck waiting for the data to be sent, which is very strange, and I can't understand it.

Tokit_0-1710826667037.pngTokit_1-1710826684053.png

If it has already finished sending and automatically stopped, why isn't the TC flag set?

Thanks for replay

Of course,both of SCL and SDA have pull up res.The software version of the code is modified from the hardware I2C code,PIN and I2C initialization are the same as in the hardware version.I simply set the pins to OUTPUT mode beacause they have already be initialized to opendrain during I2C initialization.if there's something wrong with pull-up,software i2c won't work either

Observe waveforms on SCL and SDA using oscilloscope/logic analyzer (LA).

JW

Is timing of emulation the same as HW I2C? Perhaps the frequency is too high in combination with the high capacity of the cabling.

You are expecting things to happen that aren't grounded in the reference manual. Look through the reference manual to understand when TC is set. It is very explicit about it. Or look at HAL code to understand how it's done there.

If you feel a post has answered your question, please click "Accept as Solution".

@ONadr.1 wrote:

Perhaps the frequency is too high in combination with the high capacity of the cabling.


As @waclawek.jan suggested, an oscilloscope would quickly identify such issues ...