打印

急!求救各位大神:PIC18F2480的硬件I2C通信问题

[复制链接]
4576|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
boasing|  楼主 | 2013-2-22 22:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
我用PIC18F2480单片机,在proteus里面调试,结果是当加上I2C DEBUGGER测试器的时候通讯正常,可以将值写入EEPROM里,PORTD输出的显示也正常(数码管),但是拿掉I2C DEBUGGER单片机就写不进EEPROM里了,用示波器查了一下原因,发现拿掉I2C DEBUGGER后PIC单片机I2C在发送了SEN=1的起始条件后,EEPROM不给应答信号请问这是怎么回事啊?现象如图所示

以下是源代码
#include<pic18.h>
#define uchar unsigned char
#define uint unsigned int
const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
               0x07,0x7f,0x6f};
uchar read_data[9];
void delay(uint z);  
void I2Cinit();
void I2Cwrite();
void I2Cread();
void main()
{  

I2Cinit();
I2Cwrite();
delay(50);
I2Cread();
while(1)
{
  uchar i;  
  for(i=0;i<9;i++)
  {
   PORTD=read_data;
   delay(500);
   RA0=1;RA1=1;//加入指示灯调程序
      delay(100);
      RA0=0;RA1=0;
  }
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void I2Cinit()
{
INTCON=0;
PIE1=0;
PIE2=0;
TRISC3=1;
TRISC4=1;//设置为输入
TRISD=0;
TRISA=0;
SSPSTAT=0x80;//标准速度100K其他的都为检测位先设为零
SSPCON1=0x38;//使能同步串口SSP  时钟为100K
SSPCON2=0;
SSPADD=0x09;
RA0=1;
delay(10);//调程序标志
RA0=0;

}
void I2Cwrite()
{
uchar i;
SSPIF=0;
SEN=1;   //使能ssp通信
while(!SSPIF);//通过检测 sspif 代替应答信号
SSPIF=0;
SSPBUF=0xA0; //发送器件地址P0=0;A=0;
while(!SSPIF);
SSPIF=0;
SSPBUF=0;  //发送写的地址的高八位
while(!SSPIF);
SSPIF=0;
SSPBUF=0x01;  //发送写的地址的低八位0x01
while(!SSPIF);
SSPIF=0;
for(i=0;i<9;i++)
{
  SSPBUF=table;//依次写入要写的9个数
  while(!SSPIF);
  SSPIF=0;
  RA0=1;
  delay(100);
  RA0=0;
}
PEN=1;    //发送停止信号
while(!SSPIF);
SSPIF=0;
}
void I2Cread()
{

uchar i;
SSPIF=0;
SEN=1;
while(!SSPIF);
SSPIF=0;
SSPBUF=0xA0;
while(!SSPIF);
SSPIF=0;
SSPBUF=0;  //发送写的地址的高八位
while(!SSPIF);
SSPIF=0;
SSPBUF=0x01;  //发送写的地址的低八位0x01;
while(!SSPIF);
SSPIF=0;
// SSPIF=0;
RSEN=1;    //发送开始信号
while(!SSPIF);
SSPIF=0;
SSPBUF=0xA1;  //读指令
while(!SSPIF);
SSPIF=0;
for(i=0;i<9;i++)
{
  RCEN=1;
  while(!SSPIF);
  read_data=SSPBUF;
  while(!SSPIF);
  SSPIF=0;
  RA1=1;
  delay(100);
  RA1=0;
  if(i>=8)
  {
   ACKDT=1;
  }
  else
  {
   ACKDT=0;
  }
  ACKEN=1;
  while(!SSPIF);
  SSPIF=0;  
}
PEN=1;
while(!SSPIF);
SSPIF=0;
}

沙发
boasing|  楼主 | 2013-2-22 23:17 | 只看该作者
在线等。。。

使用特权

评论回复
板凳
asspeed| | 2013-2-22 23:48 | 只看该作者
主机只发个start bit,从机需要应答吗???自己看看I2C规范吧

使用特权

评论回复
地板
boasing|  楼主 | 2013-2-23 12:30 | 只看该作者
asspeed 发表于 2013-2-22 23:48
主机只发个start bit,从机需要应答吗???自己看看I2C规范吧

大神我说错了,我用的是Proteus仿真软件:在发送了起始条件SEN=1后,再发送器件地址、存储地址和数据,然后再发送停止条件PEN=1,但是这段代码无效,用示波器采信号,会发现器件不给应答,但是如果我另外加了I2C DEBUGGER,代码就有效了,示波器采信号发现I2C器件会给应答。这问题困扰了我好久,我在其他的论坛也发过类似的帖子求救,但是依然没人能解决、、、
主要代码如下:
SSPIF=0;
SEN=1;   //使能ssp通信
while(!SSPIF);//通过检测 sspif 代替应答信号
SSPIF=0;
SSPBUF=0xA0; //发送器件地址P0=0;A=0;
while(!SSPIF);
SSPIF=0;
SSPBUF=20;  //发送地址
while(!SSPIF);
SSPIF=0;
SSPBUF=10;//写入要写的数
while(!SSPIF);
SSPIF=0;
PEN=1;    //发送停止信号
while(!SSPIF);
SSPIF=0;

使用特权

评论回复
5
cherry5174| | 2013-2-25 17:03 | 只看该作者
boasing 发表于 2013-2-23 12:30
大神我说错了,我用的是Proteus仿真软件:在发送了起始条件SEN=1后,再发送器件地址、存储地址和数据,然 ...

我这刚入门啊,之前刚好做的是I2C通信的东西,说错勿怪...
感觉LZ发送的流程有问题,主机连续发送数据,每字节之间要等从机ACK的吧,最好看下从器件的时序

使用特权

评论回复
6
yewuyi| | 2013-2-25 17:09 | 只看该作者
IIC的通信还是自己BAIDU参考代码看吧,俺反正是基本不愿意给别人看代码的。

使用特权

评论回复
7
asspeed| | 2013-2-25 17:14 | 只看该作者
cherry5174 发表于 2013-2-25 17:03
我这刚入门啊,之前刚好做的是I2C通信的东西,说错勿怪...
感觉LZ发送的流程有问题,主机连续发送数据, ...

正解,如果寻址都没有回应,那说啥都没用...

使用特权

评论回复
8
dogglove| | 2013-2-28 13:09 | 只看该作者
整个发上来,我也试试

使用特权

评论回复
9
兰天白云| | 2013-3-1 10:25 | 只看该作者
LZ说的是外部EEPROM吧,有专门的规约
如果用内部EEPROM则情况不同,有序列要求

使用特权

评论回复
10
chengqing3968| | 2013-9-17 13:02 | 只看该作者
楼组实现了嘛……求指导!

使用特权

评论回复
11
boasing|  楼主 | 2013-9-27 00:33 | 只看该作者
chengqing3968 发表于 2013-9-17 13:02
楼组实现了嘛……求指导!

这个代码没有问题的,只是Proteus自身软件的BUG,添加虚拟终端I2C就行了,

使用特权

评论回复
12
q3742829| | 2013-9-27 10:01 | 只看该作者
学习一下

使用特权

评论回复
13
wsl1236| | 2015-10-28 23:13 | 只看该作者
楼主我也是和你一样的问题。 看了你的答案估计问题就出在那个I2C debugger 上面吧。 PS,用示波器查看,Protues 模拟I2C通信模块是有问题的,SCK 和SDA是在同一时刻下降的,这个可能会导致E2PROM芯片无**常读写。所以需要价格IC2 调试器。我是这么理解的,不知道有没有别的大神有别的见识?

使用特权

评论回复
14
GeekyGeek| | 2015-10-31 08:27 | 只看该作者
Proteus上面很多I2C例程都没问题啊,
你的SCK,SDA有加上拉没?

使用特权

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

本版积分规则

3

主题

9

帖子

0

粉丝