STM32硬件I2C时序配置及最高速度测试详解
以前一直用STM32cubemx配置得I2C,在cubemx里最高只能给到1MHz,然后那个时序又不怎么看得懂,于是就一度以为最高只能1MHz。
今天忙里偷闲研究了下I2C的timing寄存器
操作平台STM32G431,使用LL库
先贴手册
这是一个32bit寄存器
bit【0~7】SCLL,SCL低电平时间
bit【8~15】SCLH,SCL高电平时间
bit【16~19】SDADEL,数据保持时间,在SCL拉低多久后SDA可以变化
bit【20~23】SCLDEL,数据设置时间,在SDA上加载本次传输的0/1后多久SCL拉高(通知从机数据有效)
bit【28~31】PRESC,时钟源预分频
SCL高低电平时间很好理解
SDADEL和SCLDEL可以参考下图我框出来的,I2C在SCL高电平时数据有效,这个时间主要就是为了防止SCL高电平时SDA数据还没准备好,可以想象大部分情况下给到0其实也不会有问题,但原则上还是至少给1避免不稳定因素
关于timing参数的最小时间单位,我的理解是时钟树配给I2C的频率除去预分频就是了 ,例如160M主频如果不分频,那么timing的数字就表示多少个(1/160M)秒,但实测并不是这样,似乎时钟树提供给I2C的时钟首先已经被分频了一次,大约已经给到了10分频。但是手册上大概看了看没发现类似的说明,希望有高手给解释一下。
根据手册,写了一段代码,用来设置I2C时序
void bsp_i2c_init(void)
{
LL_I2C_Disable(I2C1);
uint16_t PRESC = 0x0; // 时间预分频器
uint16_t SCLDEL = 0x1; // 数据设置时间
uint16_t SDADEL = 0x1; // 数据保持时间
uint16_t SCLH = 0x04; // SCL 高电平时间
uint16_t SCLL = 0x02; // SCL 低电平时间
uint32_t register_value = (PRESC << 28) | (SCLDEL << 20) | (SDADEL << 16) | (SCLH << 8) | SCLL;
LL_I2C_SetTiming(I2C1, register_value);
LL_I2C_Enable(I2C1);
}
这里是我已经调整过,在2k外部上拉加内部上拉的情况下,给到的最快时序。其实这个时候已经明显出现SCL上升沿不理想的情况了。具体表现为以1.8V为触发阈值,给到了4的高电平时间实际和给到2的低电平时间脉宽一样,这个偏差的时间就是因为SCL拉高了之后上升沿太缓导致到达1.8V需要一段时间。示波器不在手头也没法测具体的压摆率数据。
测试结果如图,从机为QMC5883地磁传感器,通信是成功的,频率可以到3.12M。所以说硬件I2C也是可以很快的,如果是软件模拟I2C一方面未必能到这个速度,即便到了对于高低电平的持续持续时间也不如硬件的稳定易控。除非在推挽输出和输入之间切换。
作者:ChTomt