加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、為什么要用模擬 IIC
    • 二、實現(xiàn)模擬 IIC 的代碼封裝
    • 三、實現(xiàn)模擬 IIC 的簡要說明
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

I2C 驅(qū)動及其 Checksum在 BMS系統(tǒng)中的應(yīng)用

02/27 08:52
3503
閱讀需 11 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

各位好,從今天開始,我的 BMS 電池保護板系列開始聊一下軟件相關(guān)的話題。

首先要關(guān)注的,就是我們的主控芯片如何控制 AFE,如何從 AFE 中讀取到想要的信息,這就離不開 AFE 的通信接口。

AFE 的通信接口有很多種類,比如 Uart,IICSPI 等。其中 Uart 不多見,以 IIC 和 SPI 最為常見,因為這兩個通信協(xié)議是板級通信中最常用的,邏輯簡單,線路少。SPI 有一種菊花鏈模式,這個模式在分布式 BMS 系統(tǒng)中使用普遍,基本各個AFE 廠家都設(shè)計了相應(yīng)的隔離芯片,有保障他們的AFE 可以被更好得使用。我的 Demo 中選擇的 AFE的通信是 IIC 接口,因此這一篇文章主要講述 IIC 的實現(xiàn)。

一、為什么要用模擬 IIC

在我設(shè)計的 Demo 中,我選擇了使用 IO 口來模擬 IIC 總線,這種選擇經(jīng)歷了很久的思考。首先,這個行業(yè)的伙伴都應(yīng)該了解,早期的 STM32F1 系列 MCU,在 IIC 的硬件設(shè)計上出現(xiàn)過 bug,在中斷打斷 IIC 的時候會導(dǎo)致 IIC 總線無端掛起,或者有些標(biāo)志位無法置位,這是選擇模擬 IIC 的最初的原因。

隨后,經(jīng)過幾個項目的磨煉,這個 IIC 使用模擬 IO 實現(xiàn)還是非選不可的,原因如下:

    在 BMS 項目中,MCU 并不需要特別快速的運行,因為快速響應(yīng)的過流保護短路保護都有 AFE 的硬件直接操作,而讀取 AFE 采樣的數(shù)據(jù)也不需要很頻繁,想想,AFE 的 ADC 普遍的采樣頻率才 5Hz。從多陣列產(chǎn)品開發(fā)的角度,我們經(jīng)常會遇到更換 MCU 的情況,原因不乏成本,缺貨,或者看原廠不順眼等。那么如果使用硬件的 IIC 模式,面對各家的 MCU 的外設(shè)驅(qū)動,還需要一定的學(xué)習(xí)成本和移植風(fēng)險,所以模擬的 IIC 總線直接使用兩個 IO 口和一個簡單的延時函數(shù)即可。

當(dāng)然,硬件 IIC 是有一定的好處的,除了通信的可靠性和容錯性外,相對于模擬 IIC 最大的好處是,在單字節(jié)接收的過程中,我們可以利用中斷來讓 MCU 干些其他事情,也僅此而已。所以,如果你的系統(tǒng)運行頻率很高,CPU 負荷比較高的情況下,肯定首選硬件 IIC。

二、實現(xiàn)模擬 IIC 的代碼封裝

封裝一個代碼,首先要將模塊的功能抽象出來,確定模塊的輸入輸出邏輯,從而確定如何封裝代碼成一個通用的庫,或者說利于移植的模塊。我個人在這一塊有一個整體的思路,就是按照 C++的面向?qū)ο缶幊趟枷雭硪?guī)劃這個類,雖然 C 無法寫成類的形式,但是大體的封裝思想是可以實現(xiàn)的。

首先我們確定,要模擬 IIC 通信總線,需要兩個 IO,這兩個 IO 的通信速率不必太高,因為 IIC 一般的通信速率才 400Khz,現(xiàn)在有一些 1Mhz 的。其次,我們需要一個延時函數(shù),來控制總線的時鐘延時,這個延時最好使用定時器來實現(xiàn),這樣可以調(diào)整出比較好的 IIC 波形,但是這樣會引入一個復(fù)雜的 TIMER 模塊,因此我選擇了代碼延時,只需要確定好主時鐘調(diào)試一次即可。有了上面的兩個 IO 口和延時函數(shù),我們就可以通過控制兩個引腳的高低和時序來模擬 IIC 通信了?,F(xiàn)在,我們已經(jīng)有了足夠的輸入來對模擬 IIC 這個類進行構(gòu)造函數(shù)的編寫。那么,進一步的,我們確定 IIC 這個類的方法和屬性。我們可以把 IIC 總線通信的一些錯誤和狀態(tài)作為屬性來定義,可以讓調(diào)用者通過調(diào)用類的屬性來獲取總線的狀態(tài),是空閑,還是忙狀態(tài)。也可以通過屬性來獲取上一次通信的結(jié)果。其次,對于方法就比較明確了,我們需要查詢忙狀態(tài)的方法,需要最基本的向設(shè)備-地址的讀寫操作,然后再在上層實現(xiàn)多字節(jié)的讀寫操作。

OK,看一下代碼吧

