Skip to main content
Associate II
September 13, 2025
Question

STM32F407 I2C ADDR bit not being set

  • September 13, 2025
  • 2 replies
  • 545 views

Hi, Im using my own I2C library but after i write the device adress when i receive SB interrupt the adress bit never seems to be set to 1. I have tried testing it with HAL and it seems to work fine. I would be happy if someone could help

void I2C_EventInterruptHandler(I2C_Com* i2c)
{
	uint8_t temp;

	//Check if event interrupt bit is set
	if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_CR2, 9))
	{
		//Start condition
		if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 0))
		{
			temp = i2c->i2cReg->I2C_SR1;

			i2c->i2cReg->I2C_DR = i2c->deviceAddress;
		}

		//Check for address sent
		if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 1))
		{
			//Check if its in read mode and if rxLegth is 1
			if(i2c->deviceAddress & 1 && i2c->rxLength == 1)
			{
				//Disable ack
				i2c->i2cReg->I2C_CR1 &= ~(1 << 10);
				i2c->i2cReg->I2C_CR1 |= (1 << 9);
			}

			temp = i2c->i2cReg->I2C_SR1;
			temp = i2c->i2cReg->I2C_SR2;
		}

		//Check for tx/rx interrupt bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_CR2, 10))
		{
			//tx interrupt
			if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 7))
			{
				I2C_TxInterruptHandler(i2c);
			}

			//rx interrupt
			if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 6))
			{
				I2C_RxInterruptHandler(i2c);
			}
		}

		//Check for BFT bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 2))
		{
			I2C_BFTInterruptHandler(i2c);
		}


		//Check for Stop bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 4))
		{

		}
	}

}

 

2 replies

Technical Moderator
September 15, 2025

Hello @Defensive ,

Check the SR1 and SR2 registers for the ADDR bit, as mentioned in the RM0090: this bit is cleared by software reading SR1 register followed reading SR2, or by hardware when PE=0. 

Reading I2C_SR2 after reading I2C_SR1 clears the ADDR flag, even if the ADDR flag was set after reading I2C_SR1. Consequently, I2C_SR2 must be read only when ADDR is found set in I2C_SR1 or when the STOPF bit is cleared.

"When your question is answered, please close this topic by clicking ""Accept as Solution"".ThanksImen"
DefensiveAuthor
Associate II
September 21, 2025

Hi, sorry for the late response. The problem is that the ADDR bit is not being sent, which should happen after EV5 (Reading SR1 and writing to DR) the solution you are proposing is for clearing the ADDR bit.

TDK
Super User
September 22, 2025

Is the slave acknowledging the address? Can you show a plot of SDA/SCL that confirms this?

  • If slave does not respond, ADDR should not be set.
  • If slave does respond, ADDR gets set. Reading SR1 from code or from the debugger will clear it.
"If you feel a post has answered your question, please click ""Accept as Solution""."
DefensiveAuthor
Associate II
September 22, 2025

Hi, ACK fault seems to happen with my library but not with HAL.

TDK
Super User
September 22, 2025

Read SR1 once at the start of the handler and process each bit in there that is set. Look at HAL library for how it's done correctly. Don't read it and set it to a variable ad hoc. That has consequences.

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