開(kāi)發(fā)板:mini2440
內(nèi)核 :linux2.6.32.2
參考 :韋東山畢業(yè)班I2C視頻教程
1、i2c協(xié)議簡(jiǎn)要分析
i2c中線是一種由 PHILIPS 公司開(kāi)發(fā)的串行總線,用于連接微控制器及其外圍設(shè)備,它具有以下特點(diǎn)。
1、只有兩條總線線路:一條串行數(shù)據(jù)線SDA,一條串行時(shí)鐘線SCL。
2、每個(gè)連接到總線的器件都可以使用軟件根據(jù)它的唯一的地址來(lái)確定。
3、傳輸數(shù)據(jù)的設(shè)備之間是簡(jiǎn)單的主從關(guān)系。
4、主機(jī)可以用作主機(jī)發(fā)送器或者主機(jī)接收器。
5、它是一個(gè)真正的多主機(jī)總線,兩個(gè)或多個(gè)主機(jī)同時(shí)發(fā)起數(shù)據(jù)傳輸時(shí),可以通過(guò)沖突檢測(cè)和仲裁來(lái)防止數(shù)據(jù)被破壞。
6、串行的8位雙向傳輸,位速在標(biāo)準(zhǔn)模式下可達(dá) 100kbit/s,在快速模式下可達(dá)400kbit/s,在高速模式下可待3.4Mbit/s。
7、片上的濾波器可以增加抗干擾能力,保證數(shù)據(jù)的完整性。
8、連接到同一總線上的IC數(shù)量只受到總線的最大電容400Pf的限制。
如上圖所示,啟動(dòng)一個(gè)傳輸時(shí),主機(jī)先發(fā)送一個(gè)S信號(hào),然后發(fā)送8位數(shù)據(jù)。這8位數(shù)據(jù)的前7位為從機(jī)地址,第八位表示傳輸?shù)姆较颍?表示寫,1表示讀),如果有數(shù)據(jù)則繼續(xù)發(fā)送,最后發(fā)出P信號(hào)停止。
信號(hào)類型:
注意:正常數(shù)據(jù)傳輸時(shí),SDA 在 SCL 為低電平時(shí)改變,在 SCL 為高電平時(shí)保持穩(wěn)定。
開(kāi)始信號(hào) S 信號(hào):
SCL 為高電平時(shí),SDA由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào) P 信號(hào):
SCL 為高電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
響應(yīng)信號(hào) ACK:
接收器在接收到8位數(shù)據(jù)后,在第9個(gè)時(shí)鐘周期,拉低 SDA 電平
注意:在第9個(gè)時(shí)鐘周期,發(fā)送器保持SDA為高,如果有ACK,那么第9個(gè)時(shí)鐘周期SDA為低電平,如果沒(méi)有為高電平,發(fā)送器根據(jù)電平高低分辨是否有ACK信號(hào)。
如果使能了IIC中斷,發(fā)送完8bit數(shù)據(jù)后,主機(jī)自動(dòng)進(jìn)入中斷處理函數(shù),此時(shí)SCL被發(fā)送器拉低,讓接收器被迫等待。恢復(fù)傳輸只需要清除中斷掛起。
2、 s3c2440 讀寫流程
1、設(shè)置傳輸模式 IICSTAT[7-6],我們做實(shí)驗(yàn)與AT24C08通信時(shí),2440作為主機(jī),因此只用到主機(jī)發(fā)模式和主機(jī)收模式。
2、寫入從機(jī)地址到 IICDS[7-1],此時(shí)IICDS[7-1]位表示從機(jī)地址,第0位不關(guān)心。如 AT24C08 為 0xA0(最低位寫0了,發(fā)送到數(shù)據(jù)線上的7位地址的后邊以為才表示收發(fā),這里雖然寫0但并不是根據(jù)這里的0來(lái)真正發(fā)送的)。
3、寫 0xF0(寫) 或 0xB0(讀)到 IICSTAT 寄存器, 高兩位表示 傳輸模式前邊設(shè)置過(guò)了,設(shè)置IICSTT[5-4] 為 11,使能傳輸,發(fā)送S信號(hào)。
4、IIC控制器自動(dòng)將第2步中設(shè)置的 IICDS[7-1] 再根據(jù) 傳輸模式 補(bǔ)充 IICDS[0]位,發(fā)送出去。
5、進(jìn)入第9個(gè)時(shí)鐘周期,此時(shí),從機(jī)決定是否發(fā)出ACK信號(hào),主機(jī)進(jìn)入中斷,判斷是否收到ACK信號(hào),以及是否繼續(xù)傳輸。
繼續(xù)發(fā)送:
1、將數(shù)據(jù)寫入 IICDS
2、清除中斷掛起,SCL時(shí)鐘恢復(fù),IICDS的數(shù)據(jù)被自動(dòng)發(fā)送到 SDA 線上,回到第5步。
停止發(fā)送:
1、寫 0xD0(寫) 和 0x90(讀) 到 IICATAT ,IICATAT[7-6]還是表示的傳輸模式,IICATAT[5-4] == 0 1,發(fā)送停止信號(hào)
2、清除中斷掛起,SCL時(shí)鐘恢復(fù),發(fā)出停止信號(hào)
3、延時(shí),等待停止信號(hào)發(fā)出
3、 AT24C08 讀寫分析
1、寫過(guò)程
寫過(guò)程與2440芯片的里的寫流程相一致,按照流程寫就OK
2、讀過(guò)程
讀過(guò)程是由2440芯片里的一個(gè)寫流程加一個(gè)讀流程組合而成,其中寫流程結(jié)束沒(méi)有發(fā)出P信號(hào),而是直接發(fā)出了S信號(hào)開(kāi)始讀流程,也就是我為什么加了一道紅線的原因。
附上一份簡(jiǎn)單的裸機(jī)程序,僅供參考:基于MINI2440
#include #include "s3c2440.h" void Delay(int time); #define WRDATA (1) #define RDDATA (2) typedef struct tI2C { unsigned char *pData; /* 數(shù)據(jù)緩沖區(qū) */ volatile int DataCount; /* 等待傳輸?shù)臄?shù)據(jù)長(zhǎng)度 */ volatile int Status; /* 狀態(tài) */ volatile int Mode; /* 模式:讀/寫 */ volatile int Pt; /* pData中待傳輸數(shù)據(jù)的位置 */ }tS3C24xx_I2C, *ptS3C24xx_I2C; static tS3C24xx_I2C g_tS3C24xx_I2C; /* * I2C初始化 */ void i2c_init(void) { GPEUP |= 0xc000; // 禁止內(nèi)部上拉 /* * AT24C08 兩根線 I2CSCL I2CSDA 與 2440芯片相連 * 配置2440 GPECON GPE15 GPE14引腳為I2C功能 */ GPECON |= 0xa0000000; // 選擇引腳功能:GPE15:IICSDA, GPE14:IICSCL /* 開(kāi)INT_IIC中斷 */ //INTMSK &= ~(BIT_IIC); /* bit[7] = 1, 使能ACK * bit[6] = 0, IICCLK = PCLK/16 * bit[5] = 1, 使能中斷 * bit[3:0] = 0xf, Tx clock = IICCLK/16 * PCLK = 50MHz, IICCLK = 3.125MHz, Tx Clock = 0.195MHz */ IICCON = (1<<7) | (0<<6) | (1<<5) | (0xf); // 0xaf //IICADD = 0x10; // S3C24xx slave address = [7:1] IICSTAT = 0x10; // I2C串行輸出使能(Rx/Tx) } void I_Write(unsigned int slvaddr, unsigned char addr, unsigned char data) { unsigned int ack; // 寫從地址 IICSTAT |= 0x1<<6;//主機(jī)寫模式 IICSTAT |= 0x1<<7; IICDS = slvaddr;//0xa0; //write slave address to IICDS IICCON&=~0x10; //clear pending bit IICSTAT = 0xf0; //(M/T start) while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending // 寫寄存器地址 IICDS = addr; IICCON&=~0x10; //clear pending bit while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending // 寫數(shù)據(jù) IICDS = data; IICCON&=~0x10; //clear pending bit while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending // 發(fā)出停止信號(hào) IICSTAT = 0xD0; //write (M/T stop to IICSTAT) IICCON&=~0x10; //clear pending bit while((IICSTAT & 1<<5) == 1); } unsigned char I_Read(unsigned int slvaddr, unsigned char addr) { unsigned char data = 1; int ack; // 寫從地址 IICSTAT |= 0x1<<6;//主機(jī)寫模式 IICSTAT |= 0x1<<7; slvaddr = 0xA0; IICDS = slvaddr;//0xa0; //write slave address to IICDS IICCON&=~0x10; //clear pending bit IICSTAT = 0xf0; //(M/T start) while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending // 寫寄存器地址 IICDS = addr; IICCON&=~0x10; //clear pending bit while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending // 寫從地址(讀模式) slvaddr = 0xA1; IICSTAT &= ~(0x1<<6);//主機(jī)接受模式 IICSTAT |= 0x1<<7; IICDS = slvaddr; IICCON&=~0x10; //clear pending bit IICSTAT = 0xb0; //(M/R Start) while((IICCON & 1<<4) == 0);//udelay(10);//uart_SendByte('o');//ack period and then interrupt is pending:: // 讀數(shù)據(jù) data = IICDS; //IICCON&=~0x10; //clear pending bit IICCON = 0x2f; //清掛起狀態(tài),并設(shè)置無(wú)應(yīng)答 while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending data = IICDS; //IICCON&=~0x10; //clear pending bit IICCON = 0x2f; //清掛起狀態(tài),并設(shè)置無(wú)應(yīng)答 while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending IICSTAT = 0x90; IICCON = 0xaf; //IICCON &= ~0x10; //clear pending bit while((IICSTAT & 1<<5) == 1); return data; } 4、adapter驅(qū)動(dòng)程序 這里,我們主要分析驅(qū)動(dòng)里的發(fā)送核心算法,至于注冊(cè)中斷,IO內(nèi)存映射,設(shè)置寄存器不在討論。 static int xxx_i2c_xfer(struct i2c_adapter *adpap, struct i2c_msg *msg,int num) 這個(gè)算法函數(shù)的作用就是將上層封裝好的一些i2c_msg 進(jìn)行解析,將數(shù)據(jù)寫入寄存器,發(fā)送出去。在設(shè)備驅(qū)動(dòng)層,我們使用了類似i2c_smbus_write_byte 等函數(shù),類似的函數(shù)有很多,它們的作用就是封裝i2c_msg 結(jié)構(gòu)(比如讀和寫的 msg 肯定不一樣,讀一個(gè)字節(jié)和讀多個(gè)字節(jié)也不一樣),然后調(diào)用 i2c_smbus_xfer_emulated->i2c_transfer,最終調(diào)用到我們的xxx_i2c_xfer函數(shù)進(jìn)行傳輸。通過(guò)分析i2c_smbus_xfer_emulated函數(shù),我們可以了解i2c_msg是如何封裝的。下面,我們簡(jiǎn)單分析一下,知道最上層想干什么,我們才能知道實(shí)現(xiàn)哪些底層的功能不是。 struct i2c_msg { __u16 addr; //從機(jī)地址 __u16 flags; __u16 len; // buf 里 有多少個(gè)字節(jié) __u8 *buf; // 本 msg 含有的數(shù)據(jù),可能是1個(gè)字節(jié),可有可能是多個(gè)字節(jié) }; 此函數(shù),省略了很多內(nèi)容,舉例分析而已~,細(xì)節(jié)請(qǐng)看源碼 static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; int num = read_write == I2C_SMBUS_READ?2:1; // 寫操作兩個(gè)Msg 讀操作一個(gè)msg 這和我們前面分析AT24c08是一致的 struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, { addr, flags | I2C_M_RD, 0, msgbuf1 } }; msgbuf0[0] = command; // 從機(jī)地址右移1位得到的,比如AT24C08 為 0x50 switch(size) { case I2C_SMBUS_BYTE_DATA: // 單字節(jié)讀寫 if (read_write == I2C_SMBUS_READ) msg[1].len = 1; /* * 讀: * msgbuf0[0] = command * msg[1].len = 1 ,數(shù)據(jù)會(huì)讀到 msgbuf0[1] 里 */ else { msg[0].len = 2; msgbuf0[1] = data->byte; /* * 寫: * msgbuf0[0] = command * msgbuf0[1] = data->byte */ } break; } status = i2c_transfer(adapter, msg, num); } 上面代碼跟我們分析AT24C08的時(shí)候如出一轍,對(duì)于一個(gè)寫操作,我們只需要一個(gè)2440的寫流程對(duì)應(yīng)于這里的一個(gè)Msg,然而對(duì)于讀操作,我們需要2440的兩個(gè)流程,對(duì)應(yīng)于這里的兩個(gè)Msg。那么,我們底層控制器驅(qū)動(dòng)需要做的工作就是,取出所有的Msg,將每一個(gè)Msg里buf里的數(shù)據(jù)發(fā)送出去,如果有下一個(gè)Msg, 那么再將下一個(gè)Msg里的buf發(fā)送完畢,最后發(fā)出P停止信號(hào)。還有一點(diǎn),每發(fā)送一個(gè)Msg都要先發(fā)出S開(kāi)始信號(hào)。 在看adapter程序之前,我們先來(lái)簡(jiǎn)單思考一下,發(fā)出S開(kāi)始信號(hào)之后,可能有以下3中情況: 1、當(dāng)前msg.len == 0 ,如果有ACK直接發(fā)出stop信號(hào)。這種情況出現(xiàn)在,控制器枚舉設(shè)備的時(shí)候,因?yàn)樗话l(fā)送S信號(hào)以及設(shè)備地址,不發(fā)送數(shù)據(jù)。 2、根據(jù)msg->flags 為 I2C_M_RD 等信息判斷讀寫,msg->flags 最低位為1表示讀,最低位為0表示寫。 #define I2C_M_TEN0x0010 /* this is a ten bit chip address */ #define I2C_M_RD0x0001 /* read data, from slave to master */
上一篇:i2c驅(qū)動(dòng)程序全面分析,從adapter驅(qū)動(dòng)程序到設(shè)備驅(qū)動(dòng)程序
下一篇:Linux ARMv7中斷向量表搬移(2)
推薦閱讀最新更新時(shí)間:2025-04-17 02:02
- 熱門資源推薦
- 熱門放大器推薦
-
軟件調(diào)試 第2版 卷2 Windows平臺(tái)調(diào)試 (張銀奎)
-
深度實(shí)踐嵌入式Linux系統(tǒng)移植
-
CVPR 2023論文匯總:高效和可擴(kuò)展視覺(jué) Efficient and Scalable Vision
-
ICCV2023論文匯總:視頻分析與理解 Video Analysis and Understanding
-
CAN總線輕松入門與實(shí)踐
-
通過(guò) Verilog HDL 進(jìn)行設(shè)計(jì)
-
SIMOTION 運(yùn)動(dòng)控制器基礎(chǔ)應(yīng)用
-
EMC電磁屏蔽材料設(shè)計(jì)者指南
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦
- 英飛凌微控制器:以全新實(shí)惠套件和強(qiáng)大開(kāi)發(fā)環(huán)境為開(kāi)發(fā)者提供支持
- iTOP-i.MX6開(kāi)發(fā)板設(shè)備數(shù)驅(qū)動(dòng)Menuconfig的用法
- 迅為IMX6ULL開(kāi)發(fā)板Qt for Android搭建開(kāi)發(fā)環(huán)境
- 迅為i.MX8M mini開(kāi)發(fā)板Windots QT系統(tǒng)開(kāi)發(fā)環(huán)境搭建
- 迅為IMX8MM開(kāi)發(fā)板Yocto系統(tǒng)使用Gstarwmra(一)
- 迅為IMX8M mini開(kāi)發(fā)板Linix系統(tǒng)修改默認(rèn)屏幕
- iTOP-4412開(kāi)發(fā)板支持4G以上文件系統(tǒng)擴(kuò)展
- 迅為IMX8MM開(kāi)發(fā)板Yocto系統(tǒng)設(shè)置開(kāi)機(jī)自啟動(dòng)
- 迅為IMX6Q開(kāi)發(fā)板 Buildroot文件系統(tǒng)mqtt測(cè)試
- 通用AP3041升壓轉(zhuǎn)換器應(yīng)用電路
- DK-DEV-5CEA7NES,Cyclone V E FPGA 開(kāi)發(fā)板為低功耗開(kāi)發(fā)和原型設(shè)計(jì)提供硬件平臺(tái)
- 基于梁山派電子物料收納盒
- AC-DC全橋整流電路
- AM1DM-0512SH60-NZ 12 Vout、1W 單路輸出 DC-DC 轉(zhuǎn)換器的典型應(yīng)用
- AM437x 使用 LPDDR2 的低功耗掛起模式
- MIC4724 的典型應(yīng)用:具有 6Vmax 輸入的 3A 2MHz 集成開(kāi)關(guān)降壓穩(wěn)壓器
- +-35V功放開(kāi)關(guān)電源
- EVAL-AD5370EB,使用 AD5370、40 通道、16 位、串行輸入、電壓輸出 DAC 的評(píng)估板
- 用于工業(yè)應(yīng)用的 LT3973IDD-5 5V 降壓轉(zhuǎn)換器的典型應(yīng)用
- AI算力狂飆下的能源困局,ST如何突圍?
- 韓國(guó)研究人員開(kāi)發(fā)出耐火電池電解質(zhì)以防止熱失控
- “史上最嚴(yán)電池安全令”或引發(fā)產(chǎn)業(yè)第四次大洗牌
- 現(xiàn)代汽車發(fā)布新一代混動(dòng)系統(tǒng),燃油效率提升45%
- 三星顯示將全面采用雙棧串聯(lián)技術(shù)提升車載OLED性能
- 禾賽科技計(jì)劃2026年推L3級(jí)智駕專用激光雷達(dá)“千厘眼”
- 寧德時(shí)代發(fā)布驍遙雙核電池:跨體系技術(shù)革新,續(xù)航超1000km
- 寧德時(shí)代發(fā)布全球首款800km續(xù)航12C超充磷酸鐵鋰電池
- 華為發(fā)布全液冷超充技術(shù),15分鐘充電90%革新重卡市場(chǎng)
- 車規(guī)級(jí)MCU介紹
- 觀看福祿克計(jì)量校準(zhǔn)視頻 參與調(diào)查問(wèn)卷好禮送!
- 【已結(jié)束】R&S 直播【PCI Express Gen 3 一致性測(cè)試(含demo演示)】
- 瑞薩電子顛覆傳統(tǒng)理念的嵌入式開(kāi)發(fā)平臺(tái) Renesas Synergy™ 評(píng)估套件震撼來(lái)襲!答題即可免費(fèi)申請(qǐng)!
- 是德科技有獎(jiǎng)直播:灣區(qū)圓桌派-穿越頻譜壁壘:毫米波技術(shù)的創(chuàng)新之路
- 是德科技第二屆示波器感恩月之買一送一
- 話說(shuō)我接觸的ADI實(shí)驗(yàn)室電路“評(píng)估板”
- 安森美半導(dǎo)體移動(dòng)與可穿戴設(shè)備解決方案下載有禮!
- Nexperia ESD 應(yīng)用手冊(cè)|讀 ESD 干貨答題贏好禮
- Microchip 直播|利用motorBench®開(kāi)發(fā)套件高效開(kāi)發(fā)電機(jī)磁場(chǎng)定向控制方案
- 【EEWORLD第四十一屆】2012年08月社區(qū)明星人物揭曉!
- 馬斯克:“腦機(jī)接口”技術(shù)Neuralink“不久后”實(shí)現(xiàn)
- 松下將OLED顯示屏融于家具中
- 電動(dòng)車充電樁知識(shí)你了解多少?
- UCOSIII在STM32F4xx上的移植
- STM32的獨(dú)立看門狗(IWDG)
- 江蘇電力打造“強(qiáng)前端 大后臺(tái)”體系
- 泛在電力物聯(lián)網(wǎng)帶來(lái)增長(zhǎng)新動(dòng)能
- 深化合作交流 支撐“三型兩網(wǎng)”建設(shè)
- 四川電力:擔(dān)當(dāng)作為 以實(shí)際行動(dòng)推進(jìn)泛在電力物聯(lián)網(wǎng)建設(shè)
- 高標(biāo)準(zhǔn)建設(shè)泛在電力物聯(lián)網(wǎng) 構(gòu)建智慧培訓(xùn)生態(tài)圈