P89LPC917模拟I2C的问题

[复制链接]
4584|21
 楼主| 610095871 发表于 2011-11-11 13:51 | 显示全部楼层 |阅读模式
最近在用P89LPC917做I2C的通讯,没有使用其自带的硬件I2C而是用模拟的,奇怪的是 我用汇编写的可以用,用c语言写的就不行,哪位遇到过类似的问题?怎么解决的,能否指点下?尽管我不打算用LPC的了 但是这个问题还是想知道答案,希望大家能帮下忙
ayb_ice 发表于 2011-11-11 13:58 | 显示全部楼层
程序本身的问题和语言有什么关系呢
在C里不要直接使用寄存器,比如: ACC,B,PSW,DPTR,R0~R7等
hotpower 发表于 2011-11-11 16:52 | 显示全部楼层
为何不用硬件iic?
 楼主| 610095871 发表于 2011-11-11 18:22 | 显示全部楼层
因为做伴的时候把线连错了 3# hotpower
 楼主| 610095871 发表于 2011-11-11 18:23 | 显示全部楼层
2# ayb_ice
我觉得奇怪所以发帖问下原因,他们编译后,我查看汇编代码,发现有点不同。
hotpower 发表于 2011-11-11 18:39 | 显示全部楼层
不会吧,肯定程序有问题,因为你肯定是主机,故时钟由你控制。注意C语言也语言NOP指令的。
 楼主| 610095871 发表于 2011-11-11 20:39 | 显示全部楼层
6# hotpower
我知道啊,_nop_();但是就是不行。那些程序都是在stc上调通的。
古道热肠 发表于 2011-11-11 21:59 | 显示全部楼层
是不是IO端口的模式设得不对呀,要设置成弱上拉模式。
 楼主| 610095871 发表于 2011-11-12 14:55 | 显示全部楼层
8# 古道热肠
我知道,外部我也加上拉了,但是就是不行,正在郁闷。
ningling_21 发表于 2011-11-12 17:23 | 显示全部楼层
建议:用示波器测量波形,就能找到根本原因了...
注意:SCK的高电平和低电平时间尽量相等...
hotpower 发表于 2011-11-12 21:55 | 显示全部楼层
建议:用示波器测量波形,就能找到根本原因了...
注意:SCK的高电平和低电平时间尽量相等...
ningling_21 发表于 2011-11-12 17:23


无关
 楼主| 610095871 发表于 2011-11-14 07:59 | 显示全部楼层
void I2C_start()
{
        SDAT=1;
        SCLK=1;
        nop;
        nop;
        nop;
        nop;
        SDAT=0;

}

void I2C_write(uchar com)
{
        uchar i,dat=0;
        dat=com;
        for(i=0;i<8;i++)
        {
                SCLK=0;
                nop;
                dat=dat<<1;
                SDAT=CY;
                nop;
                SCLK=1;
                delay();
        }       
        SCLK=0;
        delay();
        SCLK=1;
        while(SDAT==1);
        SCLK=0;
}
void I2C_stop()
{
        SDAT=0;
        delay();
        SCLK=1;
        delay();
        SDAT=1;

}
以上是c语言写的I2C,其中nop被宏定义了。

EEPW:  SETB  SDA
       SETB  SCL
       NOP
       NOP
       NOP
       NOP
       CLR   SDA
       MOV   A,#0BAH           ;送器件地址  BA接电源接,B8地


       ACALL SUBS
       MOV   A,R2              ;送片内字节地址

      ACALL SUBS
AGAIN: MOV   A,R3
      ACALL SUBS             ;调发送单字节子程序
          
      
       CLR     SDA            ;SDA置0, 准备送停止信号
       ACALL   DELAY          ;延时以满足传输速率要求
       SETB    SCL            ;发停止信号
       ACALL   DELAY
       SETB    SDA

       RET
SUBS:  MOV  R0,#8             ;发送单字节子程序
LOOP:  CLR  SCL
       ;RLC  A
           ADD A,ACC
       MOV  SDA,C
       NOP
       SETB  SCL
       ACALL DELAY
       DJNZ  R0,LOOP
       CLR   SCL
       ACALL DELAY
       SETB  SCL
REP:   MOV   C,SDA
       JC    REP             ;判应答到否,未到则等待
       CLR   SCL
;           CLR   CH_LED_GREEN_Pin
       RET
DELAY: NOP
       NOP
       NOP
       NOP
       RET
        END
以上是汇编代码,汇编代码可以顺利执行,求解。时钟分频我用的是一样的而且都比实际要求偏大。
 楼主| 610095871 发表于 2011-11-15 07:52 | 显示全部楼层
自己顶下 免的沉了
hotpower 发表于 2011-11-15 08:13 | 显示全部楼层
程序有些问题。写函数在读应答信号前未释放sda数据总线。还有主机写时从机有时可能不返回应答信号,在从机异常时。而且主机在写一片数据的最后一个字节时,由于要发送停止信号,故也不要求从机应答。
故读应答信号应该做个超时错误处理。
 楼主| 610095871 发表于 2011-11-15 14:15 | 显示全部楼层
14# hotpower
你说的我知道,但是你看下汇编代码和c代码,我可以很付责任的说汇编代码一点问题都没,而c代码就不行。我一直在找这个问题的答案。
hotpower 发表于 2011-11-15 15:04 | 显示全部楼层
俺很复杂地说你的程序有问题,主要是没释放数据总线。因为SDAT=CY,CY可能为0,故应该在测试SDAT==1前要有句SDAT=1释放总线。
 楼主| 610095871 发表于 2011-11-16 07:55 | 显示全部楼层
16# hotpower
阁下说的是,我改以后还是那样,汇编可以运行,c还是不行,而且我吧I2C的程序写成汇编在c中调用也不管用,必须把整个初始化都写成汇编才好。不知道为什么?求解啊,而且我用c语言在proteus中操作24c02可以读可以写。
 楼主| 610095871 发表于 2011-11-17 14:09 | 显示全部楼层
自己再顶下
 楼主| 610095871 发表于 2011-11-20 10:09 | 显示全部楼层
要沉了。。。。。。。。。
passart 发表于 2011-11-20 10:12 | 显示全部楼层
程序本身的问题和语言有什么关系呢
在C里不要直接使用寄存器,比如: ACC,B,PSW,DPTR,R0~R7等
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

323

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部