SPI、I2C、UART的区别和联系
 第一個(gè)區(qū)別當(dāng)然是名字:
 ???? SPI(Serial Peripheral Interface:串行外設(shè)接口);
 ???? I2C(INTER IC BUS)
 ???? UART(Universal Asynchronous Receiver Transmitter:通用異步收發(fā)器)
 第二,區(qū)別在電氣信號(hào)線上:
 ???? SPI總線由三條信號(hào)線組成:串行時(shí)鐘(SCLK)、串行數(shù)據(jù)輸出(SDO)、串行數(shù)據(jù)輸入(SDI)。SPI總線可以實(shí)現(xiàn) 多個(gè)SPI設(shè)備互相連接。提供SPI串行時(shí)鐘的SPI設(shè)備為SPI主機(jī)或主設(shè)備(Master),其他設(shè)備為SPI從機(jī)或從設(shè)備(Slave)。主從設(shè)備 間可以實(shí)現(xiàn)全雙工通信,當(dāng)有多個(gè)從設(shè)備時(shí),還可以增加一條從設(shè)備選擇線。
 ???? 如果用通用IO口模擬SPI總線,必須要有一個(gè)輸出口(SDO),一個(gè)輸入口(SDI),另一個(gè)口則視實(shí)現(xiàn)的設(shè)備類型而定,如果要實(shí)現(xiàn)主從設(shè)備,則需輸入輸出口,若只實(shí)現(xiàn)主設(shè)備,則需輸出口即可,若只實(shí)現(xiàn)從設(shè)備,則只需輸入口即可。
 ???? I2C總線是雙向、兩線(SCL、SDA)、串行、多主控(multi-master)接口標(biāo)準(zhǔn),具有總線仲裁機(jī)制,非常適合在器件之間進(jìn)行近距離、非經(jīng)常性的數(shù)據(jù)通信。在它的協(xié)議體系中,傳輸數(shù)據(jù)時(shí)都會(huì)帶上目的設(shè)備的設(shè)備地址,因此可以實(shí)現(xiàn)設(shè)備組網(wǎng)。
 ???? 如果用通用IO口模擬I2C總線,并實(shí)現(xiàn)雙向傳輸,則需一個(gè)輸入輸出口(SDA),另外還需一個(gè)輸出口(SCL)。(注:I2C資料了解得比較少,這里的描述可能很不完備)
 ???? UART總線是異步串口,因此一般比前兩種同步串口的結(jié)構(gòu)要復(fù)雜很多,一般由波特率產(chǎn)生器(產(chǎn)生的波特率等于傳輸波特率的16倍)、UART接收器、UART發(fā)送器組成,硬件上由兩根線,一根用于發(fā)送,一根用于接收。
 ???? 顯然,如果用通用IO口模擬UART總線,則需一個(gè)輸入口,一個(gè)輸出口。
 第三,從第二點(diǎn)明顯可以看出,SPI和UART可以實(shí)現(xiàn)全雙工,但I(xiàn)2C不行;
 第四,看看牛人們的意見(jiàn)吧!
 ???? wudanyu:I2C線更少,我覺(jué)得比UART、SPI更為強(qiáng)大,但是技術(shù)上也更加麻煩些,因?yàn)镮2C需要有雙向IO的支持,而且使用上拉電阻,我覺(jué)得 抗干擾能力較弱,一般用于同一板卡上芯片之間的通信,較少用于遠(yuǎn)距離通信。SPI實(shí)現(xiàn)要簡(jiǎn)單一些,UART需要固定的波特率,就是說(shuō)兩位數(shù)據(jù)的間隔要相 等,而SPI則無(wú)所謂,因?yàn)樗怯袝r(shí)鐘的協(xié)議。
 ???? quickmouse:I2C的速度比SPI慢一點(diǎn),協(xié)議比SPI復(fù)雜一點(diǎn),但是連線也比標(biāo)準(zhǔn)的SPI要少。
