[PIC®/AVR®/dsPIC®产品] pic16f886的i2c通信问题请教!!

[复制链接]
4759|34
 楼主| 涵潇舒雅 发表于 2013-10-17 11:31 来自手机 | 显示全部楼层 |阅读模式
本帖最后由 涵潇舒雅 于 2013-10-22 10:06 编辑
  1. void TX_i2c(uchar add,uchar cmd)
  2. {
  3.         SEN=1;
  4.         while(SEN);
  5.         SSPBUF=add&0xfe;
  6.         while(R_nW);
  7.         if(ACKSTAT==1)
  8.                 while(1);       //如果没有收到应答就进入死循环
  9.         SSPBUF=cmd;
  10.         while(R_nW);
  11.         if(ACKSTAT==1)
  12.                 while(1);
  13. //如果没有收到应答就进入死循环
  14.         PEN=1;
  15.         while(PEN);
  16. }
  1.   if(key2==0)//当按键的时候,向从机发送数据
  2.                 {
  3.                         while(!key2);
  4.                         TX_i2c(0xb0,0x01);
  5.                         hanzi(0,40,4,TX_DOWN); //如果发送成功,那么就在液晶上显示状态
  6.                 }
有关从机的配置,这是从机中断函数。

我下载到板子进行调试,主机液晶上能够显示“发送成功”,说明通信正常,但是在从机方面,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单片机入门与实战》这本书,这本书上针对数据手册上的各个模块有比较详细的讲解,虽然这本书比较老了,但一些常用概念基本都讲了,你可以参考着看。


另:同样的问题,不要重复发贴,按照版规应当删除。
 楼主| 涵潇舒雅 发表于 2013-10-19 09:33 | 显示全部楼层
yewuyi 发表于 2013-10-19 08:38
没人理你是因为这只需要通过看手册就应该解决的问题,别人不能帮你看手册。

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

您的意见很中肯,我研究了好几天了,感觉时序没有问题,但是就是不能达到预期的效果,我还是继续研究研究手册吧!!!!!
伏尔加的鱼 发表于 2013-10-19 09:47 来自手机 | 显示全部楼层
去看看人家的程序吧
 楼主| 涵潇舒雅 发表于 2013-10-21 15:43 | 显示全部楼层
伏尔加的鱼 发表于 2013-10-19 09:47
去看看人家的程序吧

看了很多了,用protues能够达到想要的结果,但是实物之后就坏了!!
NE5532 发表于 2013-10-22 13:43 | 显示全部楼层
涵潇舒雅 发表于 2013-10-21 15:43
看了很多了,用protues能够达到想要的结果,但是实物之后就坏了!!

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

我的是I2C还想问一下,把从机掉电之后,主机发送数据,为啥还能收到应答信号?ACKSTAT始终是0?从机收到起始信号之后,并不能产生中断吧!?我也想搞清楚有没有地址匹配,
  1.                 else  //接受的是地址
  2.                 {
  3.                         if(BF==1)
  4.                         {
  5.                                 master_add=SSPBUF;
  6.                                 read_flag=1;
  7.                         }
  8.                         count_isr++;
  9.                 }
这样之后,read_flag并没有置一,也就是没有匹配,但是主机那边却是发送成功,也就是接收到应答了,既然没有匹配,那就不能接收到应答信号,这才是我纠结的!!
 楼主| 涵潇舒雅 发表于 2013-10-22 14:40 | 显示全部楼层
NE5532 发表于 2013-10-22 13:43
把protues卸载了吧,那东西除了害你以后养不起老婆孩子之外没啥功能。你的从机工作流程我觉得少了很多东 ...

数据手册我一直在看,也参考了一下群里的问题,我自认为I2C的通讯流程差不多熟悉了,我目前的理解感觉自己的时序没有问题啊,实在是找不到问题所在,所以跪求大神解答!!!
NE5532 发表于 2013-10-22 16:29 | 显示全部楼层
涵潇舒雅 发表于 2013-10-22 14:40
数据手册我一直在看,也参考了一下群里的问题,我自认为I2C的通讯流程差不多熟悉了,我目前的理解感觉自 ...

