如何进行AT24C02存储芯片的串行E2PROM读写

电子说

1.3w人已加入

描述

  24C02中带有片内地址寄存器。每写入或读出一个数据字节后,该地址寄存器自动加1,以实现对下一个存储单元的读写。所有字节均以单一操作方式读取。为降低总的写入时间,一次操作可写入多达8个字节的数据。

  ;这是将0600H地址中以下的8个数据写到24C02的01H为首址单元中去的汇编程序

  ORG 0000H

  SCL BIT P3.4;定义24C02的串行时钟线

  SDA BIT P3.5;定义24C02的串行数据线

  LJMP START

  START:LCALL STAR;调用

  MOV R2,#08H;一个数据有8位

  MOV DPTR,#0600H;定义源数据的位置

  LOOP:MOV A,#00H

  MOVC A,@A+DPTR

  LCALL SDATA

  LCALL ACK

  JC LOOP

  INC DPTR

  DJNZ R2,LOOP

  LCALL STOP;调用停止子程序

  STAR:SETB SDA

  SETB SCL

  NOP

  NOP

  NOP

  NOP

  CLR SDA

  NOP

  NOP

  NOP

  NOP

  CLR SCL

  RET

  SDATA:MOV R0,#08H

  LOOP0:RLC A

  MOV SDA,C

  NOP

  NOP

  SETB SCL

  NOP

  NOP

  NOP

  NOP

  CLR SCL

  DJNZ R0,LOOP0

  RET

  ACK:SETB SDA

  NOP

  NOP

  SETB SCL

  NOP

  NOP

  NOP

  NOP

  MOV C,SDA

  CLR SCL

  RET

  STOP:CLR SDA

  NOP

  NOP

  NOP

  NOP

  SETB SCL

  NOP

  NOP

  NOP

  NOP

  SETB SDA

  NOP

  NOP

  NOP

  NOP

  RET

  ORG 0600H

  DB 0A0H,10H,01H,02H,03H,04H,05H,06H

  END

  读写子程序如下:

  ;写串行E2PROM子程序EEPW

  ; R3=10100000(命令1010+器件3位地址+读/写。 器件地址一个芯片,是000)

  ; (R4)=片内字节地址

  ; (R1)=欲写数据存放地址指针

  ; (R7)=连续写字节数n

  EEPW: MOV P1,#0FFH

  CLR  P1.0  ;发开始信号

  MOV  A,R3  ;送器件地址

  ACALL  SUBS

  MOV  A,R4  ;送片内字节地址

  ACALL SUBS

  AGAIN: MOV A,@R1

  ACALL SUBS ;调发送单字节子程序INC   R1

  DJNZ  R7,AGAIN;连续写n个字节

  CLR    P1.0  ;SDA置0, 准备送停止信号

  ACALL DELAY ;延时以满足传输速率要求

  SETB   P1.1  ;发停止信号

  ACALL DELAY

  SETB   P1.0

  RET

  SUBS: MOV R0,#08H ;发送单字节子程序

  LOOP: CLR P1.1

  RLC  A

  MOV  P1.0,C

  NOP

  SETB P1.1

  ACALL DELAY

  DJNZ R0,LOOP ;循环8次送8个bit

  CLR  P1.1

  ACALL DELAY

  SETB P1.1

  REP: MOV C,P1.0

  JC  REP  ;判应答到否,未到则等待

  CLR  P1.1

  RET

  DELAY: NOP

  NOP

  RET

  ;读串行E2PROM子程序EEPR

  ;(R1)=欲读数据存放地址指针

  ;; R3=10100001(命令1010+器件3位地址+读/写。 器件地址一个芯片,是000)

  ;(R4)=片内字节地址

  ;(R7)=连续读字节数

  EEPR: MOV P1,#0FFH

  CLR  P1.0  ;发开始信号

  MOV  A,R3  ;送器件地址

  ACALL SUBS   ;调发送单字节子程序

  MOV A,R4   ;送片内字节地址

  ACALL SUBS

  MOV P1,#0FFH

  CLR P1.0   ;再发开始信号

  MOV A,R3

  SETB ACC.0  ;发读命令

  ACALL SUBS

  MORE: ACALL SUBR

  MOV @R1,A

  INC R1

  DJNZ R7,MORE

  CLR P1.0

  ACALL DELAY

  SETB P1.1

  ACALL DELAY

  SETB P1.0 ;送停止信号

  RET

  SUBR: MOV  R0,#08H ;接受单字节子程序

  LOOP2: SETB  P1.1

  ACALL DELAY

  MOV C,P1.0

  RLC A

  CLR P1.1

  ACALL DELAY

  DJNZ R0,LOOP2

  CJNE R7,#01H,LOW

  SETB P1.0  ;若是最后一个字节置A=1

  AJMP SETOK

  LOW: CLR P1.0  ;否则置A=0

  SETOK: ACALL DELAY

  SETB  P1.1

  ACALL DELAY

  CLR  P1.1

  ACALL DELAY

  SETB P1.0  ;应答毕,SDA置1

  RET

  程序中多处调用了DELAY子程序(仅两条NOP指令),这是为了满足I2C总线上数据传送速率的要求,只有当SDA数据线上的数据稳定下来之后才能进行读写(即SCL线发出正脉冲)。另外,在读最后一数据字节时,置应答信号为“1”,表示读操作即将完成。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分