| 同步外設(shè)接口(SPI)是由摩托羅拉公司開(kāi)發(fā)的全雙工同步串行總線,該總線大量用在與EEPROM、ADC、FRAM和顯示驅(qū)動(dòng)器之類的慢速外設(shè)器件通信。 SPI(Serial Peripheral Interface)是一種串行同步通訊協(xié)議,由一個(gè)主設(shè)備和一個(gè)或多個(gè)從設(shè)備組成,主設(shè)備啟動(dòng)一個(gè)與從設(shè)備的同步通訊,從而完成數(shù)據(jù)的交換。SPI 接口由SDI(串行數(shù)據(jù)輸入),SDO(串行數(shù)據(jù)輸出),SCK(串行移位時(shí)鐘),CS(從使能信號(hào))四種信號(hào)構(gòu)成,CS 決定了唯一的與主設(shè)備通信的從設(shè)備,如沒(méi)有CS 信號(hào),則只能存在一個(gè)從設(shè)備,主設(shè)備通過(guò)產(chǎn)生移位時(shí)鐘來(lái)發(fā)起通訊。通訊時(shí),數(shù)據(jù)由SDO 輸出,SDI 輸入,數(shù)據(jù)在時(shí)鐘的上升或下降沿由SDO 輸出,在緊接著的下降或上升沿由SDI 讀入,這樣經(jīng)過(guò)8/16 次時(shí)鐘的改變,完成8/16 位數(shù)據(jù)的傳輸。 SPI通信 SPI總線接口及時(shí)序 ? SPI是一個(gè)環(huán)形總線結(jié)構(gòu),由ss(cs)、sck、sdi、sdo構(gòu)成,其時(shí)序其實(shí)很簡(jiǎn)單,主要是在sck的控制下,兩個(gè)雙向移位寄存器進(jìn)行數(shù)據(jù)交換。 ? 
 這 樣就完成了兩個(gè)寄存器8位的交換,上面的上表示上升沿、下表示下降沿,sdi、sdo相對(duì)于主機(jī)而言的。其中ss引腳作為主機(jī)的時(shí)候,從機(jī)可以把它拉底被 動(dòng)選為從機(jī),作為從機(jī)的是時(shí)候,可以作為片選腳用。根據(jù)以上分析,一個(gè)完整的傳送周期是16位,即兩個(gè)字節(jié),因?yàn)?#xff0c;首先主機(jī)要發(fā)送命令過(guò)去,然后從機(jī)根據(jù) 主機(jī)的名準(zhǔn)備數(shù)據(jù),主機(jī)在下一個(gè)8位時(shí)鐘周期才把數(shù)據(jù)讀回來(lái)? SPI 總線是Motorola公司推出的三線同步接口,同步串行3線方式進(jìn)行通信:一條時(shí)鐘線SCK,一條數(shù)據(jù)輸入線MOSI,一條數(shù)據(jù)輸出線MISO;用于 CPU與各種外圍器件進(jìn)行全雙工、同步串行通訊。SPI主要特點(diǎn)有:可以同時(shí)發(fā)出和接收串行數(shù)據(jù);可以當(dāng)作主機(jī)或從機(jī)工作;提供頻率可編程時(shí)鐘;發(fā)送結(jié)束 中斷標(biāo)志;寫(xiě)沖突保護(hù);總線競(jìng)爭(zhēng)保護(hù)等。圖3示出SPI總線工作的四種方式,其中使用的最為廣泛的是SPI0和SPI3方式(實(shí)線表示): 圖2?? SPI總線四種工作方式 SPI 模塊為了和外設(shè)進(jìn)行數(shù)據(jù)交換,根據(jù)外設(shè)工作要求,其輸出串行同步時(shí)鐘極性和相位可以進(jìn)行配置,時(shí)鐘極性(CPOL)對(duì)傳輸協(xié)議沒(méi)有重大的影響。如果 CPOL=0,串行同步時(shí)鐘的空閑狀態(tài)為低電平;如果CPOL=1,串行同步時(shí)鐘的空閑狀態(tài)為高電平。時(shí)鐘相位(CPHA)能夠配置用于選擇兩種不同的傳 輸協(xié)議之一進(jìn)行數(shù)據(jù)傳輸。如果CPHA=0,在串行同步時(shí)鐘的第一個(gè)跳變沿(上升或下降)數(shù)據(jù)被采樣;如果CPHA=1,在串行同步時(shí)鐘的第二個(gè)跳變沿 (上升或下降)數(shù)據(jù)被采樣。SPI主模塊和與之通信的外設(shè)音時(shí)鐘相位和極性應(yīng)該一致。SPI接口時(shí)序如圖3、圖4所示。 二,.SPI功能模塊的設(shè)計(jì) 根據(jù)功能定義及SPI的工作原理,將整個(gè)IP Core分為8個(gè)子模塊:uC接口模塊、時(shí)鐘分頻模塊、發(fā)送數(shù)據(jù)FIFO模塊、接收數(shù)據(jù)FIFO模塊、狀態(tài)機(jī)模塊、發(fā)送數(shù)據(jù)邏輯模塊、接收數(shù)據(jù)邏輯模塊以及中斷形式模塊。 深入分析SPI的四種傳輸協(xié)議可以發(fā)現(xiàn),根據(jù)一種協(xié)議,只要對(duì)串行同步時(shí)鐘進(jìn)行轉(zhuǎn)換,就能得到其余的三種協(xié)議。為了簡(jiǎn)化設(shè)計(jì)規(guī)定,如果要連續(xù)傳輸多個(gè)數(shù)據(jù),在兩個(gè)數(shù)據(jù)傳輸之間插入一個(gè)串行時(shí)鐘的空閑等待,這樣狀態(tài)機(jī)只需兩種狀態(tài)(空閑和工作)就能正確工作。 SPI協(xié)議心得 SPI接口時(shí)鐘配置心得: | 
