搜索
bottom↓
回复: 4

用汇编写的IIC通信协议,求教下各位朋友。

[复制链接]

出0入0汤圆

发表于 2011-11-3 22:45:50 | 显示全部楼层 |阅读模式
最近用义隆单片机做东西,需要编写IIC通信协议,不过不需要非常标准,只需要和AT24CXX之间能实现通信就可以,不需要太严格的错误检测。
    选用的芯片是EM78P163N+AT24C02N。
    自己参考网上找的时序写了模拟IIC的 字节写入 字节读出 起始位 结束位 应答位 非应答位 子程序。然后分别写了 写入3个字节,读出3个字节的程序 进行调试,都通过了,写入程序写入后,用读取程序读出校验的结果是正确的。
    但是我把2个测试程序合并到一起,先写入然后读取并校验结果,写入部分正常,读取部分却不行了,通过手动设置测试点的方式,发现就在写和读衔接的地方出问题的。
    写入是正常完成的,读取时第一步先写入IC地址,就是到这一步有问题,一直没应答信号,没有写成功,很奇怪,写入程序和读取程序的这个部分用的一模一样的语句。估计是结束位的时序有问题,但是自己弄了半天没弄出来,所以来求教下各位,怎么回事?
程序如下
INCLUDE "EM78P163N.INC"
    SDA   == PORT6.0
    SCL   == PORT6.1
    SDACR == P6CR
    BS MACRO SDACR;释放SDA线宏
        MOV A,@0X01
        IOW P6CR
    ENDM
    BC MACRO SDACR;占用SDA线宏
        MOV A,@0
        IOW P6CR
    ENDM
    IIC_BIT_NUM == R10
    IIC_DATA    == R11
    IIC_RDDATA0 == R13
    IIC_RDDATA1 == R14
    IIC_RDDATA2 == R15
    IIC_WRDA    == 0B10100000
    IIC_RDDA    == 0B10100001
    IIC_SPK_SIGN== R12.0;响应应答标志位:1有应答,0无应答.
    ORG 0
    ADD A,@0XFF
    ADD A,@0XFF
    ADD A,@0XFF
    ADD A,@0XFF
    ADD A,@0XFF
    JMP MAIN
    ORG 0X20
MAIN:
   ;初始化部分
    MOV A,@0
    IOW P6CR
    IOW P5CR
    MOV A,@0XFF
    MOV PORT6,A
    MOV PORT5,A
    MOV A,@0XF4
    IOW PHCR
    ;写入部分
    MOV A,@IIC_WRDA;写入3个数据
    MOV IIC_DATA,A
    CALL IIC_BEGIN
    CALL IIC_WRITE
    MOV A,@0
    MOV IIC_DATA,A
    CALL IIC_WRITE
    MOV A,@0B01010101
    MOV IIC_DATA,A
    CALL IIC_WRITE
    MOV A,@0B01010101
    MOV IIC_DATA,A
    CALL IIC_WRITE
    MOV A,@0XFF
    MOV IIC_DATA,A
    CALL IIC_WRITE
    CALL IIC_END
    BC PORT5.0;写入结束
    ;读取部分
    MOV A,@IIC_WRDA;读取写入的三个数据
    MOV IIC_DATA,A
    CALL IIC_BEGIN
    CALL IIC_WRITE
    MOV A,@0
    MOV IIC_DATA,A
    CALL IIC_WRITE
    MOV A,@IIC_RDDA
    MOV IIC_DATA,A
    CALL IIC_BEGIN
    CALL IIC_WRITE
    BC PORT5.1;写入读操作命令结束
    CALL IIC_READ
    MOV IIC_RDDATA0,A
    CALL IIC_AN
    CALL IIC_READ
    MOV IIC_RDDATA1,A
    CALL IIC_AN
    CALL IIC_READ
    MOV IIC_RDDATA2,A
    CALL IIC_UNAN
    CALL IIC_END
    ;校验部分
    MOV A,@0B01010101;比较读出的数据是否为写入的数据
    SUB IIC_RDDATA0,A
    JBC Z
    BC PORT6.7
    SUB IIC_RDDATA1,A
    JBC Z
    BC PORT6.6
    SUB IIC_RDDATA2,A
    JBC Z
    BC PORT6.5
