打印

谁帮我看看这段I模拟I2C的代码,究竟出了什么问题

[复制链接]
1606|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhlking|  楼主 | 2007-4-21 09:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
;-----------------------
;MCU:AT89C52,Fosc=22.1184MHZ
;程序内容:向AT24C16写一个字节的数据,再读出来,并送到P1口看是否正确
;------------------------


    SDA bit P1.4
    SCL bit P1.5

    ADDRH EQU 20H
    ADDRL EQU 21H
    ADDWH EQU 22H
    ADDWL EQU 23H
    _DATA EQU 24H
 


    ORG 0000H
    LJMP START

    ORG 0030H
START:     
    MOV SP,#60H    

    MOV ADDRH,#00H
    MOV ADDRL,#00H
    MOV ADDWH,#00H
    MOV ADDWL,#00H

    MOV _DATA,#0FH 
    
    LCALL W_24C16    

    LCALL R_24C16
    
    MOV A,25H
    MOV P1,A        ;送到I/O口检测收到的数据是否正确

;    RET
    SJMP $


;---------------------------
;读AT24C16一个字节数据子程序
;---------------------------
R_24C16:
    LCALL _SIGNAL        ;调用发起始信号子程序 
    MOV A,ADDRH        ;取要读数据的高位地址
    CLR C
    RLC A            ;I/O口模拟I2C只能按位读,左环移一位空出R/W位: 0 0 0 0 A10 A9 A8 R/W
    ORL A,#0a0H        ;保留器件地址1010,AT24C系列的EEPROM的型号地址均为1010
                ;1 0 1 0 A10 A9 A8 R/W
                ;AT24C16的片选信号A2A1A0均用硬件拉低的
                ;第一个1表示起始信号,最后一个1表示先写高位地址            
    CALL SEND        ;发送高位地址
    MOV A,ADDRL        ;取低位地址
    LCALL SEND        ;发送低位地址
    LCALL _SIGNAL        ;调用发起始信号子程序,准备传数据
    MOV A,#0A1H        
    LCALL SEND        ;发送本器件地址
    LCALL READ
    CALL STOP        ;调用终止子程序
    RET

;---------------------------
;读数据子程序
;---------------------------
READ:
    MOV R7,#08H
    CLR SCL
READ_LOP:
    CALL DELAY5US
    SETB SDA
    SETB SCL
    CALL DELAY5US
    MOV C,SDA
    MOV A,R2
    RLC A
    MOV R2,A
    CALL DELAY5US
    CLR SCL
    DJNZ R7,READ_LOP
    MOV 25H,A
    CLR SDA            ;应答信号
    CALL DELAY5US
    SETB SCL
    RET
    



;---------------------------
;向AT24C16写入一个字节数据子程序
;---------------------------

W_24C16:

    CALL _SIGNAL        ;调用发起始信号子程序
    MOV A,ADDWH        ;存储单元地址高位0000,0 A10 A9 A8
    CLR C
    RLC A            ;左环移一位空出R/W位: 0 0 0 0 A10 A9 A8 R/W
    ORL A,#0a0H        ;保留器件地址1010,AT24C系列的EEPROM的型号地址均为1010;;第一个1表示起始信号,最后一个0表示先写高位地址
                ;1 0 1 0 A10 A9 A8 0
    CALL SEND        ;调用发送子程序,发送第一个字节        
    MOV A,ADDWL        ;存储单元地址低8位 0 0 0 0 0 0 0 0
    CALL SEND        ;发送低位地址
    MOV A,_DATA        ;把放在DATA里面要发送的数据给A
    CALL SEND        ;发送数据
    CALL STOP        ;调用发送终止信号子程序    
    RET            ;传输结束后必须发送终止子程序
    

;---------------------------
;发送I2C总线终止信号子程序,关闭24C16
;---------------------------
STOP:
    CLR SDA            ;SCL=1时,SDA由0变为1,即为终止信号
    SETB SCL        
    CALL DELAY5US
    SETB SDA
    CALL DELAY5US
    CLR SCL
    CLR SDA
    CALL DELAY5US
    RET


;---------------------------
;发送子程序
;---------------------------
SEND:
    MOV R7,#08H    ;用I/O模拟I2C时,必须按位传输,每个字节8位
    CLR SCL
SEND_LOP:
    RLC A        ;大循环左移
    MOV SDA,C    ;只能按位来传输
    CALL DELAY5US
    SETB SCL    ;;给SCL一个上升沿
    CALL DELAY5US
    CLR SCL        ;开始发送下一位,且SDA上的值只能在SCL为0时才能更改
    DJNZ R7,SEND_LOP
    SETB SDA     ;每次发完一个字节后都要发应答信号
    CALL DELAY5US
    SETB SCL
    CALL DELAY5US
SEND_LOP1:        ;等待AT24C16的应答信号
    MOV C,SDA    ;应答信号一来则SDA变0
    JC SEND_LOP1
    CLR SCL
    RET        


;---------------------------
;发起始信号子程序
;---------------------------

_SIGNAL:
    SETB SCL            ;SCL=1时,SDA由1变为0,即为起始信号
    SETB SDA
    CALL DELAY5US
    CLR SDA
    CALL DELAY5US
    CLR SCL
    CALL DELAY5US
    RET

;-----------------------
;延时5us子程序
;-----------------------

DELAY5US:
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    RET


END

相关帖子

沙发
zhlking|  楼主 | 2007-4-21 11:34 | 只看该作者

帮帮忙啊!

有人指导一下么?

使用特权

评论回复
板凳
jxmemail| | 2007-4-21 22:54 | 只看该作者

出什么问题了?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

116

帖子

0

粉丝