2024-03-18 07:39 PM
STM32L051K8U6
The code always gets stuck here
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.
Solved! Go to Solution.
2024-03-19 06:05 AM
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.
2024-03-18 08:16 PM
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.
2024-03-18 08:29 PM
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?
2024-03-18 10:39 PM
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.
If it has already finished sending and automatically stopped, why isn't the TC flag set?
2024-03-19 01:13 AM
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
2024-03-19 02:29 AM
Observe waveforms on SCL and SDA using oscilloscope/logic analyzer (LA).
JW
2024-03-19 03:03 AM
Is timing of emulation the same as HW I2C? Perhaps the frequency is too high in combination with the high capacity of the cabling.
2024-03-19 06:05 AM
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.
2024-03-19 07:55 AM
@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 ...