打印

24C02的问题 已经解决 并附上OK的程序

[复制链接]
2816|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feiyuneiio|  楼主 | 2007-10-29 12:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是我想把46H,47H两个字节写入24C02 再重新读出到26H和27H中
可是读出的结果是26H,27H的内容都为47H中的内容。。。。。
实在不得其解 
我的目标是对24C02进行16个字节的读写
希望那位大哥帮个忙啊
    SDA    EQU    P3.7    ;定义24C02SDA对应引脚
    SCL    EQU    P1.0    ;定义24C02SCL对应引脚
    ;-----------------------------------------------------
    ORG    0000H
    AJMP    MAIN
MAIN:    MOV    SP,#60H    
    MOV    46H,#16H
    MOV    47H,#33H
    ACALL    WR_24C02
    ACALL    RD_24C02
    SLEEP:    ACALL    DELAY0.5S
    MOV    PCON,#02H    ;置CPU为掉电方式
    ;=========写子程序==========
WR_24C02:    ACALL    WRITE_24C02A
    ACALL    DELAY
    ACALL    WRITE_24C02B
    ACALL    DELAY
    RET
    ;=========读子程序====================
RD_24C02:    ACALL    READ_24C02A
    ACALL    READ_24C02B
    RET
    ;=========写入数据=====================
WRITE_24C02A:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    MOV    A,#00H    ;取存储地址
    ACALL    SENTBYTE
    MOV    A,46H    ;去发送的数据
    ACALL    SENTBYTE    ;发送一次数据
    ACALL    DELAY10
    ACALL    STOP    ;发送IC总线停止条件
 RET
WRITE_24C02B:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    MOV    A,#01H    ;取存储地址
    ACALL    SENTBYTE
    MOV    A,47H    ;去发送的数据
    ACALL    SENTBYTE    ;发送一次数据
    ACALL    DELAY10
    ACALL    STOP    ;发送IC总线停止条件
RET
    ;============读数据==============
READ_24C02A:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    
    ACALL    SENTBYTE    ;24C02总线地址
    MOV    A,#00H    ;取存储地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    ACALL    START    ;发送IC总线重复起始条件
    MOV    A,#0A1H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送被控制总线地址
    ACALL    RCVBYTE    ;接受数据
    MOV    26H,A    ;接受的数据送入P1口
    ACALL    STOP    ;发送IC总线停止条件
  RET
READ_24C02B:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    ;
    ACALL    SENTBYTE    ;24C02总线地址
    MOV    A,#00H    ;取存储地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    ACALL    START    ;发送IC总线重复起始条件
    MOV    A,#0A1H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送被控制总线地址
    ACALL    RCVBYTE    ;接受数据
    MOV    27H,A    ;接受的数据送入P1口
    ACALL    STOP    ;发送IC总线停止条件
 RET    
    ;=================总线起始条件子程序============================
START:    SETB    SDA    ;发送起始条件的数据信号
    NOP
    NOP
    NOP
    SETB    SCL    ;发送起始条件的时钟信号
    NOP
    NOP
    NOP
    CLR    SDA    ;发送起始信号
    NOP
    NOP
    NOP
    CLR    SCL    ;钳住IC总线准备发送或接受数据
    RET
    ;==================发送子程序==================
SENTBYTE:    MOV    R0,#08H    ;送数8位
SENTB:    RLC    A    ;要发送的数据左移,发送入位C
    MOV    SDA,C
    NOP
    NOP
    NOP
    SETB    SCL    ;置时钟线为高,通知被控制开始接受数据位
    NOP
    NOP
    NOP
    CLR    SCL    ;钳住总线准备接受下一个数据位
    DJNZ    R0,SENTB    ;8位没发送完继续发送
    NOP
    NOP
    SETB    SDA    ;8位发送完后释放数据为准备接受应答
    NOP
    NOP
    SETB    SCL    ;开始接受应答信号
    NOP
    NOP
REP:    MOV    C,SDA
    JC    REP
    NOP
    CLR    SCL    ;发送结束钳住总线准备下一步接受或发送数据或进行其他处理
    RET
    ;=====================接收子程序=================
RCVBYTE:    SETB    SDA    ;置数据线为输入方式
    MOV    R0,#08H    ;要传送的数据长度为8位
RCV:    NOP
    CLR    SCL    ;置时钟线为低,准备接受数据
    NOP
    NOP
    NOP
    NOP
    NOP
    SETB    SCL    ;置时钟线为高使数据线上数据有效
    NOP
    NOP
    MOV    C,SDA    ;接收的数据位放入ACC
    RLC    A
    NOP
    NOP
    DJNZ    R0,RCV    ;8位没接受完继续接受
    CLR    SCL    ;8位接受完置时钟线和数据线
    NOP
    NOP
    CLR    SDA
    SETB    SDA    ;接受非应答信号
    NOP
    NOP
    SETB    SCL    ;置时钟线为高,使应答位有效
    NOP
    NOP
    SETB    SDA
    NOP
    NOP
    NOP
    CLR    SCL    ;清时钟线钳住IC总线以便发送停止条件
    RET
    ;====================停止条件子程序=====================
