打印
[PIC®/AVR®/dsPIC®产品]

pic16f886的i2c通信问题请教!!

[复制链接]
4181|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 涵潇舒雅 于 2013-10-22 10:06 编辑
void TX_i2c(uchar add,uchar cmd)
{
        SEN=1;
        while(SEN);
        SSPBUF=add&0xfe;
        while(R_nW);
        if(ACKSTAT==1)
                while(1);       //如果没有收到应答就进入死循环
        SSPBUF=cmd;
        while(R_nW);
        if(ACKSTAT==1)
                while(1);
//如果没有收到应答就进入死循环
        PEN=1;
        while(PEN);
}
  if(key2==0)//当按键的时候,向从机发送数据
                {
                        while(!key2);
                        TX_i2c(0xb0,0x01);
                        hanzi(0,40,4,TX_DOWN); //如果发送成功,那么就在液晶上显示状态
                }
有关从机的配置,这是从机中断函数。

我下载到板子进行调试,主机液晶上能够显示“发送成功”,说明通信正常,但是在从机方面,count_isr=3,但是write_flag始终是0,我本想把主机master_add显示出来,但是一直是0.说明SSPBUF里面根本没有数据
这是用proteus仿真出来的结果。通信很正常!!当我把从机断电之后,在发送数据,依然显示发送成功!!!!!!郁闷了
沙发
涵潇舒雅|  楼主 | 2013-10-18 15:21 | 只看该作者
怎么没人理我呢???

使用特权

评论回复
板凳
涵潇舒雅|  楼主 | 2013-10-19 08:03 | 只看该作者
help~~~~~~~~~~~

使用特权

评论回复
地板
yewuyi| | 2013-10-19 08:38 | 只看该作者
没人理你是因为这只需要通过看手册就应该解决的问题,别人不能帮你看手册。

你可以购买一本张明峰写的《PIC单片机入门与实战》这本书,这本书上针对数据手册上的各个模块有比较详细的讲解,虽然这本书比较老了,但一些常用概念基本都讲了,你可以参考着看。


另:同样的问题,不要重复发贴,按照版规应当删除。

使用特权

评论回复
5
涵潇舒雅|  楼主 | 2013-10-19 09:33 | 只看该作者
yewuyi 发表于 2013-10-19 08:38
没人理你是因为这只需要通过看手册就应该解决的问题,别人不能帮你看手册。

你可以购买一本张明峰写的《PI ...

您的意见很中肯,我研究了好几天了,感觉时序没有问题,但是就是不能达到预期的效果,我还是继续研究研究手册吧!!!!!

使用特权

评论回复
6
伏尔加的鱼| | 2013-10-19 09:47 | 只看该作者
去看看人家的程序吧

使用特权

评论回复
7
涵潇舒雅|  楼主 | 2013-10-21 15:43 | 只看该作者
伏尔加的鱼 发表于 2013-10-19 09:47
去看看人家的程序吧

看了很多了,用protues能够达到想要的结果,但是实物之后就坏了!!

使用特权

评论回复
8
NE5532| | 2013-10-22 13:43 | 只看该作者
涵潇舒雅 发表于 2013-10-21 15:43
看了很多了,用protues能够达到想要的结果,但是实物之后就坏了!!

把protues卸载了吧,那东西除了害你以后养不起老婆孩子之外没啥功能。你的从机工作流程我觉得少了很多东西呢?从机收到Start信号有标志或中断没?地址匹配有标志或中断没?后续处理流程呢?你用的是SPI还是I2C?SPI很简单,I2C的流程绝对不是这么简单的。4楼说得对,你该熟读I2C协议和手册关于硬件I2C部分的接口以后再来做。当然第一步是——把protues卸载了。

使用特权

评论回复
9
涵潇舒雅|  楼主 | 2013-10-22 14:37 | 只看该作者
NE5532 发表于 2013-10-22 13:43
把protues卸载了吧,那东西除了害你以后养不起老婆孩子之外没啥功能。你的从机工作流程我觉得少了很多东 ...

我的是I2C还想问一下,把从机掉电之后,主机发送数据,为啥还能收到应答信号?ACKSTAT始终是0?从机收到起始信号之后,并不能产生中断吧!?我也想搞清楚有没有地址匹配,
                else  //接受的是地址
                {
                        if(BF==1)
                        {
                                master_add=SSPBUF;
                                read_flag=1;
                        }
                        count_isr++;
                }
这样之后,read_flag并没有置一,也就是没有匹配,但是主机那边却是发送成功,也就是接收到应答了,既然没有匹配,那就不能接收到应答信号,这才是我纠结的!!

使用特权

评论回复
10
涵潇舒雅|  楼主 | 2013-10-22 14:40 | 只看该作者
NE5532 发表于 2013-10-22 13:43
把protues卸载了吧,那东西除了害你以后养不起老婆孩子之外没啥功能。你的从机工作流程我觉得少了很多东 ...

数据手册我一直在看,也参考了一下群里的问题,我自认为I2C的通讯流程差不多熟悉了,我目前的理解感觉自己的时序没有问题啊,实在是找不到问题所在,所以跪求大神解答!!!

使用特权

评论回复
11
NE5532| | 2013-10-22 16:29 | 只看该作者
涵潇舒雅 发表于 2013-10-22 14:40
数据手册我一直在看,也参考了一下群里的问题,我自认为I2C的通讯流程差不多熟悉了,我目前的理解感觉自 ...