LOOP:
    JMP LOOP
;*功能函数部分*
;IIC起始位
IIC_BEGIN:
    BC SDACR
    BS SDA
    BS SCL
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP;NOP*10=5us
    BC SDA
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP;NOP*9=4.5us
    BC SCL
    RET;起始位结束时:SCL=0,SDA=0.
;IIC结束位
IIC_END:
    BC SDA
    BS SCL
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP;NOP*9=4.5us
    BS SDACR
    JBS SDA
    JMP IIC_END
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP;NOP*10=5us
    RET;结束位结束时:SCL=1,SDA=1.
;IIC写入一字子程序
IIC_WRITE:
    MOV A,@8
    MOV IIC_BIT_NUM,A
IIC_WRITE_0:
    RLC IIC_DATA
    JBC R3,0
    JMP SET_P60
    BC SDA
    JMP IIC_W1BIT_END
SET_P60:
    BS SDA
IIC_W1BIT_END:
    BS SCL;产生一个大于4us的正脉冲
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP;NOP*9=4.5us
    BC SCL
    DJZ IIC_BIT_NUM
    JMP IIC_WRITE_0
IIC_SPK:;IIC响应从器件应答
    BS SDACR
    BS SCL
    NOP
    NOP
    NOP
    JBC SDA
    JMP CLR_IIC_SPK_SIGN
    BS IIC_SPK_SIGN;置1应答标志位
    JMP IIC_SPK_END
CLR_IIC_SPK_SIGN:
    BC IIC_SPK_SIGN
IIC_SPK_END:;应答操作为3步*0.5us
    NOP
    NOP
    NOP
    BC SCL
    BC SDACR
    JBS IIC_SPK_SIGN
    JMP IIC_SPK;未收到应答,继续等待应答.
    RET
;IIC读取一字子程序
IIC_READ:
    BS SDACR
    MOV A,@8
    MOV IIC_BIT_NUM,A
IIC_READ_0:
    BS SCL;产生一个大于4us的正脉冲,中间读取SDA.
    NOP
    NOP
    NOP
    JBC SDA
    JMP SET_C
    BC C
    JMP ICC_R1BIT_END
SET_C:
    BS C
ICC_R1BIT_END:
    RLC IIC_DATA
    NOP
    NOP
    BC SCL
    DJZ IIC_BIT_NUM
    JMP IIC_READ_0
    BC SDACR
    BC SDA
    MOV A,IIC_DATA
    RET
;IIC应答位
IIC_AN:
    BC SDA
    BS SCL
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    BC SCL
    RET
;IIC非应答位
IIC_UNAN:
    BS SDA
    BS SCL
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    BC SCL
    RET

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-12-14 11:18:11 | 显示全部楼层
在写之后,最小延迟5MS,再读,看看...
不知是否有帮助...

出0入0汤圆

发表于 2011-12-14 11:56:17 | 显示全部楼层
写入24CXX后要等一段时间,一般在5-10ms,不同芯片不太一样。在24cxx手册里有,好像叫write cycle time。
用FRAM就没这事。

出0入0汤圆

发表于 2011-12-14 11:59:27 | 显示全部楼层
你把SDA上拉1K电阻看看

出0入0汤圆

 楼主| 发表于 2011-12-14 23:25:04 | 显示全部楼层
呵呵,谢谢LS 3位朋友,这个程序发帖次日已解决,忘了来编辑下了。
原因是写操作结束后,接着进行下一操作时,需要类似LCD显示器那样查忙,不忙时,E2ROM才会接受操作指令,当然延时也行的,但是延时就没法确定数据是否被成功的写入,而且延时会使系统资源不同程度的浪费。EM78P163N的几个IO口有内部上拉电阻,使能之就不必加外部上拉电阻了,但是阻值不得而知。
为做这个小项目,专门借了编程器来,最后样品也通过了全部功能及稳定性的测试,但是“客户”最后还是不要了,样品也不退还给我,辛苦费都不给一点,还编程器时自己还给人家老师傅买了两包烟,悲惨的第一次哎。(看到此贴,突发牢骚。)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 20:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表