IIC
型號(hào)? ???容量? ?? ?器件/業(yè)面尋址字節(jié)? ?? ?? ?? ?? ?? ? 可尋址位? ?? ? 模塊24C01? ?128B? ?? ?(1010)(A2)(A1)(A0)(0或1)? ???3? ?? ?? ?? ?128B
24C02? ?256B? ?? ?(1010)(A2)(A1)(A0)(0或1)? ???3? ?? ?? ?? ?256B
24C04? ?512B? ?? ?(1010)(A2)(A1)(P0)(0或1)? ???2? ?? ?? ?? ?2X256B
24C08??1024B? ?? ?(1010)(A2)(P1)(P0)(0或1)? ???1? ?? ?? ?? ?4X256B
24C16??2048B? ?? ?(1010)(P2)(P1)(P0)(0或1)? ???0? ?? ?? ?? ?8X256B
解析:IIC總線接口器件24C系列非易失性存儲(chǔ)器與89C51接口采用軟件模擬IIC。24C系列
存儲(chǔ)器器件地址統(tǒng)一為1010XXXX,不要問(wèn)為什么,這是廠家出廠的時(shí)候規(guī)定好的了。至
于24C的引腳功能和89C51的接口我就不多說(shuō)了,本文的重點(diǎn)主要是如何應(yīng)用。
??上面說(shuō)了,器件的地址字節(jié)的高位是1010,那么低4位呢?先說(shuō)最后一位吧,最后一
位為0的時(shí)候表示89C51要寫(xiě)數(shù)據(jù)入存儲(chǔ)器,1的時(shí)候表示要從存儲(chǔ)器讀數(shù)據(jù)。還剩下中
三位A2,A1和A0。它們的高低電平取決于24C的A2,A1,A0是接高電平還是接地。A2,
A1 和A0有8個(gè)組合,因此可以擴(kuò)展8個(gè)相同的器件,根據(jù)A2、A1、A0的不同,一樣的器件
也會(huì)有不同的地址。那么是不是每一個(gè)24C都可以擴(kuò)展8個(gè)呢?不是的。注意上表,24C01
有三個(gè)可尋址位,A2,A1,A0,所以可以擴(kuò)展8個(gè),24C02也一樣。而04則只可以擴(kuò)展4個(gè)
08只可以擴(kuò)展2個(gè),16就沒(méi)有擴(kuò)展了,只可以掛一片24C16。為什么呢?因?yàn)樵L問(wèn)24C系列
除了訪問(wèn)器件地址外,還要訪問(wèn)器件內(nèi)的字節(jié)的地址。例如24C01,要對(duì)其操作,就先選
選中它的地址,然后操作第一個(gè)字節(jié)或其他字節(jié),這些字節(jié)也是有地址的,分模塊,用
一個(gè)字節(jié)表示,最多可以操作256個(gè)字節(jié)。24C01和24C02不大于256個(gè)字節(jié),對(duì)其操作就
簡(jiǎn)單得多了。但24C04,08和16呢?他們都大于256個(gè)字節(jié),怎么辦?分模塊。注意到上
表的P0,P1,P3沒(méi)有?把04分成兩個(gè)模塊,2X256B,08四個(gè)模塊,16就八個(gè)模塊。究竟
怎么
模塊操作呢?拿24C08為例,有A2 P1 P0。A2只可以0或1,所以只能擴(kuò)展2個(gè)24C08,其
內(nèi)有4個(gè)256字節(jié)的模塊,要操作哪個(gè)模塊取決于P1,P0的組合。例如,24C08的地址字節(jié)
為1010000X第一個(gè)字節(jié)地址為0,第256個(gè)地址為255,如果地址字節(jié)是1010001X,那么第
256個(gè)字節(jié)的地址為0,第512個(gè)字節(jié)的地址為255。就如此。
? ? 再用24C08舉例說(shuō)明如何擴(kuò)展,當(dāng)兩個(gè)24C08的A2腳分別接高電平和地的時(shí)候,就可
以了,這樣就擴(kuò)展了,他們的器件地址分別是1010000X和1010100X。當(dāng)要讀第一個(gè)(A2
接地)
? ?24C08的的第一個(gè)模塊的數(shù)據(jù)時(shí)候,單片機(jī)先發(fā)送地址字節(jié)10100001;當(dāng)要把數(shù)據(jù)寫(xiě)
進(jìn)第二個(gè)(A2接高電平)24C08的第二個(gè)模塊的時(shí)候,應(yīng)發(fā)送10101010地址字節(jié)。
? ? 不再說(shuō)了,再說(shuō)我瘋了,看程序吧。這是對(duì)24C16操作的例子。*/ 復(fù)制內(nèi)容到剪貼板
代碼:
#include <reg51.h>/* 全局符號(hào)定義 */
#define WRITE 0xA0? ?? ?? ?? ?? ?? ?? ?? ?/* 定義24C016的器件地址SLA和方向位W */
#define READ??0xA1? ?? ?? ?? ?? ?? ?? ?? ?/* 定義24C04的器件地址SLA和方向位R */
#define BLOCK_SIZE? ? 100? ?? ?? ?? ?? ?? ?/* 定義指定字節(jié)個(gè)數(shù) */
#define uchar unsigned char
#define HIGH 1
#define LOW 0
#define FALSE 0
#define TRUE ~FALSE
sbit SCL? ? ? ? ? ? ? ? =P3^4;??//T0? ? ? ??
sbit SDA? ? ? ? ? ? ? ? =P3^5;??//T1? ? ? ??
uchar xdata EAROMImage[BLOCK_SIZE]={0}; /* 在外部RAM中定義發(fā)送存儲(chǔ)映象單元 */
void delayi2c( void ) {
? ? ? ? ;
}
void I_start( void ) {
? ? ? ? SCL = HIGH ;
? ? ? ? delayi2c() ;
? ? ? ? SDA = LOW ;
? ? ? ? delayi2c() ;
? ? ? ? SCL = LOW ;
? ? ? ? delayi2c() ;
}
void I_stop( void ) {
? ? ? ? SDA = LOW ;
? ? ? ? delayi2c() ;
? ? ? ? SCL = HIGH ;
? ? ? ? delayi2c() ;
? ? ? ? SDA = HIGH ;
? ? ? ? delayi2c() ;
? ? ? ? SCL = LOW ;
? ? ? ? delayi2c() ;
}
//初始化
void I_init( void ) {
? ? ? ? SCL = LOW ;
? ? ? ? I_stop() ;
}
bit I_clock( void ) {
? ? ? ? bit sample ;
? ? ? ? SCL = HIGH ;
? ? ? ? delayi2c() ;
? ? ? ? sample = SDA ;
? ? ? ? SCL = LOW ;
? ? ? ? delayi2c() ;
? ? ? ? return ( sample ) ;
}
//發(fā)送8位數(shù)據(jù)
bit I_send( uchar I_data ) {
? ? ? ? uchar i ;
? ? ? ? /* 發(fā)送8位數(shù)據(jù) */
? ? ? ? for ( i=0 ; i<8 ; i++ ) {
? ? ? ? ? ? ? ? SDA = (bit)( I_data & 0x80 ) ;
? ? ? ? ? ? ? ? I_data = I_data << 1 ;
? ? ? ? ? ? ? ? I_clock() ;
? ? ? ? }
? ? ? ? /* 請(qǐng)求應(yīng)答信號(hào)ACK */
? ? ? ? SDA = HIGH ;
? ? ? ? return ( ~I_clock() );
??}
//接受8位數(shù)據(jù)
uchar I_receive( void ) {
? ? ? ? uchar I_data = 0 ;
? ? ? ? register uchar i ;
? ? ? ? for ( i=0 ; i<8 ; i++ ) {
? ? ? ? ? ? ? ? I_data *= 2 ;
? ? ? ? ? ? ? ? if (I_clock()) I_data++ ;
? ? ? ? }
? ? ? ? return ( I_data ) ;
}
//應(yīng)答
void I_Ack( void ) {
? ? ? ? SDA = LOW;
? ? ? ? I_clock();
? ? ? ? SDA = HIGH;
}
void wait_5ms( void ) {
? ? ? ? int i ;
? ? ? ? for ( i=0 ; i<1000 ; i++ )?
? ? {
? ? ? ? ? ? ? ? ;
? ? ? ? }
}
//向24C04寫(xiě)入器件地址和一個(gè)指定的字節(jié)地址。
bit E_address(uchar page ,uchar Address )?
? ?{
? ? ? ? I_start() ;
? ? ? ? if ( I_send( WRITE +page) )
? ? ? ? ? ? ? ? return ( I_send( Address ) ) ;
? ? ? ? else
? ? ? ? ? ? ? ? return ( FALSE ) ;
? ?}
//參數(shù)的含義:從第幾個(gè)模塊(不超過(guò)3),模塊中第幾個(gè)字節(jié)(不超過(guò)255)
//? ?? ?? ?? ?寫(xiě)到RAM映象的第幾個(gè)字節(jié)和讀的長(zhǎng)度
bit E_read_block(uchar page, uchar addr,uchar arraypoint,uchar longth)
? ?{
? ? ? ? uchar i ;
? ? ? ? /* 從地址0開(kāi)始讀取數(shù)據(jù) */
? ? ? ? if ( E_address(page, addr ) ) {
? ? ? ? ? ? ? ? /* 發(fā)送重復(fù)啟動(dòng)信號(hào) */
? ? ? ? ? ? ? ? I_start() ;
? ? ? ? ? ? ? ? if ( I_send( READ+page ) ) {
? ? ? ? ? ? ? ? ? ? ? ? for ( i=0; i<=longth ;i++ )?
? ?? ?? ?? ?? ?{
? ?? ?? ?? ?? ?? ?EAROMImage[arraypoint+i] =I_receive();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ( i != longth ) I_Ack() ;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? I_clock() ;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? I_stop() ;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? return ( TRUE ) ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? ? ? I_stop() ;
? ? ? ? ? ? ? ? ? ? ? ? return ( FALSE ) ;
? ? ? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else
? ? ? ? ? ? ? ? I_stop() ;
? ? ? ? ? ? ? ? return ( FALSE ) ;
}
bit E_write_block(uchar page,uchar addr,uchar arraypoint,uchar longth) {
? ? ? ? uchar i ;
? ? ? ? for ( i=addr; i<=addr+longth ; i++ ) {
? ? ? ? ? ? ? ? if ( E_address(page,i) && I_send( EAROMImage[arraypoint+i-addr] ) ) {
? ? ? ? ? ? ? ? ? ? ? ? I_stop() ;
? ? ? ? ? ? ? ? ? ? ? ? wait_5ms();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? return ( FALSE ) ;
? ? ? ? }
? ? ? ? return ( TRUE ) ;
}
//test
void??main() {
? ? ? ? EAROMImage[39]=0xfe;
? ? SCON = 0x5a;? ?? ???
? ? TMOD = 0x20;??
? ? TCON = 0x69;??
? ? TH1 =??0xfd;?
? ? ? ? I_init();? ?? ?? ?? ?? ?? ?? ?? ?//??I2C 總線初始化?
? ? ? ? P1=0xFF;
? ? ? ??
? ? ? ? if (E_write_block(0,8,39,1))
? ? ? ? ? ? ? ???P1=0xFE;//p10
? ? ? ? else
? ? ? ? ? ? ? ???{}
? ? ? ? if (E_read_block(0,8,55,1))
? ? ? ? ? ? ? ? {}?
? ? ? ? else
? ? ? ? ? ? ? ? P1=P1&0xFD;
? ? ? ??
? ? ? ? if(EAROMImage[55]==0xfe)?
? ? ? ? P1=P1&0x0FB;?
? ? while(1);
} posted @?2009-02-22 22:41?陳廣強(qiáng) 閱讀(18) |?評(píng)論 (0)?|?編輯 關(guān)于IIC總線
 I2C(Inter-Integrated Circuit)總線是一種由PHILIPS公司開(kāi)發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。I2C總線產(chǎn)生于在80年代,最初為音頻和視頻設(shè) 備開(kāi)發(fā),如今主要在服務(wù)器管理中使用,其中包括單個(gè)組件狀態(tài)的通信。例如管理員可對(duì)各個(gè)組件進(jìn)行查詢,以管理系統(tǒng)的配置或掌握組件的功能狀態(tài),如電源和系 統(tǒng)風(fēng)扇。可隨時(shí)監(jiān)控內(nèi)存、硬盤(pán)、網(wǎng)絡(luò)、系統(tǒng)溫度等多個(gè)參數(shù),增加了系統(tǒng)的安全性,方便了管理。?
 1 I2C總線特點(diǎn)?
 I2C總線最主要的優(yōu)點(diǎn)是其簡(jiǎn)單性和有效性。由于接口直接在組件之上,因此I2C總線占用的空間非常小,減少了電路板的空間和芯片管腳的數(shù)量,降低了互聯(lián)成本。總線的長(zhǎng)度可高達(dá)25英尺,并且能夠以10Kbps的最大傳輸速率支持40個(gè)組件。I2C總線的另一個(gè)優(yōu)點(diǎn)是,它支持多主控(multimastering), 其中任何能夠進(jìn)行發(fā)送和接收的設(shè)備都可以成為主總線。一個(gè)主控能夠控制信號(hào)的傳輸和時(shí)鐘頻率。當(dāng)然,在任何時(shí)間點(diǎn)上只能有一個(gè)主控。?
2 I2C總線工作原理?
 2.1 總線的構(gòu)成及信號(hào)類型?
 I2C總線是由數(shù)據(jù)線SDA和時(shí)鐘SCL構(gòu)成的串行總線,可發(fā)送和接收數(shù)據(jù)。在CPU與被控IC之間、IC與IC之間進(jìn)行雙向傳送,最高傳送速率100kbps。各種被控制電路均并聯(lián)在這條總線上,但就像電話機(jī)一樣只有撥通各自的號(hào)碼才能工作,所以每個(gè)電路和模塊都有唯一的地址,在信息的傳輸過(guò)程中,I2C總線上并接的每一模塊電路既是主控器(或被控器),又是發(fā)送器(或接收器),這取決于它所要完成的功能。CPU發(fā)出的控制信號(hào)分為地址碼和控制量?jī)刹糠?#xff0c;地址碼用來(lái)選址,即接通需要控制的電路,確定控制的種類;控制量決定該調(diào)整的類別(如對(duì)比度、亮度等)及需要調(diào)整的量。這樣,各控制電路雖然掛在同一條總線上,卻彼此獨(dú)立,互不相關(guān)。?
 I2C總線在傳送數(shù)據(jù)過(guò)程中共有三種類型信號(hào), 它們分別是:開(kāi)始信號(hào)、結(jié)束信號(hào)和應(yīng)答信號(hào)。
開(kāi)始信號(hào):SCL為高電平時(shí),SDA由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào):SCL為低電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。?
應(yīng)答信號(hào):接收數(shù)據(jù)的IC在接收到8bit數(shù)據(jù)后,向發(fā)送數(shù) 據(jù)的IC發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)。CPU向受控單元發(fā)出一個(gè)信號(hào)后,等待受控單元發(fā)出一個(gè)應(yīng)答信號(hào),CPU接收到應(yīng)答信號(hào)后,根據(jù)實(shí)際情況 作出是否繼續(xù)傳遞信號(hào)的判斷。若未收到應(yīng)答信號(hào),由判斷為受控單元出現(xiàn)故障。?
 目前有很多半導(dǎo)體集成電路上都集成了I2C接口。帶有I2C接口的單片機(jī)有:CYGNAL的 C8051F0XX系列,PHILIPSP87LPC7XX系列,MICROCHIP的PIC16C6XX系列等。很多外圍器件如存儲(chǔ)器、監(jiān)控芯片等也提供I2C接口。
I2C總線的時(shí)鐘信號(hào)
????在I2C總線上傳送信息時(shí)的時(shí)鐘同步信號(hào)是由掛接在SCL時(shí)鐘線上的所有器件的邏輯“與”完成的。SCL線上由高電平到低電平的跳變將影響到這些器件,一旦某個(gè)器件的時(shí)鐘信號(hào)變?yōu)榈碗娖?#xff0c;將使SCL線上所有器件開(kāi)始并保護(hù)低電平期。此時(shí),低電平周期短的器件的時(shí)鐘由低至高的跳變并不影響SCL線的狀態(tài),這些器件將進(jìn)入高電平等待的狀態(tài)。
????當(dāng)所有器件的時(shí)鐘信號(hào)都變?yōu)楦唠娖綍r(shí),低電平期結(jié) 束,SCL線被釋放返回高電平,即所有的器件都同時(shí)開(kāi)始它們的高電平期。其后,第一個(gè)結(jié)束高電平期的器件又將SCL線拉成低電平。這樣就在SCL線上產(chǎn)生 一個(gè)同步時(shí)鐘。可見(jiàn),時(shí)鐘低電平時(shí)間由時(shí)鐘低電平期最長(zhǎng)的器件決定,而時(shí)鐘高電平時(shí)間由時(shí)鐘高電平期最短的器件決定。
I2C總線的傳輸協(xié)議與數(shù)據(jù)傳送
起始和停止條件
在數(shù)據(jù)傳送過(guò)程中,必須確認(rèn)數(shù)據(jù)傳送的開(kāi)始和結(jié)束。在I2C總線技術(shù)規(guī)范中,開(kāi)始和結(jié)束信號(hào)(也稱啟動(dòng)和停止信號(hào))的定義如圖3所示。
開(kāi)始信號(hào):當(dāng)時(shí)鐘總線SCL為高電平時(shí),數(shù)據(jù)線SDA由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào):當(dāng)SCL線為高電平時(shí),SDA線從低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
開(kāi)始和結(jié)束信號(hào)都是由主器件產(chǎn)生。在開(kāi)始信號(hào)以后,總線即被認(rèn)為處于忙狀態(tài),其它器件不能再產(chǎn)生開(kāi)始信號(hào)。主器件在結(jié)束信號(hào)以后退出主器件角色,經(jīng)過(guò)一段時(shí)間過(guò),總線被認(rèn)為是空閑的。
圖3超始和停止信號(hào)圖
數(shù)據(jù)格式
????I2C總線數(shù)據(jù)傳送采用時(shí)鐘脈沖逐位串行傳送方式,在SCL的低電平期間,SDA線上高、低電平能變化,在高電平期間,SDA上數(shù)據(jù)必須保護(hù)穩(wěn)定,以便接收器采樣接收,時(shí)序如圖4所示。
圖4 數(shù)據(jù)傳送時(shí)序圖
????I2C總線發(fā)送器送到SDA線上的每個(gè)字節(jié)必須為8位長(zhǎng),傳送時(shí)高位在前,低位在后。與之對(duì)應(yīng),主 器件在SCL線上產(chǎn)生8個(gè)脈沖;第9個(gè)脈沖低電平期間,發(fā)送器釋放SDA線,接收器把SDA線拉低,以給出一個(gè)接收確認(rèn)位;第9個(gè)脈沖高電平期間,發(fā)送器 收到這個(gè)確認(rèn)位然后開(kāi)始下一字節(jié)的傳送,下一個(gè)字節(jié)的第一個(gè)脈沖低電平期間接收器釋放SDA。每個(gè)字節(jié)需要9個(gè)脈沖,每次傳送的字節(jié)數(shù)是不受限制的。
????I2C總線的數(shù)據(jù)傳送格式是在I2C總線開(kāi)始信號(hào)后,送出的第一字節(jié)數(shù)據(jù)是用來(lái)選擇從器件地址的,其中前7位為地址碼,第8位為方 向位(R/W)。方向位為“0”表示發(fā)送,即主器件把信息寫(xiě)到所選擇的從器件中;方向位為“1”表示主器件將從從器件讀信息。格式如下:
| 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/W | 
注:前四位固定為1010。
????開(kāi)始信號(hào)后,系統(tǒng)中的各個(gè)器件將自己的地址和主器件送到總線上的地址進(jìn)行比較,如果與主器件發(fā)送到總線上的地址一致,則該器件即被主器件尋址的器件,其接收信息還是發(fā)送信息則由第8位(R/W)決定。發(fā)送完第一個(gè)字節(jié)后再開(kāi)始發(fā)數(shù)據(jù)信號(hào)。
響應(yīng)
????數(shù)據(jù)傳輸必須帶響應(yīng)。相關(guān)的響應(yīng)時(shí)鐘脈沖由主機(jī)產(chǎn)生,當(dāng)主器件發(fā)送完一字節(jié)的數(shù)據(jù)后,接著發(fā)出對(duì)應(yīng)于SCL線上的一個(gè)時(shí)鐘 (ACK)認(rèn)可位,此時(shí)鐘內(nèi)主器件釋放SDA線,一字節(jié)傳送結(jié)束,而從器件的響應(yīng)信號(hào)將SDA線拉成低電平,使SDA在該時(shí)鐘的高電平期間為穩(wěn)定的低電 平。從器件的響應(yīng)信號(hào)結(jié)束后,SDA線返回高電平,進(jìn)入下一個(gè)傳送周期。
????通常被尋址的接收器在接收到的每個(gè)字節(jié)后必須產(chǎn)生一個(gè)響應(yīng)。當(dāng)從機(jī)不能響應(yīng)從機(jī)地址時(shí),從機(jī)必須使數(shù) 據(jù)線保持高電平,主機(jī)然后產(chǎn)生一個(gè)停止條件終止傳輸或者產(chǎn)生重復(fù)起始條件開(kāi)始新的傳輸。如果從機(jī)接收器響應(yīng)了從機(jī)地址但是在傳輸了一段時(shí)間后不能接收更多 數(shù)據(jù)字節(jié),主機(jī)必須再一次終止傳輸。這個(gè)情況用從機(jī)在第一個(gè)字節(jié)后沒(méi)有產(chǎn)生響應(yīng)來(lái)表示。從機(jī)使數(shù)據(jù)線保持高電平主機(jī)產(chǎn)生一個(gè)停止或重復(fù)起始條件。完整的數(shù) 據(jù)傳送過(guò)程如圖5所示。
圖5 完整的數(shù)據(jù)傳送過(guò)程
????I2C總線還具有廣播呼叫地址用于尋址總線上所有器件的功能。若一個(gè)器件不需要廣播呼叫尋址中所提供的任何數(shù)據(jù),則可以忽咯該地址不作響應(yīng)。如果該器件需要廣播呼叫尋址中按需提供的數(shù)據(jù),則應(yīng)對(duì)地址作出響應(yīng),其表現(xiàn)為一個(gè)接收器。
?
 3 總線基本操作?
 I2C規(guī)程運(yùn)用主/從雙向通訊。器件發(fā)送數(shù)據(jù)到總線上,則定義為發(fā)送器,器件接收數(shù)據(jù)則定義為接收器。主器件和從器件都 可以工作于接收和發(fā)送狀態(tài)。 總線必須由主器件(通常為微控制器)控制,主器件產(chǎn)生串行時(shí)鐘(SCL)控制總線的傳輸方向,并產(chǎn)生起始和停止條件。SDA線上的數(shù)據(jù)狀態(tài)僅在SCL為低 電平的期間才能改變,SCL為高電平的期間,SDA狀態(tài)的改變被用來(lái)表示起始和停止條件。參見(jiàn)圖1。
