計算模擬I2C的傳輸速率
阿新 • • 發佈:2019-02-15
在編寫I2C器件的驅動時,經常會看到手冊中提及該器件的最高傳輸速率,如:
而在配置暫存器實現I2C中也是需要配置I2C的傳輸速率,如:
但模擬I2C的速率該如何計算?
首先一般I2C速率的單位是kbit/s,I2C傳輸速率的定義:每秒傳輸的位元位數。
先把程式碼貼出來(這裡的程式碼在之前的日誌中貼出來過):
我們計算的方法是:首先計算模擬I2C傳送一個位元組所需要多長時間,之後除以8,以算出傳送一位需要多長時間。#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; }
由於暫存器操作的時間可忽略不計,故主要計算其中的延時時間。
在開始訊號 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,
所以
綜上,傳送一個位元組所需要 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