I2C總線規(guī)范與I2C器件C51讀寫程序(一)
1、I2C總線簡(jiǎn)介:
I2C 總線是一雙線串行總線,它提供一小型網(wǎng)絡(luò)系統(tǒng),為總線上的電路共享公共的總線??偩€上的器件有單片機(jī)、LCD 驅(qū)動(dòng)器以及上E2PROM 器等等。自從菲利普公司提出I2C總線規(guī)范以來(lái),I2C器件得到了廣泛的應(yīng)用。I2C器件的應(yīng)用大大減少了電路間連線,減小了電路板尺寸,降低了硬件成本,并提高了系統(tǒng)可靠性。
2、I2C規(guī)范:
I2C總線規(guī)范可以參考有關(guān)資料,本文僅給出有關(guān)硬件操作的基本概念。
2.1、I2C 總線名詞解釋:
發(fā)送器:發(fā)送數(shù)據(jù)到總線上的器件
接收器:從總線上接收數(shù)據(jù)的器件
主器件:?jiǎn)?dòng)數(shù)據(jù)傳送并產(chǎn)生時(shí)鐘信號(hào)的器件
從器件:被主器件尋址的器件
2.2、I2C總線時(shí)序定義:
起始位:SCL=1時(shí),在SDA上有下降延
停止位:SCL=1時(shí),在SDA上有上升延
*主器件發(fā)停止信號(hào)給從器件,作用在于使從器件處為準(zhǔn)備狀態(tài)(或是已知的狀態(tài))
從應(yīng)答:SDA=0
*寫數(shù)據(jù)時(shí),應(yīng)答的器件在第九個(gè)時(shí)鐘周期將SDA線拉低,表示已收到一個(gè)8位數(shù)據(jù),并表示可繼續(xù)接收。主機(jī)在向從機(jī)寫一字節(jié)后接收從應(yīng)答,再進(jìn)行后續(xù)操作(一般不考慮從應(yīng)答位的具體值,僅在應(yīng)答檢測(cè)時(shí)用于判斷從器件是否完成其內(nèi)部寫周期)
主應(yīng)答:SDA=0(用)
*讀數(shù)據(jù)時(shí),主機(jī)每接收從機(jī)一個(gè)字節(jié)數(shù)據(jù)(不是最后一個(gè)),返回主應(yīng)答ACK(SDA=0)
是最后一個(gè)字節(jié)時(shí)返回?zé)o需應(yīng)答NO_ACK(SDA=1)
當(dāng)從機(jī)工作于讀模式時(shí),在向主機(jī)發(fā)送一個(gè)8位數(shù)據(jù)后釋放SDA線并監(jiān)視一個(gè)應(yīng)答信號(hào),一旦接收到主機(jī)的應(yīng)答信號(hào),從機(jī)繼續(xù)發(fā)送數(shù)據(jù);如主器件沒(méi)有發(fā)送應(yīng)答信號(hào),從機(jī)停止傳送數(shù)據(jù)并等待一個(gè)停止信號(hào),主器件必須發(fā)一個(gè)停止信號(hào)給從機(jī)使其進(jìn)入備用電源模式并使器件處于已知的狀態(tài)
應(yīng)答檢測(cè):采用應(yīng)答檢測(cè)讀命令測(cè)試從機(jī)是否<頁(yè)寫>結(jié)束(通過(guò)從應(yīng)答來(lái)識(shí)別)
*當(dāng)從器件完成內(nèi)部寫周期后將發(fā)送一個(gè)應(yīng)答信號(hào)(從應(yīng)答)給主器件,以便可以繼續(xù)進(jìn)行下一次讀操作
3、I2C器件C51讀寫程序
3.1、數(shù)據(jù)定義說(shuō)明:
sbit sda=P0^0; //I2C器件SDA數(shù)據(jù)線
sbit scl=P0^1; //I2C器件SCL時(shí)鐘線
#define nops() {_nop_();_nop_();_nop_();_nop_();_nop_();} //nop指令個(gè)數(shù)定義
uchar i2c_ad_main; //器件從地址
uchar i2c_ad_sub; //器件子地址
uchar *i2c_buf; //發(fā)送/接收數(shù)據(jù)緩沖區(qū)
uchar i2c_num; //發(fā)送/接收數(shù)據(jù)個(gè)數(shù)
說(shuō)明:可以在你的應(yīng)用程序中修改上述值,使其適應(yīng)你的demo設(shè)計(jì)
3.2、子函數(shù)說(shuō)明:(私有函數(shù),不能調(diào)用)
void i2c_start(void) //送起始位
void i2c_stop(void) //送停止位
void i2c_ack_main(bit ack_main) //主應(yīng)答
說(shuō)明:ack_main=1:ack主應(yīng)答;ack_main=0:no_ack無(wú)需應(yīng)答
void send_byte(uchar c) //發(fā)送單個(gè)字節(jié)
uchar read_byte(void) //接收單個(gè)字節(jié)
說(shuō)明:此函數(shù)需要配合主應(yīng)答來(lái)用
3.3、模塊函數(shù)說(shuō)明:(I2C外部接口函數(shù),可被應(yīng)用程序調(diào)用)
void send_to_byte(uchar ad_main,uchar c) //向無(wú)子地址器件發(fā)送單字節(jié)數(shù)據(jù)
void send_to_nbyte(uchar ad_main,uchar ad_sub,uchar *buf,uchar num)
//向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)
void read_from_byte(uchar ad_main,uchar *buf) //從無(wú)子地址器件讀單字節(jié)數(shù)據(jù)
void read_from_nbyte(uchar ad_main,uchar ad_sub,uchar *buf,uchar num)
//從有子地址器件讀多個(gè)字節(jié)數(shù)據(jù)