<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機學(xué)習之二十:E2PROM芯片24C02的讀寫(xiě)程序

單片機學(xué)習之二十:E2PROM芯片24C02的讀寫(xiě)程序

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

本文引用地址:http://dyxdggzs.com/article/201611/315894.htm

一、實(shí)驗目的:

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

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

二、理論知識準備:

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

(一)、I2C總線(xiàn)概念

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

(二)、I2C總線(xiàn)結構

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

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


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

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

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

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

1、位傳輸

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

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

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

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

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

2、數據傳輸的字節格式

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

好啦,了解了I2C傳輸數據的格式,現在來(lái)研究雙方傳送的協(xié)議問(wèn)題。

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

I2C總線(xiàn)的數據傳輸協(xié)議如下:

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

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

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

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

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

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

我們對引腳的功能作一個(gè)簡(jiǎn)單的解釋?zhuān)?/p>

VCC,GND:電源、地引腳

A2A1A0:地址引腳

SCLK、SDA:通信引腳

WP:寫(xiě)保護引腳

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

(五)、程序分析

寫(xiě)過(guò)程:

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

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

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

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

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

讀過(guò)程:

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

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

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

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

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

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

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

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

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

三、實(shí)驗程序

Org 0000h

I2cdata equ 30h ;發(fā)送數據緩沖區的首址

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

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

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ā)送寫(xiě)24C02的尋址字節

Mov r7,#2402data

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

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

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

wrloop: Mov a,@r0

Mov r7,a

Inc r0

Lcall send

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

lcall stop ;停止

lcall d1s

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

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

Mov r7,#0a0h

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

Mov r7,#2402data

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

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

Mov r7,#0a1h

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

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

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

lcall d1s

lcall d1s

Djnz r5,reloop

Lcall stop ;3字節讀取完畢發(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)信號子程序,大家可以參考開(kāi)始信號的時(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è)字節子程序

send: mov r6,#08h

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

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

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

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

lcall d5u

clr scl

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

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

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

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

lcall d5u

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

jc sendlop2

clr scl ;接受到應答位,結束時(shí)鐘

ret

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

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

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

lcall d5u

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

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

clr scl ;結束時(shí)鐘

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

mov r7,a ;讀進(jìn)來(lái)的數放在r7中

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

sack: clr sda ;拉低sda線(xiàn)

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ā)現數碼管依次顯示數字0、1、2



評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>