Skip to main content
Associate III
September 16, 2024
Solved

STM32F103RB AF bit of I2C1_SR1 don't work

Hello,
STM32F103RB microcontroller.

Mykola_Levun_1-1726487576667.png

7-bit master transmitter (see Figure 273).
When I send Address then I receive AF bit of I2C_SR1 register equals "1" (Acknowledge failure). But the diagram taken from the oscilloscope shows that after the address there is a Acknowledge bit equal to "0". Which does not correspond to the AF bit in I2C_SR1 register. Why? I also attach the program code.

 

/**
 * @brief This function must be called before using other functions from this file.
 * None.
 * @retval None.
 */
void init_i2c1(void)
{
	RCC->APB2ENR |= 0x00000008;
	RCC->APB1ENR |= 0x00200000;
	GPIOB->CRL &= 0x44000000;
	GPIOB->CRL |= 0xDD000000;
	I2C1->CR2 |= 0x0008;
	I2C1->CCR |= 0x0028;
	I2C1->TRISE |= 0x0009;
	I2C1->CR1 |= 0x0401;
}

/**
 * @brief This function must be called to generate START condition.
 * None.
 * @retval Execution result code:
 * 			- 0: Not successfully.
 * 			- 1: Successfully.
 */
unsigned char start_i2c1(void)
{
	unsigned int temp = 0;
	I2C1->CR1 |= 0x0100;
	/*while ((I2C1->SR1 & 0x0001) == 0x0000)
	 ;*/
	temp = 0;
	while (temp <= 10000)
	{
		if ((I2C1->SR1 & 0x0001) == 0x0001)
		{
			return 0x01;
		}
		else
		{
			temp++;
		}
	}
	return 0x00;
}

/**
 * @brief This function must be called to send address byte.
 * address: Slave device address.
 * mode: Operation mode.
 * 				- 0: Write.
 * 				- 1: Read.
 * @retval Execution result code:
 * 			- 0: Not successfully.
 * 			- 1: Successfully.
 */
unsigned char send_address_byte(unsigned char address, unsigned char mode)
{
	unsigned int temp = 0;
	if ((mode & 0x01) == 0x01)
	{
		address |= 0x01;
	}
	else
	{
		address &= ~0x01;
	}
	I2C1->DR = address;
	temp = 0;
	while (temp <= 10000)
	{
		if ((I2C1->SR1 & 0x0400) == 0x0400)
		{
			I2C1->SR1 &= ~0x0400;
			I2C1->CR1 |= 0x0200;
			return 0x00;
		}
		else
		{
			temp++;
		}
	}
	I2C1->CR1 |= 0x0200;
	return 0x01;
}

 



 

int main(void)
{
	int temp = 0;
	init_i2c1();
	while(1)
	{
		if (start_i2c1() == 0x01)
		{
			if (send_address_byte(0x90, 0x00) == 0x01)
			{
				temp++;
			}
			else
			{
				temp++;
			}
		}
		else
		{
			temp++;
		}
	}
}

 

This topic has been closed for replies.
Mykola_LevunBest answer
Associate III
October 3, 2024

Hello,
This STM32F103RB is genuine.
I was solving this problem. There is the Figure 32 (I2C bus AC waveforms and measurement circuit) in the STM32F103RB datasheeet (see Figure 1 in this text). STM indicate that Rp resistor must be equal to 4.7k, but not indicate resistance of Rs. I have put Rp equal to 4.7k that is right. Also, I have put Rs equal to 4.7k that is wrong. Rs must be equal to 100 Ohm. Because the Rs value was not correct, I2C periphery of STM32F103RB did'n work properly.
As a result, Rp must be equal to 4.7k and Rs equal to 100 Ohm and not Rs equal to 4,7k.
Figure 1

Mykola_Levun_0-1727934102790.png

 

4 replies

waclawek.jan
Super User
September 16, 2024

> When I send Address then I receive AF bit of I2C_SR1 register equals "1" (Acknowledge failure).

How do you know?

> But the diagram taken from the oscilloscope shows that after the address there is a Acknowledge bit equal to "0".

Show.

JW

Associate III
September 16, 2024

I'm looking through the debugger.

Mykola_Levun_0-1726493338529.png

This loop constantly returns 0x00 (see above is the full code).

while (temp <= 10000)
	{
		if ((I2C1->SR1 & 0x0400) == 0x0400)
		{
			I2C1->SR1 &= ~0x0400;
			I2C1->CR1 |= 0x0200;
			return 0x00;
		}
		else
		{
			temp++;
		}
	}

 

waclawek.jan
Super User
September 16, 2024

It's humm for me. Sorry, I have no answers.

JW

PS. Is this a genuine STM32F103, or a clone?

 

Mykola_LevunAuthorBest answer
Associate III
October 3, 2024

Hello,
This STM32F103RB is genuine.
I was solving this problem. There is the Figure 32 (I2C bus AC waveforms and measurement circuit) in the STM32F103RB datasheeet (see Figure 1 in this text). STM indicate that Rp resistor must be equal to 4.7k, but not indicate resistance of Rs. I have put Rp equal to 4.7k that is right. Also, I have put Rs equal to 4.7k that is wrong. Rs must be equal to 100 Ohm. Because the Rs value was not correct, I2C periphery of STM32F103RB did'n work properly.
As a result, Rp must be equal to 4.7k and Rs equal to 100 Ohm and not Rs equal to 4,7k.
Figure 1

Mykola_Levun_0-1727934102790.png