圖1 串行總線上的數(shù)據(jù)傳送順序
 
 3.1 控制字節(jié)?
 在起始條件之后,必須是器件的控制字節(jié),其中高四位為器件類型識(shí)別符(不同的芯片類型有不同的定義,EEPROM一般應(yīng)為1010),接著三位為片選,最后一位為讀寫(xiě)位,當(dāng)為1時(shí)為讀操作,為0時(shí)為寫(xiě)操作。如圖2所示。?
圖2 控制字節(jié)配置
 3.2 寫(xiě)操作 寫(xiě)操作分為字節(jié)寫(xiě)和頁(yè)面寫(xiě)兩種操作,對(duì)于頁(yè)面寫(xiě)根據(jù)芯片的一次裝載的字節(jié)不同有所不同。關(guān)于頁(yè)面寫(xiě)的地址、應(yīng)答和數(shù)據(jù)傳送的時(shí)序參見(jiàn)圖3。?
圖3 頁(yè)面寫(xiě)
3.3 讀操作讀操作有三種基本操作:當(dāng)前地址讀、隨機(jī)讀和順序讀。圖4給出的是順序讀的時(shí)序圖。應(yīng)當(dāng)注意的是:最后一個(gè)讀操作的第9個(gè)時(shí)鐘周期不是“不關(guān)心”。 為了結(jié)束讀操作,主機(jī)必須在第9個(gè)周期間發(fā)出停止條件或者在第9個(gè)時(shí)鐘周期內(nèi)保持SDA為高電平、然后發(fā)出停止條件。
圖4 順序讀
4 實(shí)例:X24C04與MCS-51單片機(jī)軟硬件的實(shí)現(xiàn)X24C04是XICOR公司的CMOS 4096位串行EEPROM,內(nèi)部組織成512×8位。16字節(jié)頁(yè)面寫(xiě)。與MCS-51單片機(jī)接口如圖5所示。由于SDA是漏極開(kāi)路輸出,且可以與任何數(shù) 目的漏極開(kāi)路或集電極 開(kāi)路輸出“線或”(wire-Ored)連接。上拉電阻的選擇可參考X24C04的數(shù)據(jù)? 手冊(cè)。下面是通過(guò)I2C接口對(duì)X24C04進(jìn)行單字節(jié)寫(xiě)操作的例程。流程圖及源程序如 下:????????????????????????????????????????????????????????????????????????????????????????????????
?
圖5 X24C04與51單片機(jī)接口
;名稱:BSENT?
 ;描述:寫(xiě)字節(jié)?
 ;功能:寫(xiě)一個(gè)字節(jié)?
 ;調(diào)用程序:無(wú)?
 ;輸入?yún)?shù):A?
 ;輸出參數(shù):無(wú)?
 ????? BSEND: MOV R2,#08H ;1字節(jié)8位
