AT24C02使用詳解

這篇文章是寫(xiě)給一個(gè)學(xué)弟看的,關(guān)于IIC,關(guān)于24C02的單字節(jié)寫(xiě)入\讀取..頁(yè)寫(xiě)入和讀取,,學(xué)弟總是害怕協(xié)議,,,我總是對(duì)人家說(shuō),本來(lái)就這樣的,協(xié)議就是人家這樣規(guī)定的,,,如果你早生幾十年你也可能規(guī)定個(gè)IIC協(xié)議......

我的單片機(jī)和24C02通信,,,我的單片機(jī)就叫主機(jī),,,24C02叫從機(jī)

先看IIC

IIC協(xié)議規(guī)定開(kāi)始傳輸數(shù)據(jù)的時(shí)候要先發(fā)一個(gè)起始信號(hào),,,目的應(yīng)該是告訴從機(jī)要開(kāi)始通信了,準(zhǔn)備準(zhǔn)備

終止信號(hào)就是拜拜啦,再見(jiàn)!

起始信號(hào)就是 在SCL在高電平期間SDA來(lái)一個(gè)下降沿,,終止信號(hào)就是在SCL在高電平期間SDA來(lái)一個(gè)上升沿(所以協(xié)議上才會(huì)說(shuō),在正常傳輸數(shù)據(jù)的時(shí)候,只有在SCL為低電平的時(shí)候,數(shù)據(jù)線SDA的高低電平狀態(tài)才允許改變,要不然豈不是和起始信號(hào)或者終止信號(hào)沖突了)

/*******************************************************************

起動(dòng)總線函數(shù)

函數(shù)原型: void? Start_I2c();

功能:? ? 啟動(dòng)I2C總線,即發(fā)送I2C起始條件.

********************************************************************/voidStart_I2c()

{

SDA=1;/*發(fā)送起始條件的數(shù)據(jù)信號(hào)*/_Nop();

SCL=1;

_Nop();/*起始條件建立時(shí)間大于4.7us,延時(shí)*/_Nop();

_Nop();

_Nop();

_Nop();

SDA=0;/*發(fā)送起始信號(hào)*/_Nop();/*起始條件鎖定時(shí)間大于4μs*/_Nop();

_Nop();

_Nop();

_Nop();

SCL=0;/*鉗住I2C總線褥实,準(zhǔn)備發(fā)送或接收數(shù)據(jù)*/_Nop();

_Nop();

}

voidStop_I2c()

{

SDA=0;/*發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)*/_Nop();/*發(fā)送結(jié)束條件的時(shí)鐘信號(hào)*/SCL=1;/*結(jié)束條件建立時(shí)間大于4μs*/_Nop();

_Nop();

_Nop();

_Nop();

_Nop();

SDA=1;/*發(fā)送I2C總線結(jié)束信號(hào)*/_Nop();

_Nop();

_Nop();

_Nop();

}

發(fā)送完起始信號(hào)就能傳輸數(shù)據(jù)了

下面是程序

voidSendByte(unsignedcharc)

{

unsignedcharBitCnt;//SCL=0; 起始信號(hào)最后是SCL=0;所以不用寫(xiě)了for(BitCnt=0;BitCnt<8;BitCnt++)/*要傳送的數(shù)據(jù)長(zhǎng)度為8位*/{if((c<

SDA=1;

}else{

SDA=0;

}

_Nop();

SCL=1;/*置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位*/_Nop();

_Nop();/*保證時(shí)鐘高電平周期大于4μs*/_Nop();

_Nop();

_Nop();

SCL=0;

}

_Nop();

_Nop();

SDA=1;/*8位發(fā)送完后釋放數(shù)據(jù)線如筛,準(zhǔn)備接收應(yīng)答位*/_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();if(SDA==1)/*判斷是否接收到應(yīng)答信號(hào)*/ack=0;//沒(méi)有接收到應(yīng)答信號(hào)elseack=1;//接收到應(yīng)答信號(hào)SCL=0;

_Nop();

