娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年11月24日(星期日)

正在發生

2021年11月24日 | I2C協議->裸機程序->adapter驅動程序分析

發布者:電子設計藝術家 關鍵字:I2C協議  adapter 手機看文章 掃描二維碼
隨時隨地手機看文章

開發板:mini2440


內核  :linux2.6.32.2


參考  :韋東山畢業班I2C視頻教程


1、i2c協議簡要分析


    i2c中線是一種由 PHILIPS 公司開發的串行總線,用于連接微控制器及其外圍設備,它具有以下特點。

        1、只有兩條總線線路:一條串行數據線SDA,一條串行時鐘線SCL。

        2、每個連接到總線的器件都可以使用軟件根據它的唯一的地址來確定。

        3、傳輸數據的設備之間是簡單的主從關系。

        4、主機可以用作主機發送器或者主機接收器。

        5、它是一個真正的多主機總線,兩個或多個主機同時發起數據傳輸時,可以通過沖突檢測和仲裁來防止數據被破壞。

        6、串行的8位雙向傳輸,位速在標準模式下可達 100kbit/s,在快速模式下可達400kbit/s,在高速模式下可待3.4Mbit/s。

        7、片上的濾波器可以增加抗干擾能力,保證數據的完整性。

        8、連接到同一總線上的IC數量只受到總線的最大電容400Pf的限制。

如上圖所示,啟動一個傳輸時,主機先發送一個S信號,然后發送8位數據。這8位數據的前7位為從機地址,第八位表示傳輸的方向(0表示寫,1表示讀),如果有數據則繼續發送,最后發出P信號停止。

信號類型:


    注意:正常數據傳輸時,SDA 在 SCL 為低電平時改變,在 SCL 為高電平時保持穩定。

    開始信號 S 信號:

        SCL 為高電平時,SDA由高電平向低電平跳變,開始傳送數據。

    結束信號 P 信號:

        SCL 為高電平時,SDA由低電平向高電平跳變,結束傳送數據。

    響應信號 ACK:

        接收器在接收到8位數據后,在第9個時鐘周期,拉低 SDA 電平

    注意:在第9個時鐘周期,發送器保持SDA為高,如果有ACK,那么第9個時鐘周期SDA為低電平,如果沒有為高電平,發送器根據電平高低分辨是否有ACK信號。

          如果使能了IIC中斷,發送完8bit數據后,主機自動進入中斷處理函數,此時SCL被發送器拉低,讓接收器被迫等待。恢復傳輸只需要清除中斷掛起。


2、 s3c2440 讀寫流程

    1、設置傳輸模式 IICSTAT[7-6],我們做實驗與AT24C08通信時,2440作為主機,因此只用到主機發模式和主機收模式。

    2、寫入從機地址到 IICDS[7-1],此時IICDS[7-1]位表示從機地址,第0位不關心。如 AT24C08 為 0xA0(最低位寫0了,發送到數據線上的7位地址的后邊以為才表示收發,這里雖然寫0但并不是根據這里的0來真正發送的)。

    3、寫 0xF0(寫) 或 0xB0(讀)到 IICSTAT 寄存器, 高兩位表示 傳輸模式前邊設置過了,設置IICSTT[5-4] 為 11,使能傳輸,發送S信號。

    4、IIC控制器自動將第2步中設置的 IICDS[7-1] 再根據 傳輸模式 補充 IICDS[0]位,發送出去。

    5、進入第9個時鐘周期,此時,從機決定是否發出ACK信號,主機進入中斷,判斷是否收到ACK信號,以及是否繼續傳輸。

    繼續發送:

        1、將數據寫入 IICDS 

        2、清除中斷掛起,SCL時鐘恢復,IICDS的數據被自動發送到 SDA 線上,回到第5步。

    停止發送:

        1、寫 0xD0(寫) 和 0x90(讀) 到 IICATAT ,IICATAT[7-6]還是表示的傳輸模式,IICATAT[5-4] == 0 1,發送停止信號

        2、清除中斷掛起,SCL時鐘恢復,發出停止信號

        3、延時,等待停止信號發出

3、 AT24C08 讀寫分析


    1、寫過程

    寫過程與2440芯片的里的寫流程相一致,按照流程寫就OK


    2、讀過程

    讀過程是由2440芯片里的一個寫流程加一個讀流程組合而成,其中寫流程結束沒有發出P信號,而是直接發出了S信號開始讀流程,也就是我為什么加了一道紅線的原因。


附上一份簡單的裸機程序,僅供參考:基于MINI2440



#include

#include "s3c2440.h"

 

void Delay(int time);

 

#define WRDATA      (1)

#define RDDATA      (2)

 

typedef struct tI2C {

    unsigned char *pData;   /* 數據緩沖區 */

    volatile int DataCount; /* 等待傳輸的數據長度 */

    volatile int Status;    /* 狀態 */

    volatile int Mode;      /* 模式:讀/寫 */

    volatile int Pt;        /* pData中待傳輸數據的位置 */

}tS3C24xx_I2C, *ptS3C24xx_I2C;

 

