打印

P89LPC917模拟I2C的问题

[复制链接]
3313|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

使用特权

评论回复
5
610095871|  楼主 | 2011-11-11 18:23 | 只看该作者
2# ayb_ice
我觉得奇怪所以发帖问下原因,他们编译后,我查看汇编代码,发现有点不同。

使用特权

评论回复
6
hotpower| | 2011-11-11 18:39 | 只看该作者
不会吧,肯定程序有问题,因为你肯定是主机,故时钟由你控制。注意C语言也语言NOP指令的。

使用特权

评论回复
7
610095871|  楼主 | 2011-11-11 20:39 | 只看该作者
6# hotpower
我知道啊,_nop_();但是就是不行。那些程序都是在stc上调通的。

使用特权

评论回复
8
古道热肠| | 2011-11-11 21:59 | 只看该作者
是不是IO端口的模式设得不对呀,要设置成弱上拉模式。

使用特权

评论回复
9
610095871|  楼主 | 2011-11-12 14:55 | 只看该作者
8# 古道热肠
我知道,外部我也加上拉了,但是就是不行,正在郁闷。

使用特权

评论回复
10
ningling_21| | 2011-11-12 17:23 | 只看该作者
建议:用示波器测量波形,就能找到根本原因了...
注意:SCK的高电平和低电平时间尽量相等...

使用特权

评论回复
11
hotpower| | 2011-11-12 21:55 | 只看该作者
建议:用示波器测量波形,就能找到根本原因了...
注意:SCK的高电平和低电平时间尽量相等...
ningling_21 发表于 2011-11-12 17:23


无关

使用特权

评论回复
12
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
以上是汇编代码,汇编代码可以顺利执行,求解。时钟分频我用的是一样的而且都比实际要求偏大。

使用特权

评论回复
13
610095871|  楼主 | 2011-11-15 07:52 | 只看该作者
自己顶下 免的沉了

使用特权

评论回复
14
hotpower| | 2011-11-15 08:13 | 只看该作者
程序有些问题。写函数在读应答信号前未释放sda数据总线。还有主机写时从机有时可能不返回应答信号,在从机异常时。而且主机在写一片数据的最后一个字节时,由于要发送停止信号,故也不要求从机应答。
故读应答信号应该做个超时错误处理。

使用特权

评论回复
15
610095871|  楼主 | 2011-11-15 14:15 | 只看该作者
14# hotpower
你说的我知道,但是你看下汇编代码和c代码,我可以很付责任的说汇编代码一点问题都没,而c代码就不行。我一直在找这个问题的答案。

使用特权

评论回复
16
hotpower| | 2011-11-15 15:04 | 只看该作者
俺很复杂地说你的程序有问题,主要是没释放数据总线。因为SDAT=CY,CY可能为0,故应该在测试SDAT==1前要有句SDAT=1释放总线。

使用特权

评论回复
17
610095871|  楼主 | 2011-11-16 07:55 | 只看该作者
16# hotpower
阁下说的是,我改以后还是那样,汇编可以运行,c还是不行,而且我吧I2C的程序写成汇编在c中调用也不管用,必须把整个初始化都写成汇编才好。不知道为什么?求解啊,而且我用c语言在proteus中操作24c02可以读可以写。

使用特权

评论回复
18
610095871|  楼主 | 2011-11-17 14:09 | 只看该作者
自己再顶下

使用特权

评论回复
19
610095871|  楼主 | 2011-11-20 10:09 | 只看该作者
要沉了。。。。。。。。。

使用特权

评论回复
20
passart| | 2011-11-20 10:12 | 只看该作者
程序本身的问题和语言有什么关系呢
在C里不要直接使用寄存器,比如: ACC,B,PSW,DPTR,R0~R7等

使用特权

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

本版积分规则

27

主题

323

帖子

10

粉丝