那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?

使用特权

评论回复
12
涵潇舒雅|  楼主 | 2013-10-22 16:41 | 只看该作者
NE5532 发表于 2013-10-22 16:29
那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?

我自己的理解就是,收到start信号后,等待主机发送地址信息,如果匹配,并且没有溢出,那么就产生应答信号!!是这样吗?版主大哥

使用特权

评论回复
13
涵潇舒雅|  楼主 | 2013-10-22 16:45 | 只看该作者
NE5532 发表于 2013-10-22 16:29
那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?

我自己的理解就是接受到应答信号之后,从机等待主机发送地址信息,并与自己的SSPADD中的地址进行匹配(这些都是硬件自动完成的!?)如果匹配,并且SSPBUF没有溢出那么就产生ACK,并将地址信息移到SSPBUF中!不知道这样理解对不对!

使用特权

评论回复
14
NE5532| | 2013-10-22 16:49 | 只看该作者
涵潇舒雅 发表于 2013-10-22 16:45
我自己的理解就是接受到应答信号之后,从机等待主机发送地址信息,并与自己的SSPADD中的地址进行匹配(这 ...

嗯,我虽然没用过PIC的I2C模块,但是你说的应该是正确的,这个过程调试通过了没?就是说主机发送从机地址以后有没有收到应答信号?建议用示波器在总线上看,应为主机程序也可能有问题。

另外你问的从机掉电以后,主机可以收到掉电信号,有2种可能性:

1.从机消耗的电流很小,从I2C上拉电阻上偷电进行工作。
2.从机消耗电流很大,本身就充当了一个下拉,主机来读当然就当个应答位读了。

使用特权

评论回复
15
涵潇舒雅|  楼主 | 2013-10-22 16:56 | 只看该作者
NE5532 发表于 2013-10-22 16:49
嗯,我虽然没用过PIC的I2C模块,但是你说的应该是正确的,这个过程调试通过了没?就是说主机发送从机地址 ...
a) SSPSR寄存器的值被装入SSPBUF寄存器。
b) 缓冲器满标志位BF置1。
c) 产生ACK脉冲。
d) 在第9个SCL脉冲的下降沿,PIR1寄存器的
MSSP中断标志位SSPIF置1(如果允许中断
则产生中断)。
这是手册里面的一段话,可以这样理解,只要是SSPIF置位了,说明地址肯定匹配了,并且移入SSPBUF中了,也就意味这BF=1,但是我在测试的时候,BF并没有置位,读出来的地址和我发送的地址信息完全不一样,身边有个示波器,但是不会用,感觉很白痴啊!

使用特权

评论回复
16
涵潇舒雅|  楼主 | 2013-10-22 16:59 | 只看该作者
NE5532 发表于 2013-10-22 16:49
嗯,我虽然没用过PIC的I2C模块,但是你说的应该是正确的,这个过程调试通过了没?就是说主机发送从机地址 ...

版主,别嫌我白痴啊,我是实在是找不到头绪了!!!!!

使用特权

评论回复
17
NE5532| | 2013-10-22 17:02 | 只看该作者
不会用示波器就上百度搜,自己摸着弄啊。你现在手里没一样东西是能确定正确的,咋调啊,拿给我都没办法调,还不说新手了。

还有个办法,你把从机拔了,把SDA线拉到GND,然后主机发启动信号和从机地址,看能不能检测到应答,如果能,那主机检测应答的机制应该是正确的,就去找从机的问题。但是不排除主机会进入总线错误的状态,所以还是建议你把示波器用起来,一切就都明白了。

使用特权

评论回复
18
NE5532| | 2013-10-22 17:05 | 只看该作者
涵潇舒雅 发表于 2013-10-22 16:59
版主,别嫌我白痴啊,我是实在是找不到头绪了!!!!!

我可没嫌你啊,我都是在教你方法。调试的基本原则就是用已知验证未知,你可以梳理一下你自己什么是已知,什么是未知。

还有数据手册建议看英文的,中文的错太多了,很容易误导人。

使用特权

评论回复
19
涵潇舒雅|  楼主 | 2013-10-23 08:53 | 只看该作者
NE5532 发表于 2013-10-22 17:02
不会用示波器就上百度搜,自己摸着弄啊。你现在手里没一样东西是能确定正确的,咋调啊,拿给我都没办法调, ...
void TX_i2c(uchar add,uchar cmd)
{
        SEN=1;
        while(SEN);
        while(BCLIF); //检测总线冲突
/*        SSPBUF=add&0xfe;
        while(R_nW);//R_nW=1说明数据发送进行中
        if(ACKSTAT==1)
                while(1);
        SSPBUF=cmd;
        while(R_nW);//R_nW=1说明数据发送进行中
        if(ACKSTAT==1)
                while(1);
        PEN=1;
        while(PEN);*/
}
这是我发现的问题,这样之后就不能发送成功了,也就是发生总线冲突了,但是怎么解决呢??

使用特权

评论回复
20
NE5532| | 2013-10-23 09:25 | 只看该作者
数据发送完成马上就能读到ACK?然后一个while死循环?ACK的反馈有这么快回来?你是不是该等到ACK了以后再判断呢?

使用特权

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

本版积分规则

26

主题

164

帖子

1

粉丝