赞助论坛
  • 4335阅读
  • 0回复

学习单片机之---24LC256模拟IIC通信 [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-20 16:21:48 
24LC256模拟IIC通信
//24LC256IIC通信程序


# include<pic.h>
# define uch unsigned char
# define unint unsigned int
# define SDA RC4
# define SCL RC3
uch ACK;

void delay(void)     //延时
{
  unint m;
  for(m=0;m<0xffff;m++)
  continue;
}  

void start (void)   // IIC开始
{
  TRISC3=0;       //置输出
  TRISC4=0;
  SDA=1;    
  asm("nop");
  SCL=1;         //在至少4u秒期间SDA从高电平到低电平
  asm("nop");
  asm("nop");
  asm("nop");
  SDA=0;
  asm("nop");
  asm("nop");
  asm("nop");
  SCL=0;
  asm("nop");
  asm("nop");
}

void stop(void)     // IIC结束
{ TRISC3=0;
  TRISC4=0;       //置输出
  SDA=0;
  asm("nop");
  SCL=1;       //在至少4u秒期间SDA从低电平到高电平
  asm("nop");
  asm("nop");
  asm("nop");
  SDA=1;
  asm("nop");
  asm("nop");
  asm("nop");
  SCL=0;
  asm("nop");
  asm("nop");
}

uch check(void)     // 检查应答信号
{
  TRISC4=1;
  SCL=0;
  SCL=1;
 
  if (SDA == 1)
  {
      ACK = 1;
  }
  else
  {
      ACK = 0;
  }
  SCL=0;
  return(ACK);
  }
 

void send(uch data)   // 发送一个字节
{
uch bitcount=8;     //发送8位
    do
      {
      TRISC3=0;   //置输出
      TRISC4=0;
      if((data&0x80)==0x80)  
        {
          SDA=1;     //发送 1
        }
        else
        {
          SDA=0;     //发送 0
        }
       
      SCL=0;     // 在时钟大于4u秒期间写数据
      SCL=1;
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      SCL=0;
      data=data<<1;
      bitcount--;
      } while(bitcount);
      TRISC4=1 ;             //释放总线等待应答
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");  
}  

uch recive(void)     //接受一个字节
{
  uch temp1=0;
  uch bitcount1=8;
  TRISC4=1;       //置输入
  TRISC3=0;
  do
  { SCL=0;         //在时钟大于4u秒期间读数据
  SCL=1;
  asm("nop");
  asm("nop");  
  if(SDA)             //读 1
    {
    temp1=temp1|0x01;
    }
  else             //读 0
  {
    temp1=temp1&0xfe;
  }
    SCL=0;
    if(bitcount1-1)
    {
      temp1=temp1<<1;
    }
    bitcount1--;
    }while(bitcount1);
    return(temp1);
}    
void ack(void)   //发送继续读信号
{
  SDA=0;
  SCL=0;
  SCL=1;
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  SCL=0;
}
 
void nack(void)     //停止继续读
{
  SDA=1;
  SCL=0;
  SCL=1;
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  SCL=0;
}

 
void wrtoROM(uch *data,unint address,uch num) //给24LC256写数据
{ unint i;
  unint adrl=address%256;     //低8位地址
  unint adrh=address/256;     //高8位地址
      start();           //起始信号
      send(0xa2);       //写主控器识别地址,本人是a2
     
  do{;
    }while(check());   //等待应答
 
  send(adrh);       //送数据高8位地址

  do{;
    }while(check());   //等待应答
    send(adrl);       //送数据低8位地址
  do
  {
    ;
    }while(check());       //等待应答
  for(i=0;i<num;i++,data++)
  {
    send(*data);         //发送数据
  do{;
    }while(check());     //等待应答
    }
  stop();           //停止
  delay();           //延时,下次发数据
 
}
void rdfromROM(uch *pdata,unint address,uch num2)   //从24LC256中读数据
{ unint adrl;    
  unint adrh;
  uch j;
  for(j=0;j<num2;j++,pdata++)
  {
    adrl=address%256;     //地址低位
    adrh=address/256;     //地址高位
    start();           //开始
  send(0xa2);         //写主控器识别地址(写),本人是a2
  do{
    ;
    }while(check());     //等待应答
  send(adrh);           //送高位
  do
    {
    ;
    }while(check());       //等待应答
  send(adrl);         //送低位
  do
  {
    ;
  }while(check());       //等待应答
  start();             //开始读数据
  send(0xa3);           //写主控器识别地址(读)
  do
  {
    ;
    }while(check());     //等待应答
 
    *pdata=recive();
    nack();
    stop();
    address=address+1;     //指向下一个地址
 
 
  }  
}  

main()
{ unint h,n;
    uch m;
   

  uch str[64]={0x5d,0x5d,0x32,0x18,0x6c,0x88,0xa0,0x1d,0x20,0x08};
 
  SCL=1;
  SDA=1;
  PORTD=0XFF;
  TRISD=0;
  for(n=0;n<256;)
  {
  wrtoROM(str,n,64);   //写一页的数据,根据24LC256一页是64个字节
  n=n+64;           //写下一页数据
  }  
 
  for(h=0;h<64;h++)   //数组清0
  {
    str[h]=0x21;
  }
  delay();
  rdfromROM(str,0x02,64);   //读从地址0开始的一页数据
  while(1)
  {
  for(m=0;m<64;m++)
    {
    PORTD=str[m];
    delay();
    PORTD=0XFF;
    delay();
    }
  }
}