×
嵌入式 > 技术百科 > 详情

计算模拟I2C的传输速率

发布时间:2022-04-12 发布时间:
|

在编写I2C器件的驱动时,经常会看到手册中提及该器件的最高传输速率,如:



而在配置寄存器实现I2C中也是需要配置I2C的传输速率,如:



但模拟I2C的速率该如何计算?


首先一般I2C速率的单位是kbit/s,I2C传输速率的定义:每秒传输的比特位数。

先把代码贴出来(这里的代码在之前的日志中贴出来过):



#define I2C_DELAY()  I2CSysCtlDelay(30) //!

 

 

/*

 * @brief  SysCtlDelay

 * @param  ulCount 延时值,必须大于0

 * @retval (3/(120M))s = 40MHz

 */

void I2CSysCtlDelay(unsigned long ulCount)

{


   __asm("    subs    r0, #1\n"

         "    bne.n   I2CSysCtlDelay\n"

         "    bx      lr");

   

}

 

/*!

 *  @brief I2C1起始信号

 *  @param none

 *  @return none

 *  @note 数据:D  时钟:C  高:H  低:L  输出:O  输入:I  延时:_

 *  @note DOCO_DHCH_DL__CL

 */

void I2C1_Start(void)

{

    I2C1_SDA_OUT(); 

    I2C1_SCL_OUT(); 

    I2C_DELAY();

    I2C1_SDA_H();  

    I2C1_SCL_H(); 

    I2C_DELAY();  

    I2C1_SDA_L();

    I2C_DELAY();

    I2C_DELAY();

    I2C1_SCL_L();

}

 

/*!

 *  @brief I2C1结束信号

 *  @param none

 *  @return none

 *  @note 数据:D  时钟:C  高:H  低:L  输出:O  输入:I  延时:_

 *  @note DOCO_DLCL_CH___DH__

 */

void I2C1_Stop(void)

{

    I2C1_SDA_OUT(); 

    I2C1_SCL_OUT();

    I2C1_SDA_L();  

    I2C1_SCL_L(); 

    I2C_DELAY();

    I2C1_SCL_H();

    I2C_DELAY();  

    I2C_DELAY();

    I2C_DELAY();

    I2C1_SDA_H();

    I2C_DELAY();

    I2C_DELAY();

}

 

/*!

 *  @brief 主机向I2C1总线发送一个字节

 *  @param data:数据

 *  @return 0:失败  1:成功

 *  @note 数据:D  时钟:C  高:H  低:L  输出:O  输入:I  延时:_  读取:R

 *  @note (_DH/L_CH__CL)*8_DHDI_CH_DR_CL_DO

 */

uint8 I2C1_Send_byte(uint8 data)

{

uint8 k;

for(k=0;k<8;k++){//!

I2C_DELAY();

if(data&0x80){

I2C1_SDA_H();

}else{

I2C1_SDA_L();

}

data=data<<1;

I2C_DELAY();

I2C1_SCL_H();

I2C_DELAY();

I2C_DELAY();

I2C1_SCL_L();

}

I2C_DELAY();//!

I2C1_SDA_H();

  

I2C1_SDA_IN();//!

I2C_DELAY();

I2C1_SCL_H();   

I2C_DELAY();

  

k=I2C1_SDA_READ();//读取ACK/NACK

I2C_DELAY();

I2C1_SCL_L();

I2C_DELAY();

I2C1_SDA_OUT();

if(k){ ////NACK响应

return 0;

}

return 1;

我们计算的方法是:首先计算模拟I2C发送一个字节所需要多长时间,之后除以8,以算出发送一位需要多长时间。


 由于寄存器操作的时间可忽略不计,故主要计算其中的延时时间。

在开始信号 start()中,含有 4个delay,设1个delay占用的时间为n(之后再计算),则一个start()占用4n。

在停止信号stop()中,含有 6个delay,则一个stop()占用6n。

发送一个字节中有 8* 4n+5n,占用37n。


一般最简单的I2C时序是,开始->发送一个字节->结束,故发送一个字节的总时间为47n. 


然后准备计算n,一个delay函数执行一次需要三个时钟周期,当前使用的时钟为120M,故执行一个delay占用[1/(40M)]s,

所以 I2CSysCtlDelay(30)所占用3/4 us.


综上,发送一个字节所需要 35.25us=141/4 us,1bit需要141/32 us,所以I2C的发送速率为32/141 Mbit/s≈227kbit/s

同理可以算出接收速率,然后选一个较小值,就可以当做当前模拟I2C的速率,注意这里的值也是大致的值,做参考。


另外若不清楚当前使用的时钟是否确为120M,可以使用以下简单暴力的方法哦:

在main函数中,采用点灯计时:


while(1)

{

    I2CSysCtlDelay(1000*10000);

    LED_ON();

    I2CSysCtlDelay(1000*10000);

    LED_OFF(); 



通过计时,LED灯亮灭十下约为5s。

故函数执行一次,所用的时间为5/10/(1000*10000*2)  = 1/(40M) s

所以时钟周期为 1/(40M)/3 = 1/(120M)s,所以时钟频率为120M


 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Semtech的LoRa技术携手Chipsafer将牧场连接至云端