_Nop();

}

現(xiàn)在說(shuō)一下接收,,,假設(shè)上面發(fā)送完0xaa以后,從機(jī)就返回給我們數(shù)據(jù)(11001100, 0xcc),當(dāng)然SCL為低電平的時(shí)候模塊準(zhǔn)備數(shù)據(jù),,SCL為高電平的時(shí)候,從機(jī)就把數(shù)據(jù)放在了SDA上,這樣循環(huán)8次,一個(gè)8位數(shù)據(jù)就過(guò)來(lái)了

整體上應(yīng)該是

Start_I2c();起始信號(hào)程序

SendByte(0xaa);

判斷下ack是不是等于1,應(yīng)答了(是繼續(xù)執(zhí)行還是停止看自己了)

Data = RcvByte();//接收數(shù)據(jù)

Ack_I2c(1);//發(fā)送非應(yīng)答,就是SDA=1;,這個(gè)程序在下面

Stop_I2c();發(fā)送停止信號(hào)

接收程序如下

unsignedcharRcvByte()

{

unsignedcharretc;

unsignedcharBitCnt;

retc=0;

SDA=1;/*置數(shù)據(jù)線為輸入方式*/for(BitCnt=0;BitCnt<8;BitCnt++)

{

_Nop();

SCL=0;/*置時(shí)鐘線為低训措,準(zhǔn)備接收數(shù)據(jù)位*/_Nop();

_Nop();/*時(shí)鐘低電平周期大于4.7μs*/_Nop();

_Nop();

_Nop();

SCL=1;/*置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/_Nop();

_Nop();

retc=retc<<1;if(SDA==1)retc=retc+1;/*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中*/_Nop();

_Nop();

}

SCL=0;

_Nop();

_Nop();return(retc);

}

應(yīng)答或者非應(yīng)答程序如下

/********************************************************************

應(yīng)答子函數(shù)

函數(shù)原型:? void Ack_I2c(bit a);

功能:? ? ? 主控器進(jìn)行應(yīng)答信號(hào)(可以是應(yīng)答0或非應(yīng)答1信號(hào)廊驼,由位參數(shù)a決定)

********************************************************************/voidAck_I2c(bit a)

{if(a==0)SDA=0;/*在此發(fā)出應(yīng)答或非應(yīng)答信號(hào)*/elseSDA=1;

_Nop();

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();/*時(shí)鐘低電平周期大于4μs*/_Nop();

_Nop();

_Nop();

SCL=0;/*清時(shí)鐘線嫌拣,鉗住I2C總線以便繼續(xù)接收*/_Nop();

_Nop();

}

IIC其實(shí)就這樣了,主要看支持IIC通信的芯片的資料了,寫(xiě)好這些就是IIC通用的了

資料鏈接

https://wenku.baidu.com/view/3fc8558002d276a200292ef9.html

現(xiàn)在看芯片資料如何寫(xiě)進(jìn)去一個(gè)字節(jié)

關(guān)于器件的地址

寫(xiě)就是0xa0;;;;讀就是0xa1

所以寫(xiě)函數(shù)就是

/**

* @brief? 向24C02寫(xiě)數(shù)據(jù)

* @param? Data--數(shù)據(jù)

* @param? Address--地址

* @param? None

* @retval None

* @example

**/unsignedcharWriteData(unsignedcharData,unsignedcharAddress)

{

Start_I2c();

SendByte(0xa0);//最后一位為0寫(xiě)入if(ack==0)return(0);

SendByte(Address);//發(fā)送地址if(ack==0)return(0);

SendByte(Data);//發(fā)送數(shù)據(jù)if(ack==0)return(0);

Stop_I2c();//結(jié)束總線return(1);

}

關(guān)于應(yīng)答哈我的SendByte(unsigned char? c)函數(shù)里面發(fā)送完8位數(shù)據(jù)后就寫(xiě)了應(yīng)答,然后把應(yīng)答標(biāo)志給ack,,后面直接判斷的ack

