<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)學(xué)習(xí)之二十:E2PROM芯片24C02的讀寫程序

          單片機(jī)學(xué)習(xí)之二十:E2PROM芯片24C02的讀寫程序

          作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          E2PROM芯片24C02讀寫程序

          本文引用地址:http://www.ex-cimer.com/article/201611/315894.htm

          一、實(shí)驗(yàn)?zāi)康模?/p>

          給24C02的內(nèi)部RAM寫入一組數(shù)據(jù),數(shù)據(jù)從24C02內(nèi)部RAM的01h開始存放。然后再把這組數(shù)據(jù)讀出來,檢驗(yàn)寫入和讀出是否正確。

          在這里我們給24C02中寫入0、1、2的段碼,然后把它讀出來,送到數(shù)碼管顯示。

          二、理論知識準(zhǔn)備:

          上面兩個(gè)實(shí)驗(yàn)主要學(xué)習(xí)的是利用單片機(jī)的串口進(jìn)行通訊,本實(shí)驗(yàn)要介紹的是基于I2C總線的串行通訊方法,下面我們先介紹一下I2C總線的相關(guān)理論知識。

          (一)、I2C總線概念

          I2C總線是一種雙向二線制總線,它的結(jié)構(gòu)簡單,可靠性和抗干擾性能好。目前很多公司都推出了基于I2C總線的外圍器件,例如我們學(xué)習(xí)板上的24C02芯片,就是一個(gè)帶有I2C總線接口的E2PROM存儲器,具有掉電記憶的功能,方便進(jìn)行數(shù)據(jù)的長期保存。

          (二)、I2C總線結(jié)構(gòu)

          I2C總線結(jié)構(gòu)很簡單,只有兩條線,包括一條數(shù)據(jù)線(SDA)和一條串行時(shí)鐘線(SCL)。具有I2C接口的器件可以通過這兩根線接到總線上,進(jìn)行相互之間的信息傳遞。連接到總線的器件具有不同的地址,CPU根據(jù)不同的地址進(jìn)行識別,從而實(shí)現(xiàn)對硬件系統(tǒng)簡單靈活的控制。

          一個(gè)典型的I2C總線應(yīng)用系統(tǒng)的組成結(jié)構(gòu)如下圖所示(假設(shè)圖中的微控制器、LCD驅(qū)動(dòng)、E2PROM、ADC各器件都是具有I2C總線接口的器件):


          我們知道單片機(jī)串行通訊的發(fā)送和接收一般都各用一條線TXD和RXD,而I2C總線的數(shù)據(jù)線既可以發(fā)送也可以接受,工作方式可以通過軟件設(shè)置。所以,I2C總線結(jié)構(gòu)的硬件結(jié)構(gòu)非常簡潔。

          當(dāng)某器件向總線上發(fā)送信息時(shí),它就是發(fā)送器,而當(dāng)其從總線上接收信息時(shí),又成為接收器。

          (三)、I2C總線上的數(shù)據(jù)傳送

          下面我們看看I2C總線是如何進(jìn)行數(shù)據(jù)傳送的。我們知道,在一根數(shù)據(jù)線上傳送數(shù)據(jù)時(shí)必須一位一位的進(jìn)行,所以我們首先研究位傳送。

          1、位傳輸

          I2C總線每傳送一位數(shù)據(jù)必須有一個(gè)時(shí)鐘脈沖。被傳送的數(shù)據(jù)在時(shí)鐘SCL的高電平期間保持穩(wěn)定,只有在SCL低電平期間才能夠改變,示意圖如下圖所示,在標(biāo)準(zhǔn)模式下,高低電平寬度必須不小于4.7us。

          那么是不是所有I2C總線中的信號都必須符合上述的有效性呢?只有兩個(gè)例外,就是開始和停止信號。

          開始信號:當(dāng)SCL為高電平時(shí),SDA發(fā)生從高到低的跳變,就定義為開始信號。

          停止信號:當(dāng)SCL為高電平時(shí),SDA發(fā)生從低到高的跳變,就定義為結(jié)束信號。

          開始和結(jié)束信號的時(shí)序圖如下圖所示:

          2、數(shù)據(jù)傳輸?shù)淖止?jié)格式

          SDA傳送數(shù)據(jù)是以字節(jié)為單位進(jìn)行的。每個(gè)字節(jié)必須是8位,但是傳輸?shù)淖止?jié)數(shù)量不受限制,首先傳送的是數(shù)據(jù)的最高位。每次傳送一個(gè)字節(jié)完畢,必須接收到從機(jī)發(fā)出的一個(gè)應(yīng)答位,才能開始下一個(gè)字節(jié)的傳輸。如果沒有接受到應(yīng)答位,主機(jī)則產(chǎn)生一個(gè)停止條件結(jié)束本次的傳送。那么從機(jī)應(yīng)該發(fā)出什么信號算是產(chǎn)生了應(yīng)答呢?這個(gè)過程是這樣的。當(dāng)主器件傳送一個(gè)字節(jié)后,在第9個(gè)SCL時(shí)鐘內(nèi)置高SDA線,而從器件的響應(yīng)信號將SDA拉低,從而給出一個(gè)應(yīng)答位。

          好啦,了解了I2C傳輸數(shù)據(jù)的格式,現(xiàn)在來研究雙方傳送的協(xié)議問題。

          3、 I2C數(shù)據(jù)傳輸協(xié)議

          I2C總線的數(shù)據(jù)傳輸協(xié)議如下:

          (1)、主器件發(fā)出開始信號

          (2)、主器件發(fā)出第一個(gè)字節(jié),用來選通相應(yīng)的從器件。其中前7位為地址碼,第8位為方向位(R/W)。方向位為“0”表示發(fā)送,方向位為“1”表示接受。

          (3)、從機(jī)產(chǎn)生應(yīng)答信號,進(jìn)入下一個(gè)傳送周期,如果從器件沒有給出應(yīng)答信號,此時(shí)主器件產(chǎn)生一個(gè)結(jié)束信號使得傳送結(jié)束,傳送數(shù)據(jù)無效。

          (4)、接下來主、從器件正式進(jìn)行數(shù)據(jù)的傳送,這時(shí)在I2C總線上每次傳送的數(shù)據(jù)字節(jié)數(shù)不限,但每一個(gè)字節(jié)必須為8位(傳送的時(shí)候先送高位,再送低位)。當(dāng)一個(gè)字節(jié)傳送完畢時(shí),再發(fā)送一個(gè)應(yīng)答位(第9位),如上一條所述,這樣每次傳送一個(gè)字節(jié)都需要9個(gè)時(shí)鐘脈沖。數(shù)據(jù)的傳送過程如下圖所示:

          (四)、24C02芯片相關(guān)介紹

          AT24C02是帶有I2C總線接口的E2PROM存儲器,具有掉電記憶的功能,并且可以象普通RAM一樣用程序改寫。它的容量是256個(gè)字節(jié)(00h~0ffh),有A2、A1、A0三位地址,可見I2C總線上可以連接8片AT24C02,它的尋址字節(jié)是1010 A2A1A0 R/W。板上面24C02的電路連接如圖所示:

          我們對引腳的功能作一個(gè)簡單的解釋:

          VCC,GND:電源、地引腳

          A2A1A0:地址引腳

          SCLK、SDA:通信引腳

          WP:寫保護(hù)引腳

          從上面的電路連接知:A2A1A0=000,可見如果要對24C02進(jìn)行寫操作,尋址字節(jié)是1010 000 0;如果對24C02進(jìn)行讀操作,尋址字節(jié)是1010 000 1。用單片機(jī)的P1.6腳作為串行時(shí)鐘線,用P1.7腳作串行數(shù)據(jù)線。

          (五)、程序分析

          寫過程:

          (1)、主機(jī)首先發(fā)出開始信號

          (2)、發(fā)出寫24C02的尋址字節(jié)1010 000 0,即0A0H

          (3)、發(fā)數(shù)據(jù)寫入24C02的地址,本例中為01H

          (4)、往24C02中寫入數(shù)據(jù),這里是3個(gè)字節(jié),分別為48h,0ebh,52h。

          (5)、寫完畢發(fā)出停止信號

          讀過程:

          (1)、主機(jī)發(fā)出start信號

          (2)、發(fā)寫24C02的尋址字節(jié)1010 000 0

          (大家可能要問:我們是讀數(shù)據(jù),為什么要發(fā)寫信號呢?這是因?yàn)槟闶紫纫统鲆粋€(gè)信號,說明從24C02中的哪個(gè)地址讀取數(shù)據(jù)。)

          (3)、發(fā)要讀取的數(shù)據(jù)在24C02中的地址,即01h

          (4)、主機(jī)發(fā)start信號

          (5)、發(fā)讀24C02的尋址字節(jié)1010 000 1

          (5)、從24 C02中讀取數(shù)據(jù)

          (6)、讀取完畢發(fā)出停止信號

          在這個(gè)程序中,我們把開始信號,結(jié)束信號、寫一個(gè)字節(jié)數(shù)據(jù)、讀一個(gè)字節(jié)數(shù)據(jù)都編制成為通用的子程序,便于在程序中隨時(shí)調(diào)用。發(fā)送和接受應(yīng)答位的過程放到子程序中,這樣可以使得程序結(jié)構(gòu)簡化。具體的程序如下所示,希望大家認(rèn)真理解。

          三、實(shí)驗(yàn)程序

          Org 0000h

          I2cdata equ 30h ;發(fā)送數(shù)據(jù)緩沖區(qū)的首址

          2402data equ 01h ;接受緩沖區(qū)首址

          numdata equ 03h ;傳送的字節(jié)數(shù),傳送3個(gè)字節(jié)

          Sda bit p1.7

          Scl bit p1.6

          Ajmp main

          Main: Lcall init ;初始化給30h,31h,32h中存入0,1,2的段碼

          Mainwr: Lcall start ;啟動(dòng)

          Mov r7,#0a0h

          Lcall send ;發(fā)送寫24C02的尋址字節(jié)

          Mov r7,#2402data

          Lcall send ;發(fā)送數(shù)據(jù)存入24C02的地址

          Mov r5,#Numdata ;欲發(fā)送的字節(jié)數(shù)

          Mov r0,#i2cdata ;發(fā)送緩沖區(qū)的首址

          wrloop: Mov a,@r0

          Mov r7,a

          Inc r0

          Lcall send

          Djnz r5, wrloop ;把3個(gè)字節(jié)的數(shù)據(jù)發(fā)送出去

          lcall stop ;停止

          lcall d1s

          mov r5,#Numdata ; 要讀取的字節(jié)數(shù)重新賦值

          Mainre: lcall start ;啟動(dòng)

          Mov r7,#0a0h

          Lcall send ;發(fā)送寫24C02的尋址字節(jié)

          Mov r7,#2402data

          Lcall send ;發(fā)接受緩沖區(qū)首址

          Lcall start ; 再次啟動(dòng)

          Mov r7,#0a1h

          Lcall send ;發(fā)送讀24C02的尋址字節(jié)

          Reloop: Lcall read ;調(diào)用讀取一個(gè)字節(jié)數(shù)據(jù)的子程序

          mov p0,r7 ;把讀進(jìn)來的數(shù)送到p0口顯示

          lcall d1s

          lcall d1s

          Djnz r5,reloop

          Lcall stop ;3字節(jié)讀取完畢發(fā)出停止信號

          Ajmp $

          init: mov p2,#0ffh ;初始化,30h、31h、32h中存入0、1、2的段碼

          mov 30h,#48h

          mov 31h,#0ebh

          mov 32h,#52h

          ret

          start: setb sda ;啟動(dòng)信號子程序,大家可以參考開始信號的時(shí)序圖

          setb scl

          lcall d5u

          clr sda

          lcall d5u

          clr scl

          ret

          stop: clr sda ;停止信號子程序

          setb scl

          lcall d5u

          setb sda

          lcall d5u

          clr sda

          clr scl

          ret

          ;send是發(fā)送一個(gè)字節(jié)子程序

          send: mov r6,#08h

          mov a,r7 ;要發(fā)送的數(shù)在r7中

          sendlop1 : rlc a ;左環(huán)移,把A的最高位移入cy

          mov sda,c ;把cy的值通過sda發(fā)送出去

          setb scl ;在scl上產(chǎn)生一個(gè)時(shí)鐘

          lcall d5u

          clr scl

          djnz r6, sendlop1 ;重復(fù)8次,發(fā)送一個(gè)字節(jié)

          ;cack是檢查應(yīng)答信號的子程序

          cack: setb sda ;主機(jī)首先拉高sda

          setb scl ;發(fā)出一個(gè)時(shí)鐘

          lcall d5u

          sendlop2:mov c,sda ;讀入sda的狀態(tài),如果是0表示接受到了應(yīng)答

          jc sendlop2

          clr scl ;接受到應(yīng)答位,結(jié)束時(shí)鐘

          ret

          read: mov r6,#08h ;讀取一個(gè)字節(jié)子程序

          readlop1: setb sda ;置sda為輸入方式

          setb scl ;發(fā)出一個(gè)時(shí)鐘

          lcall d5u

          mov c,sda ;讀入sda狀態(tài)

          rlc a ;把該位的狀態(tài)移入A中

          clr scl ;結(jié)束時(shí)鐘

          djnz r6,readlop1 ;重復(fù)8次,讀入一個(gè)字節(jié)

          mov r7,a ;讀進(jìn)來的數(shù)放在r7中

          ;sack是發(fā)送應(yīng)答位子程序

          sack: clr sda ;拉低sda線

          setb scl ;發(fā)出時(shí)鐘信號

          lcall d5u

          clr scl

          setb sda

          ret

          d5u: nop ;延時(shí)5us子程序

          nop

          nop

          nop

          nop

          ret

          d1s: mov r1,#100 ;延時(shí)1s子程序

          del1: mov r4,#20

          del2: mov r3,#0ffh

          del3: djnz r3,del3

          djnz r4,del2

          djnz r1,del1

          ret

          end

          大家把這個(gè)程序下載到測試板上面,發(fā)現(xiàn)數(shù)碼管依次顯示數(shù)字0、1、2



          評論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();