一、I2C 協(xié)議簡(jiǎn)介
I2C 通訊協(xié)議(Inter - Integrated Circuit) 也就是IIC;
由Phiilps 公司開(kāi)發(fā)的,它引腳少,硬件實(shí)現(xiàn)簡(jiǎn)單,可擴(kuò)展性強(qiáng),不需要USART、CAN 等通訊協(xié)議的外部收發(fā)設(shè)備。
I2C協(xié)議分為物理層和協(xié)議層。
物理層規(guī)定通訊系統(tǒng)中具有機(jī)械、電子功能部分的特性,確保原始數(shù)據(jù)在物理媒體的傳輸。
協(xié)議層主要規(guī)定通訊邏輯,統(tǒng)一收發(fā)雙方的數(shù)據(jù)打包、解包標(biāo)準(zhǔn)。
簡(jiǎn)單來(lái)說(shuō)物理層規(guī)定我們用嘴巴還是用肢體來(lái)交流,協(xié)議層則規(guī)定我們用中文還是英文來(lái)交流。
I2C 物理層
I2C的物理層有如下特點(diǎn):
(1) 它是一個(gè)支持設(shè)備的總線?!翱偩€”指多個(gè)設(shè)備共用的信號(hào)線。在一個(gè)I2C 通訊總線中,可連接多個(gè)I2C 通訊設(shè)備,支持多個(gè)通訊主機(jī)及多個(gè)通訊從機(jī)。
(2) 一個(gè)I2C 總線只使用兩條總線線路,一條雙向串行數(shù)據(jù)線(SDA) ,一條串行時(shí)鐘線(SCL)。數(shù)據(jù)線即用來(lái)表示數(shù)據(jù),時(shí)鐘線用于數(shù)據(jù)收發(fā)同步。
(3) 每個(gè)連接到總線的設(shè)備都有一個(gè)獨(dú)立的地址,主機(jī)可以利用這個(gè)地址進(jìn)行不同設(shè)備之間的訪問(wèn)。
(4) 總線通過(guò)上拉電阻接到電源。當(dāng)I2C 設(shè)備空閑時(shí),會(huì)輸出高阻態(tài),而當(dāng)所有設(shè)備都空閑,都輸出高阻態(tài)時(shí),由上拉電阻把總線拉成高電平。
(5) 多個(gè)主機(jī)同時(shí)使用總線時(shí),為了防止數(shù)據(jù)沖突,會(huì)利用仲裁方式?jīng)Q定由哪個(gè)設(shè)備占用總線。
(6) 具有三種傳輸模式:標(biāo)準(zhǔn)模式傳輸速率為100kbit/s ,快速模式為400kbit/s ,高速模式下可達(dá)3.4Mbit/s, 但目前大多I2C 設(shè)備尚不支持高速模式。
(7) 連接到相同總線的IC 數(shù)量受到總線的最大電容400pF 限制。
I2C協(xié)議層
I2C 的協(xié)議定義了通訊的起始和停止信號(hào)、數(shù)據(jù)有效性、響應(yīng)、仲裁、時(shí)鐘同步和地址廣播等環(huán)節(jié)。
主機(jī)寫(xiě)數(shù)據(jù)到從機(jī)(寫(xiě)數(shù)據(jù))
廣播完地址,接收到應(yīng)答信號(hào)后,主機(jī)開(kāi)始正式向從機(jī)傳輸數(shù)據(jù)(DATA),數(shù)據(jù)包的大小為8 位,主機(jī)每發(fā)送完一個(gè)字節(jié)數(shù)據(jù);
要等待從機(jī)的應(yīng)答信號(hào)(ACK),重復(fù)這個(gè)過(guò)程,可以向從機(jī)傳輸N 個(gè)數(shù)據(jù),這個(gè)N 沒(méi)有大小限制;
當(dāng)數(shù)據(jù)傳輸結(jié)束時(shí),主機(jī)向從機(jī)發(fā)送一個(gè)停止傳輸信號(hào)§,表示不再傳輸數(shù)據(jù);
主機(jī)由從機(jī)中讀數(shù)據(jù)(讀數(shù)據(jù))
廣播完地址,接收到應(yīng)答信號(hào)后,從機(jī)開(kāi)始向主機(jī)返回?cái)?shù)據(jù)(DATA),數(shù)據(jù)包大小也為8 位,從機(jī)每發(fā)送完一個(gè)數(shù)據(jù);
等待主機(jī)的應(yīng)答信號(hào)(ACK),重復(fù)這個(gè)過(guò)程,可以返回N 個(gè)數(shù)據(jù),這個(gè)N 也沒(méi)有大小限制;
當(dāng)主機(jī)希望停止接收數(shù)據(jù)時(shí),就向從機(jī)返回一個(gè)非應(yīng)答信號(hào)(NACK),則從機(jī)自動(dòng)停止數(shù)據(jù)傳輸。
通訊復(fù)合格式(讀和寫(xiě)數(shù)據(jù))
I2C 通訊常用的是復(fù)合格式;
該傳輸過(guò)程有兩次起始信號(hào)(S)。一般在第一次傳輸中,主機(jī)通過(guò)SLAVE_ADDRESS 尋找到從設(shè)備后,發(fā)送一段“數(shù)據(jù)”,這段數(shù)據(jù)通常用于表示從設(shè)備內(nèi)部的寄存器或存儲(chǔ)器地址(注意區(qū)分它與SLAVE_ADDRESS 的區(qū)別);
在第二次的傳輸中,對(duì)該地址的內(nèi)容進(jìn)行讀或?qū)憽R簿褪钦f(shuō),第一次通訊是告訴從機(jī)讀寫(xiě)地址,第二次則是讀寫(xiě)的實(shí)際內(nèi)容。
通訊的起始和停止信號(hào)
當(dāng)SCL 線是高電平時(shí)SDA線從高電平向低電平切換,這個(gè)情況表示通訊的起始。
當(dāng)SCL 是高電平時(shí)SDA 線由低電平向高電平切換,表示通訊的停止。
起始和停止信號(hào)一般由主機(jī)產(chǎn)生。
數(shù)據(jù)有效性
I2C 使用SDA 信號(hào)線來(lái)傳輸數(shù)據(jù),使用SCL 信號(hào)線進(jìn)行數(shù)據(jù)同步。
SDA 數(shù)據(jù)線在SCL 的每個(gè)時(shí)鐘周期傳輸一位數(shù)據(jù)。
傳輸時(shí),SCL 為高電平的時(shí)候SDA 表示的數(shù)據(jù)有效,即此時(shí)的SDA 為高電平時(shí)表示數(shù)據(jù)“1”,為低電平時(shí)表示數(shù)據(jù)“0”。
當(dāng)SCL 為低電平時(shí),SDA 的數(shù)據(jù)無(wú)效,一般在這個(gè)時(shí)候SDA 進(jìn)行電平切換,為下一次表示數(shù)據(jù)做好準(zhǔn)備。
每次數(shù)據(jù)傳輸都以字節(jié)為單位,每次傳輸?shù)淖止?jié)數(shù)不受限制。
地址及數(shù)據(jù)方向
I2C 總線上的每個(gè)設(shè)備都有自己的獨(dú)立地址,主機(jī)發(fā)起通訊時(shí),通過(guò)SDA 信號(hào)線發(fā)送設(shè)備地址(SLAVE_ADDRESS) 來(lái)查找從機(jī)。
I2C 協(xié)議規(guī)定設(shè)備地址可以是7 位或10 位。
緊跟設(shè)備地址的一個(gè)數(shù)據(jù)位用來(lái)表示數(shù)據(jù)傳輸方向,它是數(shù)據(jù)方向位(R/),第8位或第11 位。數(shù)據(jù)方向位為“1”時(shí)表示主機(jī)由從機(jī)讀數(shù)據(jù),該位為“0”時(shí)表示主機(jī)向從機(jī)寫(xiě)數(shù)據(jù)。
讀數(shù)據(jù)方向時(shí),主機(jī)會(huì)釋放對(duì)SDA 信號(hào)線的控制,由從機(jī)控制SDA 信號(hào)線,主機(jī)接收信號(hào),寫(xiě)數(shù)據(jù)方向時(shí),SDA 由主機(jī)控制,從機(jī)接收信號(hào)。
響應(yīng)
I2C 的數(shù)據(jù)和地址傳輸都帶響應(yīng)。
響應(yīng)包括“應(yīng)答(ACK)”和“非應(yīng)答(NACK)”兩種信號(hào)。
作為數(shù)據(jù)接收端時(shí),當(dāng)設(shè)備(無(wú)論主從機(jī)) 接收到I2C 傳輸?shù)囊粋€(gè)字節(jié)數(shù)據(jù)或地址后,若希望對(duì)方繼續(xù)發(fā)送數(shù)據(jù),則需要向?qū)Ψ桨l(fā)送“應(yīng)答(ACK)”信號(hào),發(fā)送方會(huì)繼續(xù)發(fā)送下一個(gè)數(shù)據(jù);
若接收端希望結(jié)束數(shù)據(jù)傳輸,則向?qū)Ψ桨l(fā)送“非應(yīng)答(NACK)”信號(hào),發(fā)送方接收到該信號(hào)后會(huì)產(chǎn)生一個(gè)停止信號(hào),結(jié)束信號(hào)傳輸。
傳輸時(shí)主機(jī)產(chǎn)生時(shí)鐘,在第9 個(gè)時(shí)鐘時(shí),數(shù)據(jù)發(fā)送端會(huì)釋放SDA 的控制權(quán),由數(shù)據(jù)接收端控制SDA,若SDA 為高電平,表示非應(yīng)答信號(hào)(NACK),低電平表示應(yīng)答信號(hào)(ACK)。
I2C架構(gòu)
STM32 的I2C 外設(shè)可用作通訊的主機(jī)及從機(jī),支持100Kbit/s 和400Kbit/s 的速率,支持7 位、10位設(shè)備地址,支持DMA 數(shù)據(jù)傳輸,并具有數(shù)據(jù)校驗(yàn)功能。它的I2C 外設(shè)還支持SMBus2.0 協(xié)議。
通訊引腳
I2C 的所有硬件架構(gòu)都是根據(jù)圖中左側(cè)SCL 線和SDA 線展開(kāi)的(其中的SMBA 線用于SMBUS 的警告信號(hào),I2C 通訊沒(méi)有使用)。
STM32 芯片有多個(gè)I2C 外設(shè),它們的I2C 通訊信號(hào)引出到不同的GPIO 引腳上,使用時(shí)必須配置到這些指定的引腳。
引腳 | I2C1 | I2C2 |
---|---|---|
SCL | PB6 / PB8(重映射) | PB10 |
SDA | PB7 / PB9(重映射) | PB11 |
時(shí)鐘控制邏輯
SCL 線的時(shí)鐘信號(hào),由I2C 接口根據(jù)時(shí)鐘控制寄存器(CCR) 控制,控制的參數(shù)主要為時(shí)鐘頻率。
配置I2C 的CCR 寄存器可修改通訊速率相關(guān)的參數(shù):
I2C 通訊的 “標(biāo)準(zhǔn)/快速”模式,這兩個(gè)模式分別I2C 對(duì)應(yīng)100/400Kbit/s 的通訊速率。
快速模式下可選擇SCL 時(shí)鐘的占空比,可選Tlow/Thigh=2 或Tlow/Thigh=16/9 模式,我們知道I2C 協(xié)議在SCL 高電平時(shí)對(duì)SDA 信號(hào)采樣,SCL 低電平時(shí)SDA 準(zhǔn)備下一個(gè)數(shù)據(jù),修改SCL 的高低電平比會(huì)影響數(shù)據(jù)采樣,但其實(shí)這兩個(gè)模式的比例差別并不大。
CCR 寄存器中還有一個(gè)12 位的配置因子CCR,它與I2C 外設(shè)的輸入時(shí)鐘源共同作用,產(chǎn)生SCL 時(shí)鐘,STM32 的I2C 外設(shè)都掛載在APB1 總線上,使用APB1 的時(shí)鐘源PCLK1,SCL信號(hào)線的輸出時(shí)鐘公式如下:
標(biāo)準(zhǔn)模式:
Thigh=CCRTPCKL1 Tlow = CCRTPCLK1
快速模式中Tlow/Thigh=2 時(shí):
Thigh = CCRTPCKL1 Tlow = 2CCRTPCKL1
快速模式中Tlow/Thigh=16/9 時(shí):
Thigh = 9CCRTPCKL1 Tlow = 16CCR*TPCKL1
例如,我們的PCLK1=36MHz,想要配置400Kbit/s 的速率,計(jì)算方式如下:
PCLK 時(shí)鐘周期:TPCLK1 = 1/36000000
目標(biāo)SCL 時(shí)鐘周期:TSCL = 1/400000
SCL 時(shí)鐘周期內(nèi)的高電平時(shí)間:THIGH = TSCL/3
SCL 時(shí)鐘周期內(nèi)的低電平時(shí)間:TLOW = 2*TSCL/3
計(jì)算CCR 的值:CCR = THIGH/TPCLK1 = 30
計(jì)算結(jié)果得出CCR 為30,向該寄存器位寫(xiě)入此值則可以控制IIC 的通訊速率為400KHz。
數(shù)據(jù)控制邏輯
I2C 的SDA 信號(hào)主要連接到數(shù)據(jù)移位寄存器上,數(shù)據(jù)移位寄存器的數(shù)據(jù)來(lái)源及目標(biāo)是數(shù)據(jù)寄存器(DR)、地址寄存器(OAR)、PEC 寄存器以及SDA 數(shù)據(jù)線。
當(dāng)向外發(fā)送數(shù)據(jù)的時(shí)候,數(shù)據(jù)移位寄存器以“數(shù)據(jù)寄存器”為數(shù)據(jù)源,把數(shù)據(jù)一位一位地通過(guò)SDA 信號(hào)線發(fā)送出去;當(dāng)從外部接收數(shù)據(jù)的時(shí)候,數(shù)據(jù)移位寄存器把SDA 信號(hào)線采樣到的數(shù)據(jù)一位一位地存儲(chǔ)到“數(shù)據(jù)寄存器”中。
若使能了數(shù)據(jù)校驗(yàn),接收到的數(shù)據(jù)會(huì)經(jīng)過(guò)PCE 計(jì)算器運(yùn)算,運(yùn)算結(jié)果存儲(chǔ)在“PEC 寄存器”中。
當(dāng)STM32 的I2C 工作在從機(jī)模式的時(shí)候,接收到設(shè)備地址信號(hào)時(shí),數(shù)據(jù)移位寄存器會(huì)把接收到的地址與STM32 的自身的“I2C 地址寄存器”的值作比較,以便響應(yīng)主機(jī)的尋址。
STM32 的自身I2C 地址可通過(guò)修改“自身地址寄存器”修改,支持同時(shí)使用兩個(gè)I2C 設(shè)備地址,兩個(gè)地址分別存儲(chǔ)在OAR1 和OAR2 中。
整體控制邏輯
整體控制邏輯負(fù)責(zé)協(xié)調(diào)整個(gè)I2C 外設(shè),控制邏輯的工作模式根據(jù)我們配置的“控制寄存器(CR1/CR2)”的參數(shù)而改變。
在外設(shè)工作時(shí),控制邏輯會(huì)根據(jù)外設(shè)的工作狀態(tài)修改“狀態(tài)寄存器(SR1 和SR2)”,我們只要讀取這些寄存器相關(guān)的寄存器位,就可以了解I2C 的工作狀態(tài)。
除此之外,控制邏輯還根據(jù)要求,負(fù)責(zé)控制產(chǎn)生I2C 中斷信號(hào)、DMA 請(qǐng)求及各種I2C 的通訊信號(hào)(起始、停止、響應(yīng)信號(hào)等)。
通訊過(guò)程
使用I2C 外設(shè)通訊時(shí),在通訊的不同階段它會(huì)對(duì)“狀態(tài)寄存器(SR1 及SR2)”的不同數(shù)據(jù)位寫(xiě)入?yún)?shù),我們通過(guò)讀取這些寄存器標(biāo)志來(lái)了解通訊狀態(tài)。
主發(fā)送器
主發(fā)送器發(fā)送流程:
(1) 控制產(chǎn)生起始信號(hào)(S),當(dāng)發(fā)生起始信號(hào)后,它產(chǎn)生事件“EV5”,并會(huì)對(duì)SR1 寄存器的“SB”位置1,表示起始信號(hào)已經(jīng)發(fā)送;
(2) 緊接著發(fā)送設(shè)備地址并等待應(yīng)答信號(hào),若有從機(jī)應(yīng)答,則產(chǎn)生事件“EV6”及“EV8”,這時(shí)SR1 寄存器的“ADDR”位及“TXE”位被置1,ADDR 為1 表示地址已經(jīng)發(fā)送,TXE 為1 表示數(shù)據(jù)寄存器為空;
(3) 以上步驟正常執(zhí)行并對(duì)ADDR 位清零后,我們往I2C 的“數(shù)據(jù)寄存器DR”寫(xiě)入要發(fā)送的數(shù)據(jù),這時(shí)TXE 位會(huì)被重置0,表示數(shù)據(jù)寄存器非空,I2C 外設(shè)通過(guò)SDA 信號(hào)線一位位把數(shù)據(jù)發(fā)送出去后,又會(huì)產(chǎn)生“EV8”事件,即TXE 位被置1,重復(fù)這個(gè)過(guò)程,就可以發(fā)送多個(gè)字節(jié)數(shù)據(jù)了;
(4) 當(dāng)我們發(fā)送數(shù)據(jù)完成后,控制I2C 設(shè)備產(chǎn)生一個(gè)停止信號(hào)§,這個(gè)時(shí)候會(huì)產(chǎn)生EV8_2 事件,SR1 的TXE 位及BTF 位都被置1,表示通訊結(jié)束。
假如我們使能了I2C 中斷,以上所有事件產(chǎn)生時(shí),都會(huì)產(chǎn)生I2C 中斷信號(hào),進(jìn)入同一個(gè)中斷服務(wù)函數(shù),到I2C 中斷服務(wù)程序后,再通過(guò)檢查寄存器位來(lái)判斷是哪一個(gè)事件。
主接收器
主接收器接收流程:
(1) 同主發(fā)送流程,起始信號(hào)(S) 是由主機(jī)端產(chǎn)生的,控制發(fā)生起始信號(hào)后,它產(chǎn)生事件“EV5”,并會(huì)對(duì)SR1 寄存器的“SB”位置1,表示起始信號(hào)已經(jīng)發(fā)送;
(2) 緊接著發(fā)送設(shè)備地址并等待應(yīng)答信號(hào),若有從機(jī)應(yīng)答,則產(chǎn)生事件“EV6”這時(shí)SR1 寄存器的“ADDR”位被置1,表示地址已經(jīng)發(fā)送。
(3) 從機(jī)端接收到地址后,開(kāi)始向主機(jī)端發(fā)送數(shù)據(jù)。當(dāng)主機(jī)接收到這些數(shù)據(jù)后,會(huì)產(chǎn)生“EV7”事件,SR1 寄存器的RXNE 被置1,表示接收數(shù)據(jù)寄存器非空,我們讀取該寄存器后,可對(duì)數(shù)據(jù)寄存器清空,以便接收下一次數(shù)據(jù)。此時(shí)我們可以控制I2C 發(fā)送應(yīng)答信號(hào)(ACK) 或非應(yīng)答信號(hào)(NACK),若應(yīng)答,則重復(fù)以上步驟接收數(shù)據(jù),若非應(yīng)答,則停止傳輸;
(4) 發(fā)送非應(yīng)答信號(hào)后,產(chǎn)生停止信號(hào)( P ),結(jié)束傳輸。
在發(fā)送和接收過(guò)程中,有的事件不只是標(biāo)志了我們上面提到的狀態(tài)位,還可能同時(shí)標(biāo)志主機(jī)狀態(tài)之類的狀態(tài)位,而且讀了之后還需要清除標(biāo)志位,比較復(fù)雜。
二、STM32Cube MX配置
STM32的I2C協(xié)議也支持SMBus模式(一般用于筆記本電池管理)
Master features??主模式特性
I2C Speed Mode: IIC模式設(shè)置 快速模式和標(biāo)準(zhǔn)模式。
I2C Clock Speed: I2C傳輸速率,默認(rèn)為100KHz
Slave?features??從模式特性
Clock?No?Stretch?Mode:?時(shí)鐘沒(méi)有擴(kuò)展模式文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-415469.html
IIC時(shí)鐘拉伸(Clock stretching)
clock stretching通過(guò)將SCL線拉低來(lái)暫停一個(gè)傳輸.直到釋放SCL線為高電平,傳輸才繼續(xù)進(jìn)行.
clock stretching是可選的,實(shí)際上大多數(shù)從設(shè)備不包括SCL驅(qū)動(dòng),所以它們不能stretch時(shí)鐘.
Primary?Address?Length?selection:?從設(shè)備地址長(zhǎng)度 設(shè)置從設(shè)備的地址是7bit還是10bit 大部分為7bit
Dual?Address?Acknowledged:?雙地址確認(rèn)
Primary?slave?address:??從設(shè)備初始地址文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-415469.html
三、I2C HAL庫(kù)函數(shù)
//IIC寫(xiě)函數(shù)
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
功能:HAL庫(kù) IIC寫(xiě)數(shù)據(jù)
參數(shù):
*hi2c 設(shè)置使用的IIC 名稱 例:&hi2c1
DevAddress 寫(xiě)入的地址 例 0xA0
*pData 需要寫(xiě)入的數(shù)據(jù)的地址
Size 要發(fā)送的字節(jié)數(shù)
Timeout 最大傳輸時(shí)間,超過(guò)傳輸時(shí)間將自動(dòng)退出傳輸函數(shù)
//示例: HAL_I2C_Master_Transmit(&hi2c1,0xA0,(uint8_t*)tx_data,100,1000);
//IIC讀函數(shù)
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
功能:HAL庫(kù) IIC讀一個(gè)字節(jié)
參數(shù):
*hi2c: 設(shè)置使用的是那個(gè)IIC 名稱 例:&hi2c1
DevAddress: 讀取的地址 例 0xA0
*pData: 存儲(chǔ)讀取到的數(shù)據(jù)的地址
Size: 接收的字節(jié)數(shù)
Timeout: 最大讀取時(shí)間,超過(guò)時(shí)間將自動(dòng)退出讀取函數(shù)
//示例: HAL_I2C_Master_Receive(&hi2c1,0xA0,(uint8_t*)rx_data,100,1000);
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
功能:HAL庫(kù) IIC寫(xiě)數(shù)據(jù)函數(shù)
參數(shù):
*hi2c: 設(shè)置使用的是那個(gè)IIC 名稱 例:&hi2c1
DevAddress: 從機(jī)設(shè)備地址
MemAddress:從機(jī)寄存器地址
MemAddSize:從機(jī)寄存器地址長(zhǎng)度
*pData: 存儲(chǔ)讀取到的數(shù)據(jù)的地址
Size: 接收的字節(jié)數(shù)
Timeout: 最大讀取時(shí)間,超過(guò)時(shí)間將自動(dòng)退出寫(xiě)入函數(shù)
到了這里,關(guān)于STM32 HAL庫(kù) STM32CubeMX -- I2C(IIC)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!