現(xiàn)在想想為什么叫應(yīng)答...直接說(shuō)判斷從機(jī)正沒(méi)正確接收到數(shù)據(jù)就完了唄,就是把SDA拉高,然后把SCL拉高,等一會(huì)然后判斷SDA引腳有沒(méi)有被從機(jī)拉低,拉低了就說(shuō)明好了......沒(méi)拉低從機(jī)可能接收的數(shù)據(jù)不正確

_Nop();

_Nop();

SDA=1;??????????????? /*8位發(fā)送完后釋放數(shù)據(jù)線恢口,準(zhǔn)備接收應(yīng)答位*/

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();

if(SDA==1)/*判斷是否接收到應(yīng)答信號(hào)*/

ack=0;//沒(méi)有接收到應(yīng)答信號(hào)

else

ack=1;//接收到應(yīng)答信號(hào)

SCL=0;

_Nop();

_Nop();

}

再看從任意地址讀一個(gè)數(shù)據(jù)

注意哈第一個(gè)發(fā)送的器件地址是0xa0,后面的是0xa1

所以程序如下

/**

* @brief? 從24C02讀出數(shù)據(jù)

* @param? None

* @param? Address--地址

* @param? None

* @retval 讀到的數(shù)據(jù)

* @example

**/unsignedcharReadData(unsignedcharAddress)

{

unsignedcharData =0;

Start_I2c();

SendByte(0xa0);//最后一位為0if(ack==0)return(0);

SendByte(Address);//發(fā)送地址if(ack==0)return(0);

Start_I2c();

SendByte(0xa1);//最后一位為1if(ack==0)return(0);

Data=RcvByte();

Ack_I2c(1);//發(fā)送非就答位Stop_I2c();//結(jié)束總線return(Data);

}

現(xiàn)在看頁(yè)寫(xiě)

把程序先放上,對(duì)了寫(xiě)的時(shí)候的開(kāi)始地址最好是0,8,16,24,32,40,68,,,,8的倍數(shù),要不然數(shù)據(jù)可能有錯(cuò)誤,當(dāng)然我用的芯片頁(yè)寫(xiě)最多一次能寫(xiě)入8個(gè)字節(jié).....感覺(jué)有點(diǎn)少哈......可以在現(xiàn)在的基礎(chǔ)上再做一個(gè)函數(shù)實(shí)現(xiàn)哈,,或者用寫(xiě)單字節(jié)的for循環(huán)下....

/**

* @brief? 向24C02寫(xiě)數(shù)據(jù)----頁(yè)寫(xiě),,,最多一次寫(xiě)入8個(gè)字節(jié),多了會(huì)覆蓋前面的

* @param? Data--數(shù)據(jù)

* @param? StartAddress--開(kāi)始的地址--最大255

* @param? None

* @retval None

* @example

**/unsignedcharPageWrite(unsignedchar*Data,unsignedcharAddress,unsignedcharcnt)

{

Start_I2c();

SendByte(0xa0);//最后一位為0寫(xiě)入if(ack==0)return(0);

SendByte(Address);//發(fā)送地址if(ack==0)return(0);while(cnt--)

{

SendByte(*Data++);//發(fā)送數(shù)據(jù)if(ack==0)return(0);

DelayMs(10);

}

Stop_I2c();//結(jié)束總線return(1);

}

現(xiàn)在看頁(yè)讀

看程序

/**

* @brief? 從24C02讀出數(shù)據(jù)----頁(yè)讀

* @param? Data--數(shù)據(jù)指針

* @param? StartAddress--開(kāi)始的地址--最大255

* @param? None

* @retval None

* @example

**/unsignedcharPageRead(unsignedchar*Data,unsignedcharAddress,unsignedcharcnt)

{

Start_I2c();

SendByte(0xa0);//最后一位為0if(ack==0)return(0);

SendByte(Address);//發(fā)送要讀的地址if(ack==0)return(0);

Start_I2c();

SendByte(0xa1);//最后一位為1if(ack==0)return(0);while(cnt--)

{*Data? =RcvByte();

Data++;

Ack_I2c(0);//發(fā)送應(yīng)答位DelayMs(10);

}

Ack_I2c(1);//發(fā)送非應(yīng)答位Stop_I2c();//結(jié)束總線return(1);

}

