7580|6

2

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于AT24C02的读写问题 [复制链接]

各位大侠,帮帮忙啊.我编了个AT24C02的读写程序,写已经没问题,每次都应答,但是读开始的伪写程序就是不应答,请那为高手帮看看啊!兄弟在这里谢谢了!
ORG 0000H
SCL BIT P1.6;定义24C02的串行时钟线
SDA BIT P1.7;定义24C02的串行数据线
;R0:芯片读/写命令
;R2:片内字节地址
LJMP STAR
ORG 0100
STAR:
MOV P0,#0FFH
ACALL EEPW
ACALL EEPR
;--------------------------------------------------------
;写子程序
;--------------------------------------------------------
EEPW:
ACALL ESTAR  ;发开始信号
  MOV A,#0A0H;送器件地址 10100000(0A0H)
  ACALL SUBS
  MOV A,#09H  ;送片内地址
  ACALL SUBS
      MOV A,#55H; 送一常数
  ACALL SUBS
  ACALL DELAY ;延时以满足传输速率要求
  ACALL ESTOP ;SDA置0, 准备送停止信号
RET
;----------------------------------------------------------
;读子程序
;----------------------------------------------------------
EEPR:
  ACALL ESTAR
  MOV A,#0A0H;送器件地址 10100000(0A0H)
  ACALL SUBS;调发送单字节子程序
MOV P0,#09H  
  MOV A,#09H;送片内字节地址
  ACALL SUBS    ;就是在这不应答了!
MOV P0,#10H
  ACALL ESTAR;发开始信号
  MOV A,#0A1H
  ACALL SUBS
MOV P0,#20H
  ACALL SUBR;读数据
  ;MOV P0,A
  ACALL ESTOP
  RET
;----------------------------------------------------
;开始信号
;----------------------------------------------------
ESTAR:
SETB SDA  ;发送起始条件的数据信号
SETB SCL  ;起始条件建立时间大于4US,延时
NOP
NOP
NOP
NOP
CLR SDA    ;发送起始信号
NOP        ;起始条件建立时间大于4US   
NOP
NOP
NOP
CLR SCL     ;准备发送或接收数据
RET
;------------------------------------------------------
;停止信号
;------------------------------------------------------
ESTOP:
   CLR SDA    ;发送结束条件的数据信号
NOP
NOP
NOP
NOP
SETB SCL   ;发送结束条件的时钟信号
NOP
NOP
NOP
NOP
SETB SDA    ;发送I2C总线结束信号
NOP
NOP
NOP
NOP
RET
;---------------------------------------------------------
;发送单字节子程序
;---------------------------------------------------------
SUBS:MOV R1,#08H  ;字节传送
LOOP:CLR SCL ;时钟信号保持为低,准备发送
NOP
NOP
RLC A
MOV SDA,C
NOP
NOP
SETB SCL     ;置时钟信号为高,开始发送
NOP
NOP
NOP
NOP
DJNZ R1,LOOP ;循环8次,传送8bit
CLR SCL
NOP
NOP
NOP
NOP
SETB SCL
RACK:
MOV C,SDA
JC RACK ;判应答到否,未到则等待
CLR SCL
RET
;---------------------------------------------------------
;接受单字节子程序
;---------------------------------------------------------
SUBR:
MOV R0,#08H ;接受单字节子程序
ERLOOP:
   SETB SCL
NOP
NOP
   NOP
NOP
MOV C,SDA
RLC A
CLR SCL
NOP
NOP
NOP
NOP
DJNZ R0,ERLOOP
SETB SDA ;若是最后一个字节置A=1
NOP
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
SETB SDA ;应答毕,SDA置1
RET
;----------------------------------------------------------
;延时子程序
;----------------------------------------------------------
DELAY:
NOP
NOP
RET
END

最新回复

你在读/写前都要发送的控制指令A0H后要读一次应答位,需要一个时钟脉冲,才能进入一下个写地址字节。当你写操作时,其实写入的数据可能是错的,即缺少一个时钟,但因你读不出来,所以,也不知道写入的数据是否有错误。可是读操作时,因写入的地址字节是错误的,即缺少一个钟脉冲,因此,也就不能进入读数据的操作了。注意,每个写字节的操作后都要读一次应答位,即使不需要应答位,也要给一个时钟脉冲,才能正常进入下一个字节的操作。  详情 回复 发表于 2008-8-30 13:49
点赞 关注
 

回复
举报

19

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
这是发送写指令操作:
MOV A,#0A0H;送器件地址 10100000(0A0H)
如果你要读的话,要用:
MOV A,#0A1H;送器件地址 10100001(0A0H)
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

回复 沙发 的帖子

蓝眼狐你好,从程序来看,LZ好像是要按照指定片内地址进行读操作,流程如下:

