[讨论] PIC16单片机写的一个24LC08的读写程序,为什么读出来是FF

liuqianxin   2015-3-13 11:21 楼主
#include
#define delay2408_TIME 2   //24C08的延迟时间
#define SCL1 RC3   
#define SDA1 RC4
#define uchar unsigned char
#define uint  unsigned int
void I2cinit(void)
{
  //SSP1STAT=0x80;
  SSP1CON1=0x28;
  TRISC4=1;    //SDA配置为输入;
  delay2408(delay2408_TIME);
  TRISC3=1;    //SCL配置为输入;
  delay2408(delay2408_TIME);
}
void  delay2408(unsigned int t)  //24c08的延时函数,微妙延迟
{
  while(t--);
   
}

void I2C_Start(void)
{
  /*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/
  //SCL1=0;
  SDA1=1;
  delay2408(delay2408_TIME);
  SCL1=1;
  delay2408(delay2408_TIME);
  SDA1=0;
  delay2408(delay2408_TIME);
  //SCL1=0;
  //delay2408(delay2408_TIME);
}
void I2C_Stop(void)
{
/*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/
  //SCL1=0;
  SDA1=0;
  delay2408(delay2408_TIME);
  SCL1=1;
  delay2408(delay2408_TIME);
  SDA1=1;
  delay2408(delay2408_TIME);
  //SCL1=0;
  //delay2408(delay2408_TIME);
}
void SEND_0(void)  /*SEND ACK*/
{
  /*发送0,在SCL为高电平时使SDA信号为低*/
  SDA1=0;
  delay2408(delay2408_TIME);
  SCL1=1;
  delay2408(delay2408_TIME);
  SCL1=0;
  delay2408(delay2408_TIME);
}
void SEND_1(void)  
{
  /*发送1,在SCL为高电平时使SDA信号为高*/
  SDA1=1;
  delay2408(delay2408_TIME);
  SCL1=1;
  delay2408(delay2408_TIME);
  SCL1=0;
  delay2408(delay2408_TIME);
}
void Check_Acknowledge(void)
{
  /*发送完一个字节后检验设备的应答信号*/
  uchar a;
  //SCL1=0;
  //delay2408(delay2408_TIME);
  //SDA1=1;
  //delay2408(delay2408_TIME);
  SCL1=1;
  delay2408(delay2408_TIME);
  a=255;
  while(SDA1==1)
   {
    a--;
    if(a==0)  
       { SCL1=0;
         
       }
    }
   SCL1=0;
  delay2408(delay2408_TIME);
}
void WriteI2CByte(uchar b)
{
  /*向I2C总线写一个字节*/
   unsigned char i;
   i=0;
  for(i=0;i<8;i++)
     {
      if((b<           SEND_1();
          else
            SEND_0();
      }
   SDA1=1;
   delay2408(delay2408_TIME);
}
unsigned char ReadI2CByte(void)
{
   /*从I2C总线读一个字节*/
   unsigned char b=0,i;
   for(i=0;i<8;i++)
     {
        SCL1=0;
        delay2408(delay2408_TIME);
        //SDA1=1;       /*释放总线*/
        //delay2408(4);
        SCL1=1;     /*接受总线*/
        delay2408(delay2408_TIME);
        if(SDA1==1)
          {
            b=b<<1;
            b=b|0x01;
           }
           else
              b=b<<1;
         delay2408(4);
         SCL1=0;
       }
  return b;
}
/******24c08的读写函数********************/
void Write_One_Byte(unsigned char addr,unsigned char thedata)
{
  I2C_Start();
  WriteI2CByte(0xa0);
  Check_Acknowledge();   //应答信号判断,这里应该需要确定它的应答信号
  WriteI2CByte(addr);
  Check_Acknowledge();
  WriteI2CByte(thedata);
  Check_Acknowledge();
  I2C_Stop();
  delay2408(2);
}
unsigned char Read_One_Byte(unsigned char addr)
{
  unsigned char mydata;
  /*read a byte from mem*/
  I2C_Start();
  WriteI2CByte(0xa0);
  Check_Acknowledge();
  WriteI2CByte(addr);
  Check_Acknowledge();
  I2C_Start();
  WriteI2CByte(0xa1);
  Check_Acknowledge();
  mydata=ReadI2CByte();
  delay2408(delay2408_TIME);
  I2C_Stop();
  return mydata;
  
}
void main()
{
  unsigned char data;
  data=0;
  Write_One_Byte(0x20,0x21);
  data=Read_One_Byte(0x20);
}



回复评论 (7)

应该是I2C时序上的问题,你可以在protues中用I2C仪表去检查一下I2C总线。
点赞  2015-3-13 11:50
引用: dcexpert 发表于 2015-3-13 11:50
应该是I2C时序上的问题,你可以在protues中用I2C仪表去检查一下I2C总线。
第一次用这个~请问需要对单片机进行特殊的配置吗?



点赞  2015-3-13 11:53
pic16很久没有用过了,细节记得不清楚了。你这里主要就是IO模拟I2C,其他部分影响不大。
点赞  2015-3-13 12:48
写后要延时,写与读之间不能太紧凑!
点赞  2015-3-13 12:51
引用: 新新科技 发表于 2015-3-13 12:51
写后要延时,写与读之间不能太紧凑!


试了一下~还是不行。能帮我看看程序的问题出现在哪了吗?

点赞  2015-3-13 15:30
引用: dcexpert 发表于 2015-3-13 12:48
pic16很久没有用过了,细节记得不清楚了。你这里主要就是IO模拟I2C,其他部分影响不大。
很是蛋疼~还不确定这能不能实现读写的功能。



点赞  2015-3-13 15:33
在进行写数据和读数据时最好把SDA写和读时的方向寄存器TRISC进行设置一下
点赞  2015-4-5 22:49
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复