Skip to main content
DJ1
Associate III
September 16, 2023
Solved

How to reduce I2C frequency from 100Khz to 20KHz

  • September 16, 2023
  • 13 replies
  • 5512 views

Hi, i am using STM32F401RE Nucleo board and i want am using I2C channel in standard mode which is upto 100KHz but i due to little long length of communication cable, i want my I2C frequency to be around 20KHz. I am using HSI only as clock source.

This is my function to use I2C channel.

void i2c_init()
{
// I2C3 RCC CLK enable
I2C3_CLK_EN;
// Freq setting 16MHz
I2C3->CR2 |= (16 << 0);
//CCR configuration
I2C3->CCR = 0x50;
// T-Rise configuration
I2C3->TRISE = 0x17;
// Set OAR bit
I2C3->OAR1 |= (1 << 14);
// Peripheral Enable
I2C3->CR1 |= (1 << 0);
}

This topic has been closed for replies.
Best answer by LCE

(1/16 MHz) * 400 = 25 µs which is the high and low time of the SCL pulse, so the SCL period is twice that number Tscl = Thi + Tlo = 50 µs , so fscl = 20 kHz.

You should put a little more effort into understanding the basics and reading the datasheet / ref manual.

In case of doubt, take a pen and paper and draw stuff, that helps me every now and then.

13 replies

AScha.3
Super User
September 16, 2023

so set I2C to 20kHz.  problem ?

If you feel a post has answered your question, please click on " Best Answer ".
DJ1
DJ1Author
Associate III
September 22, 2023

My doubt is how to do frequency calculation for I2C to run at 20KHz using HSI as 16MHz at register level programming.

Issamos
Super User
September 16, 2023

Hello @DJ1 

Usually, when you start the configuration of your ADC values using CubeMX, you find the default value of the I2C clock speed(Hz) is equal to 100000.

c1.PNG

You can change it manually to any value you want(20000) in your case.

c2.PNG

If you are programming using direct register acces,  you have juste to write 400 to the CCR register.

Best regards.

II

 

LCE
Principal II
September 22, 2023

What Issamos said, set CCR to 400, but mind that CR2 FREQ must be set to PCLK1 frequency, not HSI value (okay, that might be the same).

Thigh = CCR * Tpclk1
Tlow = CCR * Tpclk1

with Tpclk1 = 1 / fPCLK1 

DJ1
DJ1Author
Associate III
September 23, 2023

Okay, let me get this right. PCLK (same as HSI 16MHz) and CCR value of 400. 1/16MHz = 62.5ns. 62.5 * 400 = 25x10^-6. I dont get how it is working at 20KHz. Can you please elaborate on that. I want to confirm theoretically that my I2C bus is running at what freq. 

Pavel A.
September 24, 2023

@DJ1 I2C bus does not quite run at certain clock frequency (like SPI for example). Host and devices both monitor and drive the clock wire and this affects the data rate and the form of fronts. This has been discussed in this forum.

LCE
LCEBest answer
Principal II
September 25, 2023

(1/16 MHz) * 400 = 25 µs which is the high and low time of the SCL pulse, so the SCL period is twice that number Tscl = Thi + Tlo = 50 µs , so fscl = 20 kHz.

You should put a little more effort into understanding the basics and reading the datasheet / ref manual.

In case of doubt, take a pen and paper and draw stuff, that helps me every now and then.

DJ1
DJ1Author
Associate III
September 26, 2023

Thanks for the clarity. Well actually i am new to firmware programming and i have just started with STM32F4 and i just could not understand how to identify the frequency of I2C bus. Also i personally prefer register level programming over HAL just for having a better idea of how the things are working in there that is why it takes me a little more to get things done.

LCE
Principal II
September 25, 2023

Anyway, when I hear "cable length" as limiting factor, maybe you should switch data transfer to some differential interface.

Nikita91
Lead II
September 25, 2023

To adapt the I2C to the length of the cable you also have to play on the value of the pull ups.

DJ1
DJ1Author
Associate III
September 26, 2023

Correct. Earlier i was using 4.7K ohms as pull up and now i am using 1K ohms pull-up, usually it works well but sometimes randomly it corrupts the bus. I have 3 slaves connected on the same bus.