下面是硬件相關(guān)的定義,定義了兩個引腳和兩個延時函數(shù),因為在 IIC 通信中,有控制時鐘的延時和控制時序的延時。

//===========硬件相關(guān)的定義==================================================
#include "cw32l031.h"#include "cw32l031_gpio.h"// I2C的引腳定義#define I2C_SDA_PIN     GPIO_PIN_0#define I2C_SCL_PIN     GPIO_PIN_1
//I2C 的軟件延時,這個需要根據(jù)系統(tǒng)時鐘進行調(diào)整#define    I2C_DELAY_INIT()        u8 _counter = 0;#define    I2C_DELAY()             for( _counter = 0; _counter < 20;  ) {_counter++; }    //100K 重新測試#define    I2C_DELAY_SHORT()       for( _counter = 0; _counter < 10;  ) {_counter++; }    //
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

然后,我們需要定義一些類的屬性,在這里其實就是一些關(guān)于通信模塊的設(shè)置,比如通信的重發(fā)嘗試次數(shù),比如 IIC 總線的狀態(tài)和錯誤標(biāo)志等,這里我們直接使用宏定義來設(shè)定,沒有在提供變量給調(diào)用者進行實例化的時候進行構(gòu)建,因為這在 C語言中就相當(dāng)于脫褲子放屁。

//===============IIC 軟件層相關(guān)(2023.11.11整理)======================================// I2C的一些錯誤宏定義#define    I2C_SUCCESS                 0#define    I2C_ARBITRATION_LOST        0x11#define    I2C_NACK                    0x12#define    I2C_TIMEOUT                 0x13#define    I2C_WRITEFAIL               0x14#define    I2C_CRC                     0x15#define    I2C_OTHER                   0x16

#define    I2C_MAX_ATTEMPTS            1000   //嘗試次數(shù)

最后,我們需要給調(diào)用者提供一個可以調(diào)用的列表,從類的角度看,無非就是構(gòu)造函數(shù),析構(gòu)函數(shù)和幾個方法屬性。這里我們只有一個充當(dāng)構(gòu)造函數(shù)的初始化函數(shù)和兩個方法:讀方法和寫方法。

// I2C對外接口的聲明void i2c_init(void); //I2C的初始化函數(shù)
//多字節(jié)的讀寫u8 i2c_write(u8 addr, u8 reg_addr, u8* txBuff, int count);u8 i2c_read( u8 addr, u8 reg_addr, u8* rxBuff, int count);

好啦,有了以上的一個頭文件,我們就可以使用這個 IIC 模塊,使用的步驟很簡單,先確定 IO 口,然后確定延時函數(shù),最后在我們的初始化過程中將 i2c_init()調(diào)用一下,就可以在我們的系統(tǒng)中使用讀寫方法了。我建了一個微信群,供大家來討論 BMS 相關(guān)技術(shù),為了保證討論質(zhì)量,請先加我的個人微信,備注 “BMS” ,我來拉大家入群。

三、實現(xiàn)模擬 IIC 的簡要說明

當(dāng)我們定義好模擬 IIC 模塊的外觀后,也就是對外接口后,我們就需要思考如何在這個封裝層下來實現(xiàn)邏輯,其實這是一種自頂向下的設(shè)計模式。咱們先把 IO 的拉高拉低變換成總線上的一些狀態(tài),對于 SCL 引線還好,他負責(zé)產(chǎn)生時鐘,可以直接拉高拉低,而對于 SDA 引線就稍微復(fù)雜一些,因為他除了可以拉高拉低的輸出外,還需要從總線上讀取電平。

GPIO_TypeDef* m_I2C_PORT = CW_GPIOA; //定義I2C的IO指針,默認為GPIOB
//I2C的一些信號狀態(tài),不同的硬件需要重新定義#define i2cSetSDA_highZ()    (m_I2C_PORT->ODR |= I2C_SDA_PIN)#define i2cGetSDA()          ((m_I2C_PORT->IDR & I2C_SDA_PIN) ? 1 : 0)#define i2cSetSCL_highZ()    (m_I2C_PORT->ODR |= I2C_SCL_PIN)#define i2cGetSCL()          ((m_I2C_PORT->IDR & I2C_SCL_PIN) ? 1 : 0)#define i2cClearSDA()        (m_I2C_PORT->ODR &= (~I2C_SDA_PIN))#define i2cClearSCL()        (m_I2C_PORT->ODR &= (~I2C_SCL_PIN))

以上,我們將 IO 的狀態(tài)轉(zhuǎn)換成了 IIC 總線上的多態(tài)端口。

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
L6205PD013TR 1 STMicroelectronics DMOS DUAL FULL BRIDGE DRIVER

ECAD模型

下載ECAD模型
$23.25 查看
ADG1419BRMZ-REEL7 1 Analog Devices Inc 2.1 &Omega; On Resistance, ±15 V/+12 V/±5 V, iCMOS SPDT Switch

ECAD模型

下載ECAD模型
$4.03 查看
L9953XPTR 1 STMicroelectronics Door Actuator Driver

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

多年硬件從業(yè)經(jīng)驗,專注分享從研發(fā)到供應(yīng)鏈,再到精益制造過程中的經(jīng)驗和感悟!