在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 設(shè)計(jì)應(yīng)用 > 基礎(chǔ)知識之I2C總線

            基礎(chǔ)知識之I2C總線

            —— 基礎(chǔ)知識之串行總線
            作者: 時(shí)間:2024-04-08 來源:電子森林 收藏

            I2C - 集成電路之間的同步、半雙工數(shù)據(jù)傳輸


            I2C是一種簡單地連接多個芯片的總線方式,尤其是在FPGAs/CPLDs中.

            本文引用地址:http://www.biyoush.com/article/202404/457227.htm

            • 除了“電源”和“地”之外,只用了“SDA”和“SCL”兩根信號線
            • 在同一個總線上最多可以支持到100個器件,每個掛在總線的器件都有一個地址用于尋址
            • 多個“主”設(shè)備(例如,兩個CPU可以簡單地共用同一個I2C器件)
            • 為業(yè)界標(biāo)準(zhǔn),由Philips開發(fā), 被很多其它廠商采用
            • 用途非常廣泛,比如電視機(jī)、PCs

            但是:

            • 速度相對比較慢(100Kbps基礎(chǔ)速率,可以擴(kuò)展到3.4Mbps)
            • 不支持“即插即用”

            一個需要至少一個I2C主和I2C從. I2C“主”即可以向“從”寫也可以從“從”設(shè)備中讀取

            I2C波形

            這個圖示為向地址為0x51的EEPROM進(jìn)行寫2個字節(jié)的數(shù)據(jù)0x50和0x0F.

            initiator

            一個I2C過程由“起始”開始, 接著是我們要通信的設(shè)備的地址,有一位標(biāo)記此操作是“讀”還是“寫”;要讀取或?qū)懭氲摹皵?shù)據(jù)”,最后是個“終止”位。

            還有其它的一些細(xì)節(jié),比如在每個字節(jié)傳輸以后需要一個”應(yīng)答“位,參看波形圖。

            在FPGA或CPLD中有兩種方式創(chuàng)建一個I2C從功能:

            • 直接使用你FPGA/CPLD中的SCL信號線作為時(shí)鐘信號
            • 使用更快的時(shí)鐘信號過取樣你的SDA和SCL信號

            第一種方法設(shè)計(jì)比較緊湊,但不如第二種方法可靠,在這里我們簡單講一下第一種方法的實(shí)現(xiàn)過程。

            目標(biāo):通過I2C進(jìn)行IO端口擴(kuò)展,SCL在FPGA/CPLD中作為時(shí)鐘信號

            I2C從模塊連接到一個小的8位存儲器,這個存儲器可以通過進(jìn)行讀寫,這8位為FPGA/CPLD的外部連線,這樣就實(shí)現(xiàn)了一個I2C的IO端口擴(kuò)展

            第一步,先定義模塊

            module I2CslaveWith8bitsIO(SDA, SCL, IOout);inout SDA;input SCL;output [7:0] IOout;

            接著是我們需要的I2C“從”設(shè)備的7位地址

            parameter I2C_ADR = 7'h27;

            接著是“起始”和“終止”檢測邏輯,這也是本設(shè)計(jì)中最神秘的部分。

            // We use two wires with a combinatorial loop to detect the start and stop conditions//  ... making sure these two wires don't get optimized awaywire SDA_shadow    /* synthesis keep = 1 */;wire start_or_stop /* synthesis keep = 1 */;assign SDA_shadow = (~SCL | start_or_stop) ? SDA : SDA_shadow;assign start_or_stop = ~SCL ? 1'b0 : (SDA ^ SDA_shadow); reg incycle;always @(negedge SCL or posedge start_or_stop)if(start_or_stop) incycle <= 1'b0; else if(~SDA) incycle <= 1'b1;

            現(xiàn)在我們可以計(jì)數(shù)進(jìn)來的I2C的位數(shù)。

            reg [3:0] bitcnt;  // counts the I2C bits from 7 downto 0, plus an ACK bitwire bit_DATA = ~bitcnt[3];  // the DATA bits are the first 8 bits sentwire bit_ACK = bitcnt[3];  // the ACK bit is the 9th bit sentreg data_phase; always @(negedge SCL or negedge incycle)if(~incycle)begin
                bitcnt <= 4'h7;  // the bit 7 is received first
                data_phase <= 0;endelsebegin
                if(bit_ACK)
                begin
                	bitcnt <= 4'h7;
                	data_phase <= 1;
                end
                else
                	bitcnt <= bitcnt - 4'h1;end

            并且檢測I2C的地址是否匹配

            wire adr_phase = ~data_phase;reg adr_match, op_read, got_ACK;// sample SDA on posedge since the I2C spec specifies as low as 0μs hold-time on negedgereg SDAr;  always @(posedge SCL) SDAr<=SDA;reg [7:0] mem;wire op_write = ~op_read; always @(negedge SCL or negedge incycle)if(~incycle)begin
                got_ACK <= 0;
                adr_match <= 1;
                op_read <= 0;endelsebegin
                if(adr_phase & bitcnt==7 & SDAr!=I2C_ADR[6]) adr_match<=0;
                if(adr_phase & bitcnt==6 & SDAr!=I2C_ADR[5]) adr_match<=0;
                if(adr_phase & bitcnt==5 & SDAr!=I2C_ADR[4]) adr_match<=0;
                if(adr_phase & bitcnt==4 & SDAr!=I2C_ADR[3]) adr_match<=0;
                if(adr_phase & bitcnt==3 & SDAr!=I2C_ADR[2]) adr_match<=0;
                if(adr_phase & bitcnt==2 & SDAr!=I2C_ADR[1]) adr_match<=0;
                if(adr_phase & bitcnt==1 & SDAr!=I2C_ADR[0]) adr_match<=0;
                if(adr_phase & bitcnt==0) op_read <= SDAr;
                // we monitor the ACK to be able to free the bus when the master doesn't ACK during a read operation
                if(bit_ACK) got_ACK <= ~SDAr;     if(adr_match & bit_DATA & data_phase & op_write) mem[bitcnt] <= SDAr;  // memory writeend

            如有需要驅(qū)動=SDA信號線

            wire mem_bit_low = ~mem[bitcnt[2:0]];wire SDA_assert_low = adr_match & bit_DATA & data_phase & op_read & mem_bit_low & got_ACK;wire SDA_assert_ACK = adr_match & bit_ACK & (adr_phase | op_write);wire SDA_low = SDA_assert_low | SDA_assert_ACK;assign SDA = SDA_low ? 1'b0 : 1'bz; assign IOout = mem;endmodule

            結(jié)果如何?

            此代碼已經(jīng)在Xilinx和Altera的多個器件上進(jìn)行過測試,能夠同硬化的I2C主進(jìn)行通信,在這里可以下載完整的代碼

            不過此代碼有兩個缺點(diǎn)::

            • 在FPGA/CPLD中SCL被用做了時(shí)鐘信號,強(qiáng)烈建議在SCL輸入端加入施密特觸發(fā)器以避免錯誤的行為發(fā)生,如果不加施密特觸發(fā)器,在SCL線上的任何噪聲或振鈴都會導(dǎo)致多余的時(shí)鐘周期,導(dǎo)致功能失效
            • “起始”和“終止”的條件檢查邏輯采用的是組合反饋環(huán)路,這種方式是不建議的。同樣其它電路的異步復(fù)位也不建議采用“周期內(nèi)信號”

            如果你能夠容忍這些缺點(diǎn),這應(yīng)該是I2C從模式非常簡潔的設(shè)計(jì),否則你只能用外部時(shí)鐘對SDA和SCL進(jìn)行過取樣,通過數(shù)字濾波器將毛刺給濾除掉,“起始”和“終止”的檢測也變得比較容易,當(dāng)然代價(jià)就是設(shè)計(jì)變得更復(fù)雜。



            關(guān)鍵詞: 串行總線 I2C總線

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