SENDA: CLR P3.2??? ;?
 ????????RLC A ???????????? ;左移一位?
 ???? MOV P3.3,C???????? ;寫(xiě)一位
SETB P3.2?
 DJNZ R2,SENDA????? ;寫(xiě)完8個(gè)字節(jié)??
 CLR P3.2?????????? ;應(yīng)答信號(hào)?
 SETB P3.3?
 SETB P3.2?
 RET
?
圖6 流程圖
5? 結(jié)束語(yǔ)?
?在I2C總線的應(yīng)用中應(yīng)注意的事項(xiàng)總結(jié)為以下幾點(diǎn)?:?
 ? 1) 嚴(yán)格按照時(shí)序圖的要求進(jìn)行操作,?
 ? 2) 若與口線上帶內(nèi)部上拉電阻的單片機(jī)接口連接,可以不外加上拉電阻。?
 ? 3) 程序中為配合相應(yīng)的傳輸速率,在對(duì)口線操作的指令后可用NOP指令加一定的延時(shí)。?
 ? 4) 為了減少意外的干擾信號(hào)將EEPROM內(nèi)的數(shù)據(jù)改寫(xiě)可用外部寫(xiě)保護(hù)引腳(如果有),或者在EEPROM內(nèi)部沒(méi)有用的空間寫(xiě)入標(biāo)志字,每次上電時(shí)或復(fù)位時(shí)做一次檢測(cè),判斷EEPROM是否被意外改寫(xiě)。