說(shuō)一下讀的時(shí)候最好開(kāi)始讀取的地址是8的倍數(shù),讀取的數(shù)據(jù)個(gè)數(shù)也是8的倍數(shù),,,我測(cè)試的如果不是這樣有時(shí)候,第二次頁(yè)讀的時(shí)候就會(huì)讀錯(cuò)........

這芯片和8干上了............

還有一個(gè)立即讀,,,看明白就行,就是立即返回當(dāng)前讀地址加1后的那個(gè)數(shù)據(jù)

源碼鏈接

鏈接:http://pan.baidu.com/s/1i4M7BId%20密碼:r9ov

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市差购,隨后出現(xiàn)的幾起案子四瘫,更是在濱河造成了極大的恐慌,老刑警劉巖欲逃,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件找蜜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡稳析,警方通過(guò)查閱死者的電腦和手機(jī)洗做,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)彰居,“玉大人诚纸,你說(shuō)我怎么就攤上這事〕露瑁” “怎么了畦徘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)抬闯。 經(jīng)常有香客問(wèn)我井辆,道長(zhǎng),這世上最難降的妖魔是什么溶握? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任杯缺,我火速辦了婚禮,結(jié)果婚禮上睡榆,老公的妹妹穿的比我還像新娘夺谁。我一直安慰自己,他們只是感情好肉微,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布匾鸥。 她就那樣靜靜地躺著,像睡著了一般碉纳。 火紅的嫁衣襯著肌膚如雪勿负。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天劳曹,我揣著相機(jī)與錄音奴愉,去河邊找鬼。 笑死铁孵,一個(gè)胖子當(dāng)著我的面吹牛锭硼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜕劝,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼檀头,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼轰异!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起暑始,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤搭独,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后廊镜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牙肝,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年嗤朴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了配椭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雹姊,死狀恐怖颂郎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情容为,我是刑警寧澤乓序,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站坎背,受9級(jí)特大地震影響替劈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜得滤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一陨献、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧懂更,春花似錦眨业、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至慷暂,卻和暖如春聘殖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背行瑞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奸腺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人血久。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓突照,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親氧吐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讹蘑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 在使用單片機(jī)的過(guò)程中末盔,I2C 通信可以說(shuō)是最被廣泛使用和采納的協(xié)議之一,采用 I2C 協(xié)議可以占用更少的資源衔肢,鏈接...
    noparkinghere閱讀 2,177評(píng)論 0 8
  • IIC通信實(shí)驗(yàn) IIC簡(jiǎn)介 I2C(Inter-Integrated Circuit)字面上的意思是集成電路之間,...
    btskyrmb閱讀 1,927評(píng)論 0 2
  • i2c總線協(xié)議: 歷史:是飛利浦公司在80年代豁翎,為研發(fā)音視頻模塊的通訊而產(chǎn)生角骤。因其具有的諸多優(yōu)點(diǎn),而沿用至今心剥。 優(yōu)...
    ibo閱讀 1,464評(píng)論 1 1
  • 串行通信的幾個(gè)名詞: 全雙工:數(shù)據(jù)線有2條邦尊,分別用來(lái)發(fā)送和接收。半雙工:數(shù)據(jù)線只有1條优烧,用來(lái)發(fā)送和接收蝉揍,分時(shí)復(fù)用。...
    X_xxieRiemann閱讀 1,594評(píng)論 0 0
  • 1畦娄、嵌入式系統(tǒng)的定義 (1)定義:以應(yīng)用為中心又沾,以計(jì)算機(jī)技術(shù)為基礎(chǔ),軟硬件可裁剪熙卡,適應(yīng)應(yīng)用系統(tǒng)對(duì)功能杖刷、可靠性、成本...
    榮卓然閱讀 1,825評(píng)論 0 5