1、发送起始信号
2、发送从地址(R/W为0
3、等到确认
4、发送片内地址
5、等待确认
6、重复发送起始信号和从机地址(R/W为1
7、等待确认
8、此时开始读数据

所以从流程上来看应该是没有问题的~以上都是从书上得来的
但是我并没有调试,所以也不清楚问题出在了哪里~~~很抱歉啊~~建议单步调试一下,用示波器看一看时许啥的对不对。
自己没有实践过可能说得也有不对的地方,欢迎指正。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢两位的指导,时序应该没问题,我再试试,那位调试的朋友帮帮忙吧!
 
 
 

回复

19

帖子

0

TA的资源

一粒金砂(初级)

5
 
这里有一个程序,这个我曾使用过,你可以试试看~~~
汇编写的24C01 单字节读写程序
; =======================================================
;         24C01存储器I2C总线实验        汇编语言例子
; =======================================================
;
;      ew51仿真编程器         配套实验板学习例程
;
;      中山单片机学习网       诚电科技       站长:逸风
;
;      http://www.zsMCU.com
;      E-mail:ew51@zsmcu.com
; =======================================================
SDA              EQU       P2.0
SCL        EQU       P2.1
Address          EQU       08H
I2CData         EQU       09H

ORG 0000H

START:
       MOV      SP,#60H

       MOV      Address,#00H
       MOV      I2CData,#55H
       CALL      I2C_WRITE   ;写入数据

       MOV      I2CDATA,#0AAH   ;

       MOV      Address,#00H
       CALL      I2C_READ
       MOV      I2CData,A      ;读出数据
       NOP
       NOP

MAIN:

       JMP        MAIN

/*=======================================================
写一个字节    Address地址  I2CDatata写入的数据
=======================================================*/
I2C_WRITE:
    I2C_WRITE_A:
       LCALL    I2C_START
       MOV      A,#10100000B
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK
       JC   I2C_WRITE_A      ;=1,表示无确认,再次发送
      
       MOV      A,Address
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK      

       MOV      A,I2CData
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK      
       LCALL    I2C_STOP
RET

/*=======================================================
读一个字节    Address地址  Data读出的数据
=======================================================*/

I2C_READ:
    I2C_READ_A:
       LCALL    I2C_START
       MOV      A,#10100000B
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK
       JC   I2C_READ_A ;=1,表示无确认,再次发送

       MOV      A,Address
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK      

    I2C_READ_B:
       LCALL    I2C_START
       MOV      A,#10100001B
       LCALL    I2C_SEND8BIT
       LCALL    I2C_ACK
       JC   I2C_READ_B

       LCALL    I2C_RECEIVE8BIT
       MOV      I2CData,A
       LCALL    I2C_ACK
       LCALL    I2C_STOP
RET
;=======================================================
;发送开始信号
I2C_START:
       SETB      SCL
       SETB      SDA
       NOP
       NOP
       CLR SDA
       NOP
       NOP
       CLR SCL
RET
;=======================================================
;发送结束信号
I2C_STOP:
       CLR SDA
       NOP
       NOP
       SETB      SCL
       NOP
       NOP
       SETB      SDA
RET
;=======================================================
;发送接收确认信号
I2C_ACk:
       SETB      SDA
       SETB      SCL
       NOP
       NOP
       JB    SDA,I2C_ACK0
       CLR C     
       SJMP      I2C_ACK_END
    I2C_ACK0:
       SETB      C
    I2C_ACK_END:
       CLR SCL
RET
;=======================================================
;送八位数据
I2C_SEND8BIT:
       MOV      B,#08H
I2C_SEND8BIT_A:      
       RLC A
      
       MOV      SDA,C
       SETB      SCL
       NOP
       NOP
       CLR SCL
       DJNZ      B,I2C_SEND8BIT_A
RET
;=======================================================
;接收八位数据
I2C_RECEIVE8BIT:
       MOV      B,#08H
       CLR A
       SETB      SDA
I2C_RECEIVE8IT_A:
       SETB      SCL
       NOP
       NOP
       MOV      C,SDA
       RLC A
       CLR SCL
       DJNZ      B,I2C_RECEIVE8IT_A

RET
 
 
 

回复

19

帖子

0

TA的资源

一粒金砂(初级)

6
 
看别人写的汇编程序,我头都大了,:L
眼都看花了~~~~
 
 
 

回复

50

帖子

0

TA的资源

五彩晶圆(高级)

7
 

回复 楼主 的帖子

你在读/写前都要发送的控制指令A0H后要读一次应答位,需要一个时钟脉冲,才能进入一下个写地址字节。当你写操作时,其实写入的数据可能是错的,即缺少一个时钟,但因你读不出来,所以,也不知道写入的数据是否有错误。可是读操作时,因写入的地址字节是错误的,即缺少一个钟脉冲,因此,也就不能进入读数据的操作了。注意,每个写字节的操作后都要读一次应答位,即使不需要应答位,也要给一个时钟脉冲,才能正常进入下一个字节的操作。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表