????????????????????????????????????????????????????????????????????? 關(guān)于IIC總線的操作注意事項(xiàng)
| 1、對(duì)IIC總線的一次操作完之后,需要等待一段時(shí)間才能進(jìn)行第二次操作。否則是啟動(dòng)不了總線的:) 2、在時(shí)鐘線(SCL)為高電平的時(shí)候,一定不能動(dòng)數(shù)據(jù)線(SDA)狀態(tài),除非是啟動(dòng)或者結(jié)束總線 | 
????? 我們先來(lái)說(shuō)說(shuō)集電極開(kāi)路輸出的結(jié)構(gòu)。集電極開(kāi)路輸出的結(jié)構(gòu)如圖1所示,右邊的那個(gè)三極管集電極什么都不接,所以叫做集電極開(kāi)路(左邊的三極管為反相之用, 使輸入為"0"時(shí),輸出也為"0")。對(duì)于圖1,當(dāng)左端的輸入為“0”時(shí),前面的三極管截止(即集電極C跟發(fā)射極E之間相當(dāng)于斷開(kāi)),所以5V電源通過(guò) 1K電阻加到右邊的三極管上,右邊的三極管導(dǎo)通(即相當(dāng)于一個(gè)開(kāi)關(guān)閉合);當(dāng)左端的輸入為“1”時(shí),前面的三極管導(dǎo)通,而后面的三極管截止(相當(dāng)于開(kāi)關(guān)斷 開(kāi))。
   我們將圖1簡(jiǎn)化成圖2的樣子。圖2中的開(kāi)關(guān)受軟件控制,“1”時(shí)斷開(kāi),“0”時(shí)閉合。很明顯可以看出,當(dāng)開(kāi)關(guān)閉合時(shí),輸出直接接地,所以輸出電平為0。而當(dāng)開(kāi)關(guān)斷開(kāi)時(shí),則輸出端懸空了,即高阻態(tài)。這時(shí)電平狀態(tài)未知,如果后面一個(gè)電阻負(fù)載(即使很輕的負(fù)載)到地,那么輸出端的電平就被這個(gè)負(fù)載拉到低電平了,所以這個(gè)電路是不能輸出高電平的。?
  再看圖三。圖三中那個(gè)1K的電阻即是上拉電阻。如果開(kāi)關(guān)閉合,則有電流從1K電阻及開(kāi)關(guān)上流過(guò),但由于開(kāi)關(guān)閉和時(shí)電阻為0(方便我們的 討論,實(shí)際情況中開(kāi)關(guān)電阻不為0,另外對(duì)于三極管還存在飽和壓降),所以在開(kāi)關(guān)上的電壓為0,即輸出電平為0。如果開(kāi)關(guān)斷開(kāi),則由于開(kāi)關(guān)電阻為無(wú)窮大(同 上,不考慮實(shí)際中的漏電流),所以流過(guò)的電流為0,因此在1K電阻上的壓降也為0,所以輸出端的電壓就是5V了,這樣就能輸出高電平了。但 是這個(gè)輸出的內(nèi)阻是比較大的(即1KΩ),如果接一個(gè)電阻為R的負(fù)載,通過(guò)分壓計(jì)算,就可以算得最后的輸出電壓為5*R/(R+1000)伏,即5 /(1+1000/R)伏。所以,如果要達(dá)到一定的電壓的話,R就不能太小。如果R真的太小,而導(dǎo)致輸出電壓不夠的話,那我們只有通過(guò)減小那個(gè)1K的上拉 電阻來(lái)增加驅(qū)動(dòng)能力。但是,上拉電阻又不能取得太小,因?yàn)楫?dāng)開(kāi)關(guān)閉合時(shí),將產(chǎn)生電流,由于開(kāi)關(guān)能流過(guò)的電流是有限的,因此限制了上拉電阻的取值,另外還需 要考慮到,當(dāng)輸出低電平時(shí),負(fù)載可能還會(huì)給提供一部分電流從開(kāi)關(guān)流過(guò),因此要綜合這些電流考慮來(lái)選擇合適的上拉電阻。?
  如果我們將一個(gè)讀數(shù)據(jù)用的輸入端接在輸出端,這樣就是一個(gè)IO口了(51的IO口就是這樣的結(jié)構(gòu),其中P0口內(nèi)部不帶上拉,而其它三個(gè)口帶內(nèi)部上拉),當(dāng)我們要使用輸入功能時(shí),只要將輸出口設(shè)置為1即可,這樣就相當(dāng)于那個(gè)開(kāi)關(guān)斷開(kāi),而對(duì)于P0口來(lái)說(shuō),就是高阻態(tài)了。?
 什么是漏極開(kāi)路(OD)?
   對(duì)于漏極開(kāi)路(OD)輸出,跟集電極開(kāi)路輸出是十分類似的。將上面的三極管換成場(chǎng)效應(yīng)管即可。這樣集電極就變成了漏極,OC就變成了OD,原理分析是一樣的。?
   另一種輸出結(jié)構(gòu)是推挽輸出。推挽輸出的結(jié)構(gòu)就是把上面的上拉電阻也換成一個(gè)開(kāi)關(guān),當(dāng)要輸出高電平時(shí),上面的開(kāi)關(guān)通,下面的開(kāi)關(guān)斷;而要輸出低電平時(shí),則剛好相反。比起OC或者OD來(lái)說(shuō),這樣的推挽結(jié)構(gòu)高、低電平驅(qū)動(dòng)能力都很強(qiáng)。 如果兩個(gè)輸出不同電平的輸出口接在一起的話,就會(huì)產(chǎn)生很大的電流,有可能將輸出口燒壞。而上面說(shuō)的OC或OD輸出則不會(huì)有這樣的情況,因?yàn)樯侠娮杼峁┑?電流比較小。如果是推挽輸出的要設(shè)置為高阻態(tài)時(shí),則兩個(gè)開(kāi)關(guān)必須同時(shí)斷開(kāi)(或者在輸出口上使用一個(gè)傳輸門(mén)),這樣可作為輸入狀態(tài),AVR單片機(jī)的一些IO 口就是這種結(jié)構(gòu)。
 
 