STOP:    CLR    SDA    ;发送停止条件的数据信号
    NOP
    NOP
    NOP
    SETB    SCL    ;发送停止条件的时钟信号
    NOP
    NOP
    NOP
    SETB    SDA    ;发送IC总线停止信号
    NOP
    NOP
    NOP
    NOP
    RET
DELAY0.5S:    MOV    R6,#30
0.5SL1:    MOV    R5,#250
0.5SL2:    NOP
    DJNZ    R5,0.5SL2
    DJNZ    R6,0.5SL1
    RET
DELAY5US:    NOP
    NOP
    RET
DELAY:    MOV    R0,#255
LPP1:    MOV    R1,#255
LPP2:    NOP
    NOP
    NOP
    DJNZ    R1,LPP2
    DJNZ    R0,LPP1
    RET
DELAY10:    MOV    44H,#30H    ;延时10毫秒等待数据写完
D1:    MOV    45H,#50H
D2:    DJNZ    45H,D2
    DJNZ    44H,D1
    RET
    END

相关帖子

沙发
john_light| | 2007-10-29 12:57 | 只看该作者

STOP后再DELAY

功能相同的操作可以只写一个子程序,在调用时传递不同的参数

使用特权

评论回复
板凳
feiyuneiio|  楼主 | 2007-10-29 13:00 | 只看该作者

谢大哥 我试试看啊

使用特权

评论回复
地板
feiyuneiio|  楼主 | 2007-10-29 13:06 | 只看该作者

..........还是不行啊

这回换成 26H,27H中的数据全是46H中的数了

使用特权

评论回复
5
john_light| | 2007-10-29 15:10 | 只看该作者

READ_24C02B那里送的应该是01地址

MOV    A,#01H

这汇编,唉

复制粘贴害的。

使用特权

评论回复
6
john_light| | 2007-10-29 15:11 | 只看该作者

如果要操作的地址是连续的

它会自动增址

没法看……

使用特权

评论回复
7
ayb_ice| | 2007-10-29 15:16 | 只看该作者

GOOGLE ...

使用特权

评论回复
8
feiyuneiio|  楼主 | 2007-10-29 15:31 | 只看该作者

...我郁闷了

改了可以了 谢谢啊 我还记得我特意去看这地址来着。因为我原来还特意给地址分配了个寄存器来着 

使用特权

评论回复
9
feiyuneiio|  楼主 | 2007-10-29 15:33 | 只看该作者

郁闷

改了可以了 谢谢啊 我还记得我特意去看这地址来着。因为我原来还特意给地址分配了个寄存器来着 

使用特权

评论回复
10
feiyuneiio|  楼主 | 2007-10-29 15:34 | 只看该作者

我等等再改成连续读写的

有问题的话再帮帮忙拉 呵呵

使用特权

评论回复
11
feiyuneiio|  楼主 | 2007-10-30 09:17 | 只看该作者

改过的程序,造福大家

我只实验了连续读写16个数据,理论上应该读写N个数据没问题了有需要的拿去用吧 同时希望前辈们能加以指点 把这个程序改得更好
;=========写子程序==========
WR_24C02:    MOV    R0,#00H    ;存储地址
    MOV    R1,#40H    ;数据地址
    MOV    R2,#10H    ;数据个数
WRL1:    ACALL    WRITE24C02
    INC    R0
    INC    R1
    DJNZ    R2,WRL1
    RET
    ;=========读子程序====================
RD_24C02:    MOV    R0,#00H    ;存储地址
    MOV    R1,#20H    ;数据地址
    MOV    R2,#10H    ;数据个数
RDL1:    ACALL    READ24C02
    INC    R0
    INC    R1
    DJNZ    R2,RDL1
    RET
    ;=========写入数据=====================
WRITE24C02:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    MOV    A,R0    ;取存储地址
    ACALL    SENTBYTE
    MOV    A,@R1    ;去发送的数据
    ACALL    SENTBYTE    ;发送一次数据
    ACALL    STOP    ;发送IC总线停止条件
    ACALL    DELAY10MS
    RET
    ;============读数据==============