static tS3C24xx_I2C g_tS3C24xx_I2C;

 

/*

 * I2C初始化

 */

void i2c_init(void)

{

    GPEUP  |= 0xc000;       // 禁止內部上拉

/*

 * AT24C08 兩根線 I2CSCL I2CSDA 與 2440芯片相連

 *  配置2440 GPECON GPE15 GPE14引腳為I2C功能

 */

    GPECON |= 0xa0000000;   // 選擇引腳功能:GPE15:IICSDA, GPE14:IICSCL

/* 開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;//主機寫模式   

    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   

// 寫數據

    IICDS = data;  

    IICCON&=~0x10; //clear pending bit   

    while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending   

// 發出停止信號

    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;//主機寫模式   

    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);//主機接受模式  

    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::   

 

// 讀數據

    data = IICDS;  

    //IICCON&=~0x10; //clear pending bit

IICCON = 0x2f; //清掛起狀態,并設置無應答

    while((IICCON & 1<<4) == 0);//udelay(10);//ack period and then interrupt is pending   

    data = IICDS;  

    

//IICCON&=~0x10; //clear pending bit   

IICCON = 0x2f; //清掛起狀態,并設置無應答

    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驅動程序

    這里,我們主要分析驅動里的發送核心算法,至于注冊中斷,IO內存映射,設置寄存器不在討論。

    static int xxx_i2c_xfer(struct i2c_adapter *adpap, struct i2c_msg *msg,int num)

    這個算法函數的作用就是將上層封裝好的一些i2c_msg 進行解析,將數據寫入寄存器,發送出去。在設備驅動層,我們使用了類似i2c_smbus_write_byte 等函數,類似的函數有很多,它們的作用就是封裝i2c_msg 結構(比如讀和寫的 msg 肯定不一樣,讀一個字節和讀多個字節也不一樣),然后調用 i2c_smbus_xfer_emulated->i2c_transfer,最終調用到我們的xxx_i2c_xfer函數進行傳輸。通過分析i2c_smbus_xfer_emulated函數,我們可以了解i2c_msg是如何封裝的。下面,我們簡單分析一下,知道最上層想干什么,我們才能知道實現哪些底層的功能不是。

struct i2c_msg {

__u16 addr; //從機地址

__u16 flags;

__u16 len; // buf 里 有多少個字節

__u8 *buf; // 本 msg 含有的數據,可能是1個字節,可有可能是多個字節

};

    此函數,省略了很多內容,舉例分析而已~,細節請看源碼



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; // 寫操作兩個Msg 讀操作一個msg 這和我們前面分析AT24c08是一致的

struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },

                          { addr, flags | I2C_M_RD, 0, msgbuf1 }

                        };

msgbuf0[0] = command; // 從機地址右移1位得到的,比如AT24C08  為 0x50

switch(size) {

case I2C_SMBUS_BYTE_DATA: // 單字節讀寫

if (read_write == I2C_SMBUS_READ)

msg[1].len = 1;

/*

* 讀:

* msgbuf0[0] = command

*  msg[1].len = 1 ,數據會讀到 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的時候如出一轍,對于一個寫操作,我們只需要一個2440的寫流程對應于這里的一個Msg,然而對于讀操作,我們需要2440的兩個流程,對應于這里的兩個Msg。那么,我們底層控制器驅動需要做的工作就是,取出所有的Msg,將每一個Msg里buf里的數據發送出去,如果有下一個Msg, 那么再將下一個Msg里的buf發送完畢,最后發出P停止信號。還有一點,每發送一個Msg都要先發出S開始信號。


    在看adapter程序之前,我們先來簡單思考一下,發出S開始信號之后,可能有以下3中情況:

        1、當前msg.len == 0 ,如果有ACK直接發出stop信號。這種情況出現在,控制器枚舉設備的時候,因為它只發送S信號以及設備地址,不發送數據。

        2、根據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 */

[1] [2]
關鍵字:I2C協議  adapter 引用地址:I2C協議->裸機程序->adapter驅動程序分析

上一篇:i2c驅動程序全面分析,從adapter驅動程序到設備驅動程序
下一篇:Linux ARMv7中斷向量表搬移(2)

推薦閱讀

近年來,國內新能源產業發展遠超業內預期,電動化已經成為車企無法回避的話題。據乘聯會數據顯示2018年1-10月份,新能源乘用車累計銷量同比增長90.6%至72.6萬輛,大幅超越2017年全年的56萬輛。即便如此,依然有人不看好新能源汽車市場的發展,其最大理論根據就是電動汽車的續航能力始終不能滿足消費者的需求,且在很長一段時間內都難以匹敵傳統燃油車...
(文章來源:中科羅伯特機器人學院) 近年來工業機器人市場的快速發展,使得中國運動控制行業也進入到一個快速發展的階段。而下游需求的進一步釋放,也帶動上游的高速發展,包括直線導軌、滾珠絲杠、齒輪齒條、液(氣)壓缸、齒輪、減速器等傳動核心零部件也出現訂單大幅增長的趨勢,整個運控行業市場呈現不斷增長的發展姿態。工業機器人常用的直線傳動機...
半導體供應商意法半導體(STMicroelectronics,簡稱ST;紐約證券交易所代碼:STM),發布了亞馬遜認證智能物聯網設備參考設計套件。利用AWS IoT Core平臺的Alexa語音服務(AVS)集成功能,新設計套件讓開發者能夠在簡易微控制器(MCU)上開發Alexa內置產品。 AWS IoT Core的AVS集成功能可以徹底改變用戶與智能設備的交互方式,將基于云計算服務的Alexa體驗帶到...
熱成像萬用表是電氣設備的一線故障診斷工具,可用于檢查高電壓設備和變壓器的熱點,檢測保險絲、電線、絕緣體、連接器、拼接件和開關的受熱情況。用279FC的熱像儀進行掃描可以從安全的距離快速檢測諸多電氣問題。通過將兩種工具整合成一種工具,熱成像萬用表可以減輕負擔,提高工作效率。279FC熱像儀與iFlex(柔性電流鉗)兼容,擴展測量功能,并可深入狹...

史海拾趣

問答坊 | AI 解惑

keil arm的代碼開發全過程(軟件工程化)

keil arm的代碼開發可能很復雜,但是其軟件的工程化其實不僅僅是編寫代碼,還包括了編寫文檔、軟件測試、第三方獨立測試等。 其過程主要如下: 1 編寫軟件的需求; 3 編寫軟件開發計劃; 4 編寫軟件代碼; 5 程序員的代碼走讀; 6 程 ...…

查看全部問答∨

IP DSLAM的發展

數字用戶線接入復用器(DSLAM)是xDSL的局端設備。隨著xDSL業務在固網市場的迅速普及,DSLAM技術也在發展,本文旨在對目前的一個熱點問題-IP DSLAM技術進行探討。 一、IP DSLAM產生的背景     傳統的DSLAM是一個完全的ATM架構的設備, ...…

查看全部問答∨

液晶驅動HT1621應用實例

前段時間幫朋友做電表用到了這個東東,今天正好無聊,況且這個網站的交流氣氛這么好,現在我把液晶這部分整理出來做了個測試小程序帖上來,以備大家急用。 這款液晶不如網站上那些點陣LCD的功能強大、應用靈活,但是在做些小產品的時候還是非常適 ...…

查看全部問答∨

數控直流穩壓電源

本帖最后由 paulhyde 于 2014-9-15 03:03 編輯 數控直流穩壓電源,里面有詳細的介紹哦,很適合做比賽的  …

查看全部問答∨

快速傅里葉變換

本帖最后由 paulhyde 于 2014-9-15 09:10 編輯 快速傅里葉變換  …

查看全部問答∨

伺服電機轉子反饋的檢測相位與轉子磁極相位的對齊方式

永磁交流伺服電機的編碼器相位為何要與轉子磁極相位對齊 其唯一目的就是要達成矢量控制的目標,使d軸勵磁分量和q軸出力分量解耦,令永磁交流伺服電機定子繞組產生的電磁場始終正交于轉子永磁場,從而獲得最佳的出力效果,即“類直流特性”,這種控 ...…

查看全部問答∨

請教各位大俠,有沒有免費的能在PDA上實現局域網點點通話的軟件,謝謝!

請教各位大俠,有沒有免費的能在PDA上實現局域網點點通話的軟件,謝謝! PDA操作系統為Mobile6.0 局域網內通話,不需要連接外網,Skepe軟件必須連接外網才能通話,比較郁悶~…

查看全部問答∨

我現在想學藍牙,socket還可以,應該看什么書?

我現在想學藍牙,socket還可以,應該看什么書?謝謝!!!!!…

查看全部問答∨

關于POS開發

欲設計開發一款電子收銀機(pos機),不與電腦相連,就是市面上一般干洗點,茶餐廳,娛樂廳收銀的機器,該選用什么樣的開發板和什么樣的軟件開發平臺呢?請大家推薦一下。…

查看全部問答∨

需要修改接收到的tcp數據包中的ttl該用何種ndis技術?

希望有人能說一下要點和注意事項。 xp sp2 + 2003 sp1 ddk…

查看全部問答∨
小廣播
添点儿料...
无论热点新闻、行业分析、技术干货……
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 安图县| 会东县| 巫山县| 通山县| 延庆县| 阿勒泰市| 河源市| 东平县| 墨玉县| 阜康市| 益阳市| 神木县| 阿巴嘎旗| 藁城市| 涡阳县| 眉山市| 巩留县| 庆元县| 绥德县| 蓝田县| 恩平市| 北安市| 方正县| 庄浪县| 炉霍县| 洪江市| 康马县| 高雄县| 喀喇沁旗| 大石桥市| 永靖县| 鞍山市| 滦平县| 花莲市| 锡林郭勒盟| 霍林郭勒市| 东辽县| 林口县| 怀柔区| 镇沅| 永善县|