新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機學習之二十:E2PROM芯片24C02的讀寫程序

        單片機學習之二十:E2PROM芯片24C02的讀寫程序

        作者: 時間:2016-11-18 來源:網絡 收藏
        E2PROM芯片24C02讀寫程序

        本文引用地址:http://www.104case.com/article/201611/315894.htm

        一、實驗目的:

        給24C02的內部RAM寫入一組數據,數據從24C02內部RAM的01h開始存放。然后再把這組數據讀出來,檢驗寫入和讀出是否正確。

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

        二、理論知識準備:

        上面兩個實驗主要學習的是利用單片機的串口進行通訊,本實驗要介紹的是基于I2C總線的串行通訊方法,下面我們先介紹一下I2C總線的相關理論知識。

        (一)、I2C總線概念

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

        (二)、I2C總線結構

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

        一個典型的I2C總線應用系統的組成結構如下圖所示(假設圖中的微控制器、LCD驅動、E2PROM、ADC各器件都是具有I2C總線接口的器件):


        我們知道單片機串行通訊的發送和接收一般都各用一條線TXD和RXD,而I2C總線的數據線既可以發送也可以接受,工作方式可以通過軟件設置。所以,I2C總線結構的硬件結構非常簡潔。

        當某器件向總線上發送信息時,它就是發送器,而當其從總線上接收信息時,又成為接收器。

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

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

        1、位傳輸

        I2C總線每傳送一位數據必須有一個時鐘脈沖。被傳送的數據在時鐘SCL的高電平期間保持穩定,只有在SCL低電平期間才能夠改變,示意圖如下圖所示,在標準模式下,高低電平寬度必須不小于4.7us。

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

        開始信號:當SCL為高電平時,SDA發生從高到低的跳變,就定義為開始信號。

        停止信號:當SCL為高電平時,SDA發生從低到高的跳變,就定義為結束信號。

        開始和結束信號的時序圖如下圖所示:

        2、數據傳輸的字節格式

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

        好啦,了解了I2C傳輸數據的格式,現在來研究雙方傳送的協議問題。

        3、 I2C數據傳輸協議

        I2C總線的數據傳輸協議如下:

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

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

        (3)、從機產生應答信號,進入下一個傳送周期,如果從器件沒有給出應答信號,此時主器件產生一個結束信號使得傳送結束,傳送數據無效。

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

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

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

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

        VCC,GND:電源、地引腳

        A2A1A0:地址引腳

        SCLK、SDA:通信引腳

        WP:寫保護引腳

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

        (五)、程序分析

        寫過程:

        (1)、主機首先發出開始信號

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

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

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

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

        讀過程:

        (1)、主機發出start信號

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

        (大家可能要問:我們是讀數據,為什么要發寫信號呢?這是因為你首先要送出一個信號,說明從24C02中的哪個地址讀取數據。)

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

        (4)、主機發start信號

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

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

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

        在這個程序中,我們把開始信號,結束信號、寫一個字節數據、讀一個字節數據都編制成為通用的子程序,便于在程序中隨時調用。發送和接受應答位的過程放到子程序中,這樣可以使得程序結構簡化。具體的程序如下所示,希望大家認真理解。

        三、實驗程序

        Org 0000h

        I2cdata equ 30h ;發送數據緩沖區的首址

        2402data equ 01h ;接受緩沖區首址

        numdata equ 03h ;傳送的字節數,傳送3個字節

        Sda bit p1.7

        Scl bit p1.6

        Ajmp main

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

        Mainwr: Lcall start ;啟動

        Mov r7,#0a0h

        Lcall send ;發送寫24C02的尋址字節

        Mov r7,#2402data

        Lcall send ;發送數據存入24C02的地址

        Mov r5,#Numdata ;欲發送的字節數

        Mov r0,#i2cdata ;發送緩沖區的首址

        wrloop: Mov a,@r0

        Mov r7,a

        Inc r0

        Lcall send

        Djnz r5, wrloop ;把3個字節的數據發送出去

        lcall stop ;停止

        lcall d1s

        mov r5,#Numdata ; 要讀取的字節數重新賦值

        Mainre: lcall start ;啟動

        Mov r7,#0a0h

        Lcall send ;發送寫24C02的尋址字節

        Mov r7,#2402data

        Lcall send ;發接受緩沖區首址

        Lcall start ; 再次啟動

        Mov r7,#0a1h

        Lcall send ;發送讀24C02的尋址字節

        Reloop: Lcall read ;調用讀取一個字節數據的子程序

        mov p0,r7 ;把讀進來的數送到p0口顯示

        lcall d1s

        lcall d1s

        Djnz r5,reloop

        Lcall stop ;3字節讀取完畢發出停止信號

        Ajmp $

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

        mov 30h,#48h

        mov 31h,#0ebh

        mov 32h,#52h

        ret

        start: setb sda ;啟動信號子程序,大家可以參考開始信號的時序圖

        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是發送一個字節子程序

        send: mov r6,#08h

        mov a,r7 ;要發送的數在r7中

        sendlop1 : rlc a ;左環移,把A的最高位移入cy

        mov sda,c ;把cy的值通過sda發送出去

        setb scl ;在scl上產生一個時鐘

        lcall d5u

        clr scl

        djnz r6, sendlop1 ;重復8次,發送一個字節

        ;cack是檢查應答信號的子程序

        cack: setb sda ;主機首先拉高sda

        setb scl ;發出一個時鐘

        lcall d5u

        sendlop2:mov c,sda ;讀入sda的狀態,如果是0表示接受到了應答

        jc sendlop2

        clr scl ;接受到應答位,結束時鐘

        ret

        read: mov r6,#08h ;讀取一個字節子程序

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

        setb scl ;發出一個時鐘

        lcall d5u

        mov c,sda ;讀入sda狀態

        rlc a ;把該位的狀態移入A中

        clr scl ;結束時鐘

        djnz r6,readlop1 ;重復8次,讀入一個字節

        mov r7,a ;讀進來的數放在r7中

        ;sack是發送應答位子程序

        sack: clr sda ;拉低sda線

        setb scl ;發出時鐘信號

        lcall d5u

        clr scl

        setb sda

        ret

        d5u: nop ;延時5us子程序

        nop

        nop

        nop

        nop

        ret

        d1s: mov r1,#100 ;延時1s子程序

        del1: mov r4,#20

        del2: mov r3,#0ffh

        del3: djnz r3,del3

        djnz r4,del2

        djnz r1,del1

        ret

        end

        大家把這個程序下載到測試板上面,發現數碼管依次顯示數字0、1、2



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 龙山县| 阿拉善右旗| 建瓯市| 德化县| 本溪| 星子县| 酉阳| 永宁县| 泰顺县| 永川市| 南充市| 腾冲县| 仙游县| 尚志市| 乌兰浩特市| 田东县| 鹤峰县| 若羌县| 皋兰县| 治多县| 英德市| 上高县| 宽城| 呈贡县| 高青县| 九江市| 科尔| 建湖县| 巴里| 遂溪县| 广平县| 潼关县| 梨树县| 阿坝县| 北票市| 增城市| 云安县| 贵南县| 和硕县| 柏乡县| 乌苏市|