READ24C02:    ACALL    START    ;发送IC总线起始条件
    MOV    A,#0A0H    
    ACALL    SENTBYTE    ;24C02总线地址
    MOV    A,R0    ;取存储地址
    ACALL    SENTBYTE    ;发送24C02器件总线地址
    ACALL    START    ;发送IC总线重复起始条件
    MOV    A,#0A1H    ;24C02总线地址
    ACALL    SENTBYTE    ;发送被控制总线地址
    ACALL    RCVBYTE    ;接受数据
    MOV    @R1,A    ;接受的数据送入P1口
    ACALL    STOP    ;发送IC总线停止条件
    RET
    ;=================总线起始条件子程序============================
START:    SETB    SDA    ;发送起始条件的数据信号
    NOP
    NOP
    NOP
    SETB    SCL    ;发送起始条件的时钟信号
    NOP
    NOP
    NOP
    CLR    SDA    ;发送起始信号
    NOP
    NOP
    NOP
    CLR    SCL    ;钳住IC总线准备发送或接受数据
    RET
    ;==================发送子程序==================
SENTBYTE:    MOV    R7,#08H    ;送数8位
SENTB:    RLC    A    ;要发送的数据左移,发送入位C
    MOV    SDA,C
    NOP
    NOP
    NOP
    SETB    SCL    ;置时钟线为高,通知被控制开始接受数据位
    NOP
    NOP
    NOP
    CLR    SCL    ;钳住总线准备接受下一个数据位
    DJNZ    R7,SENTB    ;8位没发送完继续发送
    NOP
    NOP
    SETB    SDA    ;8位发送完后释放数据为准备接受应答
    NOP
    NOP
    SETB    SCL    ;开始接受应答信号
    NOP
    NOP
REP:    MOV    C,SDA
    JC    REP
    NOP
    CLR    SCL    ;发送结束钳住总线准备下一步接受或发送数据或进行其他处理
    RET
    ;=====================接收子程序=================
RCVBYTE:    SETB    SDA    ;置数据线为输入方式
    MOV    R7,#08H    ;要传送的数据长度为8位
RCV:    NOP
    CLR    SCL    ;置时钟线为低,准备接受数据
    NOP
    NOP
    NOP
    NOP
    NOP
    SETB    SCL    ;置时钟线为高使数据线上数据有效
    NOP
    NOP
    MOV    C,SDA    ;接收的数据位放入ACC
    RLC    A
    NOP
    NOP
    DJNZ    R7,RCV    ;8位没接受完继续接受
    CLR    SCL    ;8位接受完置时钟线和数据线
    NOP
    NOP
    CLR    SDA
    SETB    SDA    ;接受非应答信号
    NOP
    NOP
    SETB    SCL    ;置时钟线为高,使应答位有效
    NOP
    NOP
    SETB    SDA
    NOP
    NOP
    NOP
    CLR    SCL    ;清时钟线钳住IC总线以便发送停止条件
    RET
    ;====================停止条件子程序=====================
STOP:    CLR    SDA    ;发送停止条件的数据信号
    NOP
    NOP
    NOP
    SETB    SCL    ;发送停止条件的时钟信号
    NOP
    NOP
    NOP
    SETB    SDA    ;发送IC总线停止信号
    NOP
    NOP
    NOP
    NOP
    RET

使用特权

评论回复
12
ayb_ice| | 2007-10-30 09:30 | 只看该作者

模拟IIC太简单了

使用特权

评论回复
13
john_light| | 2007-10-30 10:39 | 只看该作者

经典的东西再简单也要动手去做

大姑娘总要上花轿的

使用特权

评论回复
14
john_light| | 2007-10-30 10:43 | 只看该作者

jianyi

将读写子例程改为通用的例程:把要操作的起始地址(1)要操作的字节总数(2)要操作的数据源/目标地址(3)作为参数输入。

用C语言来写。

使用特权

评论回复
15
古道热肠| | 2007-10-30 16:16 | 只看该作者

解决了就好!

  逐步转向用C语言编程吧,查找问题和维护都会更方便些,可移植性就更不用说了。

使用特权

评论回复
16
lihua28| | 2009-1-11 11:37 | 只看该作者

太感谢这位仁兄了!

谢谢这位同仁!我拿去用了,刚测试了下,感觉不错,代码也不算多,太谢了,为了这个功能,我看书都看了不少,也试着写了很多次,不是代码太多就是没有功能,现总算有点起色了,太谢谢兄弟了!以后多交流,这个网站真好,有问题,在这里总是能得到帮助,新的一年来了,也同时祝福所有的同行能再上一层楼,勇攀电子技术的高峰,再次谢谢本站站长及所有工作人员!谢谢!

使用特权

评论回复
17
lihua28| | 2009-5-23 14:34 | 只看该作者

单片机电平跳变检测

使用特权

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

本版积分规则

1

主题

7

帖子

0

粉丝