1. 程式人生 > >計算模擬I2C的傳輸速率

計算模擬I2C的傳輸速率

在編寫I2C器件的驅動時,經常會看到手冊中提及該器件的最高傳輸速率,如:


而在配置暫存器實現I2C中也是需要配置I2C的傳輸速率,如:


但模擬I2C的速率該如何計算?

首先一般I2C速率的單位是kbit/s,I2C傳輸速率的定義:每秒傳輸的位元位數。
先把程式碼貼出來(這裡的程式碼在之前的日誌中貼出來過):

#define I2C_DELAY()  I2CSysCtlDelay(30)	//!<I2C速率約為237Kb/s(若為40,則速率約為178Kb/s)


/*
 * @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++){//!<傳送8bit資料
		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();//!<延時讀取ACK響應
	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