那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?
 楼主| 涵潇舒雅 发表于 2013-10-22 16:41 | 显示全部楼层
NE5532 发表于 2013-10-22 16:29
那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?

我自己的理解就是,收到start信号后,等待主机发送地址信息,如果匹配,并且没有溢出,那么就产生应答信号!!是这样吗?版主大哥
 楼主| 涵潇舒雅 发表于 2013-10-22 16:45 | 显示全部楼层
NE5532 发表于 2013-10-22 16:29
那我就考考你,从机收到主机发送的启动信号以后(Start),会怎样?

我自己的理解就是接受到应答信号之后,从机等待主机发送地址信息,并与自己的SSPADD中的地址进行匹配(这些都是硬件自动完成的!?)如果匹配,并且SSPBUF没有溢出那么就产生ACK,并将地址信息移到SSPBUF中!不知道这样理解对不对!
NE5532 发表于 2013-10-22 16:49 | 显示全部楼层
涵潇舒雅 发表于 2013-10-22 16:45
我自己的理解就是接受到应答信号之后,从机等待主机发送地址信息,并与自己的SSPADD中的地址进行匹配(这 ...

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

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

1.从机消耗的电流很小,从I2C上拉电阻上偷电进行工作。
2.从机消耗电流很大,本身就充当了一个下拉,主机来读当然就当个应答位读了。
 楼主| 涵潇舒雅 发表于 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并没有置位,读出来的地址和我发送的地址信息完全不一样,身边有个示波器,但是不会用,感觉很白痴啊!
 楼主| 涵潇舒雅 发表于 2013-10-22 16:59 | 显示全部楼层
NE5532 发表于 2013-10-22 16:49
嗯,我虽然没用过PIC的I2C模块,但是你说的应该是正确的,这个过程调试通过了没?就是说主机发送从机地址 ...

版主,别嫌我白痴啊,我是实在是找不到头绪了!!!!!
NE5532 发表于 2013-10-22 17:02 | 显示全部楼层
不会用示波器就上百度搜,自己摸着弄啊。你现在手里没一样东西是能确定正确的,咋调啊,拿给我都没办法调,还不说新手了。

还有个办法,你把从机拔了,把SDA线拉到GND,然后主机发启动信号和从机地址,看能不能检测到应答,如果能,那主机检测应答的机制应该是正确的,就去找从机的问题。但是不排除主机会进入总线错误的状态,所以还是建议你把示波器用起来,一切就都明白了。
NE5532 发表于 2013-10-22 17:05 | 显示全部楼层
涵潇舒雅 发表于 2013-10-22 16:59
版主,别嫌我白痴啊,我是实在是找不到头绪了!!!!!

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

还有数据手册建议看英文的,中文的错太多了,很容易误导人。
 楼主| 涵潇舒雅 发表于 2013-10-23 08:53 | 显示全部楼层
NE5532 发表于 2013-10-22 17:02
不会用示波器就上百度搜,自己摸着弄啊。你现在手里没一样东西是能确定正确的,咋调啊,拿给我都没办法调, ...
  1. void TX_i2c(uchar add,uchar cmd)
  2. {
  3.         SEN=1;
  4.         while(SEN);
  5.         while(BCLIF); //检测总线冲突
  6. /*        SSPBUF=add&0xfe;
  7.         while(R_nW);//R_nW=1说明数据发送进行中
  8.         if(ACKSTAT==1)
  9.                 while(1);
  10.         SSPBUF=cmd;
  11.         while(R_nW);//R_nW=1说明数据发送进行中
  12.         if(ACKSTAT==1)
  13.                 while(1);
  14.         PEN=1;
  15.         while(PEN);*/
  16. }
这是我发现的问题,这样之后就不能发送成功了,也就是发生总线冲突了,但是怎么解决呢??
NE5532 发表于 2013-10-23 09:25 | 显示全部楼层
数据发送完成马上就能读到ACK?然后一个while死循环?ACK的反馈有这么快回来?你是不是该等到ACK了以后再判断呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

164

帖子

1

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