2021-11-19 02:28 PM
Thanks!
2021-11-20 02:58 PM
Please see this thread. Few last replies from Jan W.
2021-11-20 05:34 PM
I2C timing is a bit opaque. I recommend extrapolating from the RM timing table examples. The RM goes into lots of details, and ultimately suggests using Cube. Of note, the example tables are for the same set of APB freqs, on a range of STM32 devices. So, having a 24Mhz etc clock makes sense for some variatns, but it uses the same table for H7, which may have a 200Mhz APB clock!
2021-11-21 04:12 AM
Even on H7 running at 500 MHz the I2C source clock can come from multiple sources, with divisors. You can easily find one close to 48 MHz.
2021-11-22 06:05 PM
Thanks for all your reply. I am a beginner. Can you just kindly give me a number i can use for the i2c timing setting? or give me the best number of Rise time and Fall time?
BTW, the speed of usb-i2c i use is 400k and the evaluation board i2c clock frequency is 72M.
I also attach the " I2C_Timing_Configuration_V1.0.1.xls" here if you need.
Thanks a million!
2021-11-22 07:53 PM
I recommend to use STM32CubeIDE, it automatically creates timingR register value depending on clock configuration.
Then you can extract individual values and perform fine tuning based on reference manual. Let's say STM32CubeIDE gave timingR=0x40008EFF.
We can use some tool, for example SpeqMath to perform operation on bits and extract all values:
' Getting register values from timingR register
timingR=0x40008EFF;
test=Hex(timingR & 0xF0FFFFFF)
test = 0x40008EFF
SCLL=Hex(timingR & 0xFF)
SCLL = 0xFF
SCLH=Hex((timingR>>8) & 0xFF)
SCLH = 0x8E
SDADEL=Hex((timingR>>16)&(0b1111))
SDADEL = 0x0
SCLDEL=Hex((timingR>>20)&(0b1111))
SCLDEL = 0x0
PRESC=Hex((timingR>>28)&(0b1111))
PRESC = 0x4
Here is example of calculations for the table provided in reference manual:
' Calculation example 400khz i2c on 48mhz clk
i2cclk=48*10^6;
PRESC=5;
SCLL=0x9;
SCLH=0x3;
SDADEL=0x3;
SCLDEL=0x3;
i2c_t=1/i2cclk
i2c_t = 2.083333e-8
t_PRESC=(PRESC+1)*i2c_t*10^9 'ns
t_PRESC = 125.000000
t_SCLDEL=(SCLDEL+1)*t_PRESC 'ns
t_SCLDEL = 500.000000
t_SDADEL=SDADEL*t_PRESC 'ns
t_SDADEL = 375.000000
t_SCLH=(SCLH+1)*t_PRESC 'ns
t_SCLH = 500.000000
t_SCLL=(SCLL+1)*t_PRESC 'ns
t_SCLL = 1250.000000
Actual I2C frequency will differ because of clock stretching, digital filter, etc.:
t_SYNC1=7*i2c_t; // see actual values in RM
t_SYNC2=7*i2c_t;
t_SYNC1+t_SYNC2;
digitalFilter=0;
(SCLH+SCLL)*i2c_t;
t_SCL=t_SYNC1+t_SYNC2+((SCLH+1)+(SCLL+1))*(PRESC+1)*i2c_t+2*digitalFilter*i2c_t;
Hope this helps