24c02读写程序.docx
- 文档编号:6285892
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:23
- 大小:100.18KB
24c02读写程序.docx
《24c02读写程序.docx》由会员分享,可在线阅读,更多相关《24c02读写程序.docx(23页珍藏版)》请在冰豆网上搜索。
24c02读写程序
E2PROM芯片24C02的读写程序
一、实验目的:
给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,它的寻址字节是1010A2A1A0R/W。
板上面24C02的电路连接如图所示:
我们对引脚的功能作一个简单的解释:
VCC,GND:
电源、地引脚
A2A1A0:
地址引脚
SCLK、SDA:
通信引脚
WP:
写保护引脚
从上面的电路连接知:
A2A1A0=000,可见如果要对24C02进行写操作,寻址字节是10100000;如果对24C02进行读操作,寻址字节是10100001。
用单片机的P1.6脚作为串行时钟线,用P1.7脚作串行数据线。
(五)、程序分析
写过程:
(1)、主机首先发出开始信号
(2)、发出写24C02的寻址字节10100000,即0A0H
(3)、发数据写入24C02的地址,本例中为01H
(4)、往24C02中写入数据,这里是3个字节,分别为48h,0ebh,52h。
(5)、写完毕发出停止信号
读过程:
(1)、主机发出start信号
(2)、发写24C02的寻址字节10100000
(大家可能要问:
我们是读数据,为什么要发写信号呢?
这是因为你首先要送出一个信号,说明从24C02中的哪个地址读取数据。
)
(3)、发要读取的数据在24C02中的地址,即01h
(4)、主机发start信号
(5)、发读24C02的寻址字节10100001
(5)、从24 C02中读取数据
(6)、读取完毕发出停止信号
在这个程序中,我们把开始信号,结束信号、写一个字节数据、读一个字节数据都编制成为通用的子程序,便于在程序中随时调用。
发送和接受应答位的过程放到子程序中,这样可以使得程序结构简化。
具体的程序如下所示,希望大家认真理解。
三、实验程序
Org0000h
I2cdata equ30h ;发送数据缓冲区的首址
2402data equ01h ;接受缓冲区首址
numdata equ03h ;传送的字节数,传送3个字节
Sda bitp1.7
Scl bitp1.6
Ajmpmain
Main:
Lcallinit ;初始化给30h,31h,32h中存入0,1,2的段码
Mainwr:
Lcallstart ;启动
Movr7,#0a0h
Lcallsend ;发送写24C02的寻址字节
Movr7,#2402data
Lcallsend ;发送数据存入24C02的地址
Movr5,#Numdata ;欲发送的字节数
Movr0,#i2cdata ;发送缓冲区的首址
wrloop:
Mova,@r0
Movr7,a
Incr0
Lcallsend
Djnzr5,wrloop ;把3个字节的数据发送出去
lcallstop ;停止
lcalld1s
movr5,#Numdata ;要读取的字节数重新赋值
Mainre:
lcallstart ;启动
Movr7,#0a0h
Lcallsend ;发送写24C02的寻址字节
Movr7,#2402data
Lcallsend ;发接受缓冲区首址
Lcallstart ;再次启动
Movr7,#0a1h
Lcallsend ;发送读24C02的寻址字节
Reloop:
Lcallread ;调用读取一个字节数据的子程序
movp0,r7 ;把读进来的数送到p0口显示
lcalld1s
lcalld1s
Djnzr5,reloop
Lcallstop ;3字节读取完毕发出停止信号
Ajmp$
init:
movp2,#0ffh ;初始化,30h、31h、32h中存入0、1、2的段码
mov30h,#48h
mov31h,#0ebh
mov32h,#52h
ret
start:
setbsda ;启动信号子程序,大家可以参考开始信号的时序图
setbscl
lcalld5u
clrsda
lcalld5u
clrscl
ret
stop:
clrsda ;停止信号子程序
setbscl
lcalld5u
setbsda
lcalld5u
clrsda
clrscl
ret
;send是发送一个字节子程序
send:
movr6,#08h
mova,r7 ;要发送的数在r7中
sendlop1:
rlca ;左环移,把A的最高位移入cy
movsda,c ;把cy的值通过sda发送出去
setbscl ;在scl上产生一个时钟
lcalld5u
clrscl
djnzr6,sendlop1 ;重复8次,发送一个字节
;cack是检查应答信号的子程序
cack:
setbsda ;主机首先拉高sda
setbscl ;发出一个时钟
lcalld5u
sendlop2:
movc,sda ;读入sda的状态,如果是0表示接受到了应答
jcsendlop2
clrscl ;接受到应答位,结束时钟
ret
read:
movr6,#08h ;读取一个字节子程序
readlop1:
setbsda ;置sda为输入方式
setbscl ;发出一个时钟
lcalld5u
movc,sda ;读入sda状态
rlca ;把该位的状态移入A中
clrscl ;结束时钟
djnzr6,readlop1 ;重复8次,读入一个字节
movr7,a ;读进来的数放在r7中
;sack是发送应答位子程序
sack:
clrsda ;拉低sda线
setbscl ;发出时钟信号
lcalld5u
clrscl
setbsda
ret
d5u:
nop ;延时5us子程序
nop
nop
nop
nop
ret
d1s:
movr1,#100 ;延时1s子程序
del1:
movr4,#20
del2:
movr3,#0ffh
del3:
djnzr3,del3
djnzr4,del2
djnzr1,del1
ret
end
大家把这个程序下载到测试板上面,发现数码管依次显示数字0、1、2
;简洁的24C02读写汇编程序
;--------------------------------------------
I2C_SDA EQUP1.6 ;PIN5
I2C_SCL EQUP1.7 ;PIN6
;=============================================
I2C_WRITE:
; WRITE8BYTESTOEEROM;INPUT:
A-A*8=EEROMSTARTADDR
; R0-RANSTARTADDR
; USE:
C,A,R0,R6,R7
ACALLI2C_START
ACALLOUT
MOVR6,#8
WR_LP:
MOVA,@R0
ACALLOUT
INCR0
DJNZR6,WR_LP
AJMPI2C_STOP
;==========================================
I2C_READ:
; READ8BYTESFROMEEROM
;INPUT:
A-A*8=EEROMSTARTADDR
; R0-RANSTARTADDR
; USE:
C,A,R0,R6,R7
ACALLI2C_START
ACALLOUT
MOVR6,#8
MOVA,#0A1H;#RDCMD
ACALLOUTS
BRDLP:
MOVR7,#8
SETBI2C_SDA
INLP:
CLR I2C_SCL
ACALLDELAY6
SETB I2C_SCL
NOP
MOVC,I2C_SDA
RLCA
DJNZR7,INLP
CLR I2C_SCL
MOV@R0,A
INCR0
DJNZR6,ACKLP
;;;;----------------------------
I2C_STOP:
CLRI2C_SDA
ACALLDELAY5
SETBI2C_SCL
ACALLDELAY5
SETBI2C_SDA
DELAY6:
NOP
DELAY5:
NOP
RET
;;-----------------------------
I2C_START:
SWAPA
RRA
MOVR6,A
MOVA,#0A0H;#WTCMD
ACALLOUTS
MOVA,R6
RET
;-------------------------------
ACKLP:
CLRI2C_SDA
SETBI2C_SCL
ACALLDELAY5
CLRI2C_SCL
AJMPBRDLP
;=======================
OUTS:
SETBI2C_SDA
SETBI2C_SCL
ACALLDELAY5
CLRI2C_SDA
ACALLDELAY5
CLRI2C_SCL
;========================
OUT:
SETBC
MOVR7,#9
OTLP:
RLCA
NOP
MOVI2C_SDA,C
NOP
NOP
SETBI2C_SCL
ACALLDELAY5
CLR I2C_SCL
DJNZR7,OTLP
RET
;========================
END
;SDAEQUP1.6;(你可以根据你的情况变更引脚)
;SCLEQUP1.7
;D15US,D1MS子程序分别为15uS和1mS延时程序,请根据你的晶体自行编写。
;**************************************************************
;24C01写初始.(传递的数据在R7中).
;**************************************************************
sdabitp1.7
sclbitp1.6
org0000
ajmpstar
org00040
star:
movp3,#00H
mov30H,#01H
mov31h,#88h
nop
nop
nop
acallat2401w
nop
nop
nop
nop
nop
ajmp$
AT2401W:
MOVP1,#0FFH;置SDA/SCL=1
LCALLR2STAR;写开始状态字
MOVR7,#10100000B;SET2401=写
LCALLR2SEND;送
MOVACC,30H;30H指向2401数据的起始地址
MOVR7,ACC;将要写2401的起始地址送到R7
LCALLR2SEND
MOVACC,31H;取第一个号
MOVR7,ACC;数据传递到R7
LCALLR2SEND;写具体号码
LCALLR2STOP;停止
LCALLD1MS;等待一定时间使24C01内部写完成
RET
;------------------------------------------
;写到2401本程序开始及结束SDA&SCL均=0,发送数据在R7
;------------------------------------------
R2SEND:
PUSHACC;保存ACC
MOVACC,R7;将R7中的数发送出去
MOVR6,#08H;往2401发送数据
R2SLOP1:
RLCA;将ACC中的数据移到数据线上
MOVSDA,C;送出数据
LCALLD15US
SETBSCL;发送串行时钟进行写操作
LCALLD15US
CLRSCL
DJNZR6,R2SLOP1;串行发送8BIT
SETBSDA;准备接收ACK
LCALLD15US
SETBSCL;接收ACK的时钟
LCALLD15US
R2SLOP2:
MOVC,SDA;写完后等待确认信号ACK
JCR2SLOP2
CLRSCL;为下一步其它操作做准备
CLRSDA
POPACC;还原ACC
LCALLD1MS;等待内部写完
RET
;*******************************************************************
;2401读初始.
;------------------------------------------------------------------
AT2401RC:
LCALLR2STAR;写状态字
MOVR7,#10100000B;SET2401=WRI
LCALLR2SEND;送出状态字
MOVA,30H;上程序传来的读取地址
MOVR7,A;地址数据送R7
LCALLR2SEND;送出数据
MOVP1,#11111111B;保证SDA/SCL起始=1
LCALLR2STAR
MOVR7,#10100001B;0A1H;读状态
LCALLR2SEND
LCALLR2READ;读所需的数
LCALLR2STOP
RET
;**************************************************************
;设置开始,初始SDA&SCL=1,结束SDA&SCL=0
;--------------------------------------------------------------
R2STAR:
LCALLD15US;对2401操作开始
CLRSDA;在SCL=1时,SDA由1变为0表示开始
LCALLD15US
CLRSCL
LCALL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 24 c02 读写 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)