開發環境:
MDK:Keil 5.30
開發板:GD32F207I-EVAL
MCU:GD32F207IK
1 I2C工作原理
1.1 I2C串行總線概述
I2C總線是PHLIPS公司推出的一種雙線式半雙工串行總線,是具備多主機系統所需的總線裁決和高低速器件同步功能的高性能串行總線。用于連接微控器及外圍設備。I2C總線只有兩根雙向信號線。一根是數據線SDA,另一根是時鐘線SCL。
物理層
1)它只使用兩條總線線路 :一條雙向串行數據線(SDA),一條串行時鐘線(SCL)。見圖 1。
2)每個連接到總線的設備都有一個獨立的地址,主機可以利用這個地址進行不同設備之間的訪問。
3)多主機同時使用總線時,為了防止數據沖突,會利用仲裁方式決定由哪個設備占用總線。
4)具有三種傳輸模式 :標準模式的傳輸速率為 100 Kbit/s ,快速模式為 400 Kbit/s ,高速模式下可達 3.4 Mbit/s,但目前大多12C設備尚不支持高速模式。
5)片上的濾波器可以濾去總線數據線上的毛刺波以保證數據完整。
6)連接到相同總線的 IC 數量受到總線的最大電容 400 pF 限制
I2C總線通過上拉電阻接正電源。當總線空閑時,兩根線均為高電平。連到總線上的任一器件輸出的低電平,都將使總線的信號變低,即各器件的SDA及SCL都是線“與”關系。
每個接到I2C總線上的器件都有唯一的地址。主機與其它器件間的數據傳送可以是由主機發送數據到其它器件,這時主機即為發送器。由總線上接收數據的器件則為接收器。
在多主機系統中,可能同時有幾個主機企圖啟動總線傳送數據。為了避免混亂, I2C總線要通過總線仲裁,以決定由哪一臺主機控制總線。
協議層
I2C的協議包括起始和停止條件、數據有效性、響應、仲裁、時鐘同步和地址廣播等環節,由于我們使用的是 STM32 集成的硬件I2C接口,并不需要用軟件去模擬 SDA 和SCL 線的時序。
這兩幅圖表示的是主機和從機通信時 SDA 線的數據包序列。
其中 S 表示由主機的I2C接口產生的傳輸起始信號(S),這時連接到I2C總線上的所有從機都會接收到這個信號。
起始信號產生后,所有從機就開始等待主機緊接下來廣播的從機地址信號(SLAVE_ADDRESS),在I2C總線上,每個設備的地址都是唯一的。當主機廣播的地址與某個設備地址相同時,這個設備就被選中了,沒被選中的設備將會忽略之后的數據信號。根據I2C協議,這個從機地址可以是 7 位或 10 位。
在地址位之后,是傳輸方向的選擇位,該位為 0 時,表示后面的數據傳輸方向是由主機傳輸至從機。該位為 1 時,則相反。
從機接收到匹配的地址后,主機或從機會返回一個應答(A)或非應答信號,只有接收到應答信號后,主機才能繼續發送或接收數據。
若配置的方向傳輸位為寫數據,廣播完地址,接收到應答信號后,主機開始正式向從機傳輸數據(DATA),數據包的大小為 8 位。主機每發送完一個數據,都要等待從機的應答信號(A),重復這個過程,可以向從機傳輸 N 個數據,這個 N 沒有大小限制。當數據傳輸結束時,主機向從機發送一個停止傳輸信號(P),表示不再傳輸數據。
若配置的方向傳輸位為讀數據,廣播完地址,接收到應答信號后,從機開始向主機返回數據(DATA),數據包大小也為 8 位。從機每發送完一個數據,都會等待主機的應答信號(A),重復這個過程,可以返回 N 個數據,這個 N 也沒有大小限制。當主機希望停止接收數據時,就向從機返回一個非應答信號,則從機自動停止數據傳輸。
I2C接口特性
1)STM32 的中等容量和大容量型號的芯片均有多達兩個的I2C總線接口。
2)能夠工作于多主模式或從模式,分別為主接收器、主發送器、從接收器及從發送器。
3)支持標準模式 100 Kbit/s 和快速模式 400 Kbit/s,不支持高速模式。
4)支持 7 位或 10 位尋址。
5)內置了硬件 CRC 發生器 / 校驗器。
6)I2 C 的接收和發送都可以使用 DMA 操作。
7)支持系統管理總線(SMBus)2.0 版。
I 2 C 架構
I2C的所有硬件架構就是根據 SCL 線和 SDA 線展開的(其中 SMBALERT 線用于 SMBus)。SCL 線的時序即為I2C 協議中的時鐘信號,它由I2C 接口根據時鐘控制寄存器(CCR)控制,控制的參數主要為時鐘頻率。而 SDA 線的信號則通過一系列數據控制架構,在將要發送的數據的基礎上,根據協議添加各種起始信號、應答信號、地址信號,實現以 I 2 C 協議的方式發送出去。讀取數據時則從 SDA 線上的信號中取出接收到的數據值。發送和接收的數據都被保存在數據寄存器(DR)上。
1.2 I2C總線的數據傳送
數據位的有效性規定
I2C總線進行數據傳送時,時鐘信號為高電平期間,數據線上的數據必須保持穩定,只有在時鐘線上的信號為低電平期間,數據線上的高電平或低電平狀態才允許變化。
起始和終止信號
SCL線為高電平期間, SDA線由高電平向低電平的變化表示起始信號 ;SCL線為高電平期間, SDA線由低電平向高電平的變化表示終止信號 。
起始和終止信號都是由主機發出的 ,在起始信號產生后,總線就處于被占用的狀態;在終止信號產生后,總線就處于空閑狀態。連接到I2C總線上的器件,若具有I2C總線的硬件接口,則很容易檢測到起始和終止信號。每當發送器件傳輸完一個字節的數據后,后面必須緊跟一個校驗位,這個校驗位是接收端通過控制SDA(數據線)來實現的,以提醒發送端數據我這邊已經接收完成,數據傳送可以繼續進行。
數據傳送格式
字節傳送與應答
每一個字節必須保證是8位長度。數據傳送時,先傳送最高位(MSB),每一個被傳送的字節后面都必須跟隨一位應答位(即一幀共有9位)。
由于某種原因從機不對主機尋址信號應答時(如從機正在進行實時性的處理工作而無法接收總線上的數據),它必須將數據線置于高電平,而由主機產生一個終止信號以結束總線的數據傳送。
如果從機對主機進行了應答,但在數據傳送一段時間后無法繼續接收更多的數據時,從機可以通過對無法接收的第一個數據字節的“非應答”通知主機,主機則應發出終止信號以結束數據的繼續傳送。
當主機接收數據時,它收到最后一個數據字節后,必須向從機發出一個結束傳送的信號。這個信號是由對從機的“非應答”來實現的。然后,從機釋放SDA線,以允許主機產生終止信號。
總線的尋址
I2C總線協議有明確的規定:采用7位的尋址字節(尋址字節是起始信號后的第一個字節)。
尋址字節的位定義
D7~D1位組成從機的地址。D0位是數據傳送方向位,為“0”時表示主機向從機寫數據,為“1”時表示主機由從機讀數據。
主機發送地址時,總線上的每個從機都將這7位地址碼與自己的地址進行比較,如果相同,則認為自己正被主機尋址,根據R/T位將自己確定為發送器或接收器。
從機的地址由固定部分和可編程部分組成。在一個系統中可能希望接入多個相同的從機,從機地址中可編程部分決定了可接入總線該類器件的最大數目。如一個從機的7位尋址位有4位是固定位,3位是可編程位,這時僅能尋址8個同樣的器件,即可以有8個同樣的器件接入到該I2C總線系統中。
數據幀格式
I2C總線上傳送的數據信號是廣義的,既包括地址信號,又包括真正的數據信號。
在起始信號后必須傳送一個從機的地址(7位),第8位是數據的傳送方向位(R/T),用“0”表示主機發送數據(T),“1”表示主機接收數據(R)。每次數據傳送總是由主機產生的終止信號結束。但是,若主機希望繼續占用總線進行新的數據傳送,則可以不產生終止信號,馬上再次發出起始信號對另一從機進行尋址。
在總線的一次數據傳送過程中,可以有以下幾種組合方式:
A)主機向從機發送數據,數據傳送方向在整個過程中不變;
注:有陰影部分表示數據由主機向從機傳送,無陰影部分則表示數據由從機向主機傳送。A表示應答, A表示非應答(高電平)。S表示起始信號,P表示終止信號。
B)主機在第一個字節后,立即從從機讀數據。
C)在傳送過程中,當需要改變傳送方向時,起始信號和從機地址都被重復產生一次,但兩次讀/寫方向位正好反相。
要想了解對I2C的主從模式詳細了解,參看GD32xxx參考手冊的I2C接口章節。
2 AT24Cxx存儲器原理
2.1 AT24Cxx概述
AT24C01/02/04/08/16是一個1K/2K/4K/8K/16K位串行CMOS,EEPROM內部含有128/256/512/1024/2048個8位字節CATALYST公司的先進CMOS技術實質上減少了器件的功耗,AT24C01/02有一個8字節頁寫緩沖器AT24C04/08/16有一個16字節頁寫緩沖器,該器件通過I2C總線接口進行操作有一個專門的寫保護功能。 AT24C01/02每頁有8個字節,分別為16/32頁;AT24C04/08/16每頁有16個字節,分別為32/64/128頁 。
工作特點
與400KHz I2C總線兼容
1.8到6.0伏工作電壓范圍
低功耗CMOS技術
寫保護功能當WP為高電平時進入寫保護狀態
頁寫緩沖器
自定時擦寫周期
100萬次編程/擦除周期
可保存數據100年
8腳DIP SOIC或TSSOP封裝
溫度范圍商業級和工業級
AT24Cxx的引腳定義如下:
Note: For use of 5-lead SOT23, the software A2, A1, and A0 bits in the device address word must be set to zero toproperly communicate.
2.2總線時序
I2C總線時序如下:
其讀寫周期的電壓范圍如下:
寫周期時間是指從一個寫時序的有效停止信號到內部編程/擦除周期結束的這一段時間。在寫周期期間,總線接口電路禁能,SDA保持為高電平,器件不響應外部操作。
2.3 器件尋址
主器件通過發送一個起始信號啟動發送過程,然后發送它所要尋址的從器件的地址。8位從器件地址的高4位固定為(1010)。接下來的3位(A2、A1、A0)為器件的地址位,用來定義哪個器件以及器件的哪個部分被主器件訪問,上述8個AT24C01/02,4個AT24C04,2個AT24C08,1個AT24C16可單獨被系統尋址。從器件8位地址的最低位,作為讀寫控制位。“1”表示對從器件進行讀操作,“0”表示對從器件進行寫操作。在主器件發送起始信號和從器件地址字節后,AT24C01/02/04/08/16監視總線并當其地址與發送的從地址相符時響應一個應答信號(通過SDA線)。AT24C01/02/04/08/16再根據讀寫控制位(R/W)的狀態進行讀或寫操作。
字節寫
在字節寫模式下,主器件發送起始命令和從器件地址信息(R/W)位置發給從器件,在從器件產生應答信號后,主器件發送AT24Cxx的字節地址,主器件在收到從器件的另一個應答信號后,再發送數據到被尋址的存儲單元。AT24Cxx再次應答,并在主器件產生停止信號后開始內部數據的擦寫,在內部擦寫過程中,AT24Cxx不再應答主器件的任何請求。
頁寫
用頁寫,AT24C01/02可一次寫入8 個字節數據,AT24C04/08/16可以一次寫入16個字節的數據。__頁寫操作的啟動和字節寫一樣,不同在于傳送了一字節數據后并不產生停止信號。__主器件被允許發送P(AT24C01:P=7;AT24C02/04/08/16:P=15)個額外的字節。每發送一個字節數據后AT24Cxx產生一個應答位并將字節地址低位加1,高位保持不變。
如果在發送停止信號之前主器件發送超過P+1個字節,地址計數器將自動翻轉,先前寫入的數據被覆蓋。
接收到P+1字節數據和主器件發送的停止信號后,AT24Cxx啟動內部寫周期將數據寫到數據區。所有接收的數據在一個寫周期內寫入AT24Cxx。
讀字節
讀操作允許主器件對寄存器的任意字節進行讀操作,主器件首先通過發送起始信號、從器件地址和它想讀取的字節數據的地址執行一個寫操作。在AT24Cxx應答之后,主器件重新發送起始信號和從器件地址,此時R/W位置1,AT24Cxx響應并發送應答信號,然后輸出所要求的一個8位字節數據,主器件不發送應答信號但產生一個停止信號。
順序讀
在AT24Cxx發送完一個8位字節數據后,主器件產生一個應答信號來響應,告知AT24Cxx主器件要求更多的數據,對應每個主機產生的應答信號AT24Cxx將發送一個8位數據字節。當主器件不發送應答信號而發送停止位時結束此操作。
從AT24Cxx輸出的數據按順序由N到N+1輸出。讀操作時地址計數器在AT24Cxx整個地址內增加,這樣整個寄存器區域可在一個讀操作內全部讀出,當讀取的字節超過E(對于24WC01,E=127;對24C02,E=255;對24C04,E=511;對24C08,E=1023;對24C16,E=2047)計數器將翻轉到零并繼續輸出數據字節。
典型應用
ATC02的典型電路如下:
根據AT24C02的芯片資料,我們會發現AT24C02有三個地址A0,A1,A2。同時,我們會在資料的Device Address介紹發現I2C器件一共有七位地址碼,還有一位是讀/寫(R/W)操作位,而在AT24C02的前四位已經固定為1010。R/W為1則為 讀操作,為0則為寫操作。R/W位我們要設置為0(寫操作)。
規則為:1010(A0)(A1)(A2)(R/W)
例子1:
那么對應的A0,A1,A2都是接的VCC,所以為A0=1,A1=1,A2=1;可以知道AT24C02的從設備寫地址為10101110(0xae),讀設備地址為10101111(0xaf)。
例子2:
那么對應的A0,A1,A2都是接的GND,所以為A0=0,A1=0,A2=0;可以知道AT24C02的從設備寫地址為10100000(0xa0),讀設備地址為10100001(0xa1)。
3 I2C寄存器描述
I2C有6類寄存器,詳細的介紹請參考GD32F2XXX參考手冊的I2C寄存器描述部分。在這里筆者只講最重要的2個寄存器。
數據寄存器
數據寄存器的詳細描述如下所示。
時鐘寄存器
時鐘寄存器是I2C中比較重要的一個寄存器,時鐘信號的信號的穩定是I2C正常工作的前提。
4 硬件設計及連接
本文是使用I2C協議對EEPROM進行讀寫操作,具體的硬件連接如下。
從硬件鏈接可以得到AT24C02的地址是0xA0,I2C的接口是I2C0。
5 硬件I2C
5.1 具體代碼實現
首先看看I2C的初始化。這有兩部分。
一部分是I2C的GPIO初始化。
/*
brief configure the GPIO ports
param[in] i2c_typedef_enum i2c_id
param[out] none
retval none
*/
void i2c_gpio_config(i2c_typedef_enum i2c_id)
{
/* enable GPIO clock */
rcu_periph_clock_enable(I2C_BUS_SCL_GPIO_CLK[i2c_id]);
rcu_periph_clock_enable(I2C_BUS_SDA_GPIO_CLK[i2c_id]);
/* Config I2C_SCL */
gpio_init(I2C_BUS_SCL_GPIO_PORT[i2c_id], GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_BUS_SCL_PIN[i2c_id]);
/* Config I2C_SDA */
gpio_init(I2C_BUS_SDA_GPIO_PORT[i2c_id], GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_BUS_SDA_PIN[i2c_id]);
}
/*
brief configure the I2C0 interfaces
param[in] i2c_typedef_enum i2c_id
param[out] none
retval none
*/
void i2c_mode_config(i2c_typedef_enum i2c_id)
{
/* enable I2C clock */
rcu_periph_clock_enable(I2C_BUS_CLK[i2c_id]);
/* configure I2C clock */
i2c_clock_config(I2C_BUS[i2c_id], I2C_SPEED, I2C_DTCY_2);
/* configure I2C address */
i2c_mode_addr_config(I2C_BUS[i2c_id], I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7);
/* enable I2C0 */
i2c_enable(I2C_BUS[i2c_id]);
/* enable acknowledge */
i2c_ack_config(I2C_BUS[i2c_id], I2C_ACK_ENABLE);
}
主要配置I2C模式、低電平占空比、I2C尋址模式以及通信速率,最后使能I2C設備。
初始化完成后就是對AT24C02的讀寫操作,嚴格按照相應的時序操作就行。
字節寫
在字節寫模式下,向AT24C02中寫數據時序如下:
操作時序如下:
1.MCU先發送一個開始信號(START)啟動總線
2.接著跟上首字節,發送器件寫操作地址(DEVICE ADDRESS)+寫數據(0xA0)
3.等待應答信號(ACK)
4.發送數據的存儲地址。24C02一共有256個字節的存儲空間,地址從0x00~0xFF,想把數據存儲在哪個位置,此刻寫的就是哪個地址。
5.發送要存儲的數據,在寫數據的過程中,AT24C02會回應一個“應答位0”,則表明寫AT24C02數據成功,如果沒有回應答位,說明寫入不成功。
6.發送結束信號(STOP)停止總線。
代碼很簡單,跟著時序來就行。
/*
brief write one byte to the I2C EEPROM
param[in] i2c_typedef_enum i2c_id
p_buffer: pointer to the buffer containing the data to be written to the EEPROM
param[in] write_address: EEPROM's internal address to write to
param[out] none
retval none
*/
void eeprom_byte_write(i2c_typedef_enum i2c_id, uint8_t *p_buffer, uint8_t write_address)
{
/* wait until I2C bus is idle */
while(i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_I2CBSY));
/* send a start condition to I2C bus */
i2c_start_on_bus(I2C_BUS[i2c_id]);
/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_SBSEND));
/* send slave address to I2C bus */
i2c_master_addressing(I2C_BUS[i2c_id], eeprom_address, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_ADDSEND));
/* clear the ADDSEND bit */
i2c_flag_clear(I2C_BUS[i2c_id], I2C_FLAG_ADDSEND);
/* wait until the transmit data buffer is empty */
while(SET != i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_TBE));
/* send the EEPROM's internal address to write to : only one byte address */
i2c_data_transmit(I2C_BUS[i2c_id], write_address);
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_BTC));
/* send the byte to be written */
i2c_data_transmit(I2C_BUS[i2c_id], *p_buffer);
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C_BUS[i2c_id], I2C_FLAG_BTC));
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C_BUS[i2c_id]);
/* wait until the stop condition is finished */
while(I2C_CTL0(I2C_BUS[i2c_id]) & 0x0200);
}
頁寫
用頁寫,AT24C01可一次寫入8 個字節數據,AT24C02/04/08/16可以一次寫入16個字節的數據。__頁寫操作的啟動和字節寫一樣,不同在于傳送了一字節數據后并不產生停止信號。__每發送一個字節數據后AT24Cxx產生一個應答位并將字節地址低位加1,高位保持不變。
上一篇:GD32開發實戰指南(基礎篇) 第18章 CRC校驗
下一篇:GD32 MCU超頻后無法再次下載程序的解決辦法
- 熱門資源推薦
- 熱門放大器推薦
設計資源 培訓 開發板 精華推薦
- EM35x using Skyworks SE2432L
- AD9258-80EBZ,用于 AD9258BCPZ-80、2 通道、14 位、80 MSPS 模數轉換器的評估板
- 用于完整 3V、12 位、1MHz 模數轉換系統的 AD8602WARZ-R7 運算放大器的典型應用
- Si4123GM-EVB,Si4123G-BM PLL 頻率合成器評估板
- 【附公告】光纖音頻4進1出切換器分配器
- SIP78L24AC 三端低電流正壓穩壓器典型應用
- LF50CDT-TR 5V 順序極低壓降穩壓器多輸出電源的典型應用
- BD-SL-i.MX6、i.MX6x SABRE Lite 開發平臺具有強大的 i.MX 6Quad 應用處理器
- EVAL-ADuC7028QSZ,ADuC7028 MCU 的快速入門開發系統
- LTC3803ES6 演示板,電信 DC/DC 轉換器,+Vin 至 -Vin = 36V-72V,+Vout = 5V @ 2A