1、i2c是雙線單工總線,由一條時(shí)鐘線scl和一條數(shù)據(jù)線sda實(shí)現(xiàn), 加上從機(jī)的data ready(interrupt)線的話是3條線實(shí)現(xiàn)。好處是需要的io口少,壞處是單工收發(fā)慢。
2、spi是四線雙工總線,加上從機(jī)的data ready(interrupt)線的話是5條線實(shí)現(xiàn)。好處是雙工吞吐率大,壞處是線數(shù)較多。
3、以上兩種都是非對(duì)等主從總線,需要由主機(jī)發(fā)起數(shù)據(jù)讀寫(xiě)時(shí)鐘。而uart是雙工對(duì)等總線,沒(méi)有主從之分。優(yōu)劣在于:
a,非對(duì)等總線可以掛載多個(gè)設(shè)備,每個(gè)設(shè)備都能收發(fā)數(shù)據(jù)。對(duì)等總線由于沒(méi)有仲裁機(jī)制,所以只能掛載兩個(gè)同時(shí)收發(fā)數(shù)據(jù)的設(shè)備,或者一個(gè)發(fā)送設(shè)備與多個(gè)接收設(shè)備,又或者自己在應(yīng)用層實(shí)現(xiàn)仲裁(不過(guò)這就失去uart的優(yōu)勢(shì)和意義了)。
b,由于在非對(duì)等總線中必須由主機(jī)發(fā)起時(shí)鐘,數(shù)據(jù)發(fā)送比對(duì)等總線要復(fù)雜得多,特別是當(dāng)你想實(shí)現(xiàn)一些比較復(fù)雜的通信協(xié)議時(shí),幾乎只能使用同步邏輯來(lái)實(shí)現(xiàn),這樣就造成cpu的運(yùn)算速度被數(shù)據(jù)總線速度嚴(yán)重限制。而uart天生就是一個(gè)異步總線,通過(guò)dma可以幾乎不占用cpu時(shí)間。
。
總結(jié)
以上是生活随笔為你收集整理的SPI、I2C、UART的区别和联系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 2018AHU新生赛Panelatta与
- 下一篇: AHU HuffmanTree编码数据结
