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

学习单片机之---用c语言实现24LC256读写(非软件模拟方式) [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-20 17:18:43 
用c语言实现24LC256读写(非软件模拟方式)

#include <PIC1687X.H>
unsigned char i=0;
unsigned char receive=0x00;

void i2c_start()
{
  SEN=1;   //启动
  do{
  }while(SSPIF==0);
  SSPIF=0;
}

void i2c_stop()
{
  PEN=1;     //产生停止条件
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
}

void i2c_restart()
{
  RSEN=1; //启动,反复启动
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
}

void i2c_dataout()   //数据发送等待过程
{
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
}

void i2c_datain()   //读取24LC256时,不是读的最后一个字节时使用
{
  RCEN=1;
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
  receive=SSPBUF;
  ACKDT=0;
  ACKEN=1;
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
}

void i2c_datainlast()   //读取最后一个字节,或只读取24lc256中一个字节
{
  SSPIF=0;
  RCEN=1;
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
  receive=SSPBUF;
  ACKDT=1 ;
  ACKEN=1;
  do{
  ;
  }while(SSPIF==0);
  SSPIF=0;
 
}

void i2c_error()
{
  i2c_stop();
  return;
}

void write(unsigned int addr,unsigned char data,unsigned int n) //向iic写入一字节数据 地址,数据,字节个数
{
  i2c_start();
  SSPBUF=0xA0;//EEPROM寻址码和写操作命令码
  i2c_dataout(); //发送
 
  if(ACKSTAT)
  i2c_error();   //无应答,错误!
  else if(!ACKSTAT)
  SSPBUF=addr/256;
    //高eeaddr/256 ,取eeprom数据地址高字节
  i2c_dataout(); //发送
 
  if(ACKSTAT)
  i2c_error();   //无应答,错误!
  else if(!ACKSTAT)
  SSPBUF=addr%256;//低eeaddr%256 ,取eeprom数据地址低字节
  i2c_dataout(); //发送
 
  for(i=0;i<n;++i)
  {
    if(ACKSTAT)//应答
    i2c_error(); //无应答,错误!
    else if(!ACKSTAT)
    SSPBUF=data;//eedata     入eeprom的数据
    i2c_dataout();//发送
  }
 
  if(ACKSTAT)//应答
  i2c_error();
 
  i2c_stop();   //产生停止位,启动eeprom内部些过程
 
  do{
  i2c_start();
  SSPBUF=0xA0;
  i2c_dataout();
  i2c_stop();
  if(!ACKSTAT)break;
  }while(ACKSTAT);
}

unsigned int current_read(void)//current address read ok!
{
  i2c_start();
  SSPBUF=0xA1;//寻址命令码0xA0 和 读命令
  i2c_dataout();
  if(ACKSTAT)//应答
  i2c_error();
  else if(!ACKSTAT)
  i2c_datainlast();
  i2c_stop();

  return ((unsigned int)receive);
}

unsigned int random_read(unsigned int eepromaddress)
{
  i2c_start();
  SSPBUF=0xA0;//EEPROM寻址码和写操作命令码
  i2c_dataout(); //发送
 
  if(ACKSTAT)
  i2c_error();   //无应答,错误!
  else if(!ACKSTAT)
  SSPBUF=eepromaddress/256;
    //高eeaddr/256 ,取eeprom数据地址高字节
  i2c_dataout(); //发送
 
  if(ACKSTAT)
  i2c_error();   //无应答,错误!
  else if(!ACKSTAT)
  SSPBUF=eepromaddress%256;//低eeaddr%256 ,取eeprom数据地址低字节
  i2c_dataout(); //发送
 
  if(ACKSTAT)
  i2c_error();   //无应答,错误!
  else if(!ACKSTAT)
     
  i2c_restart();
  SSPBUF=0xA1;//寻址命令码0xA0 和 读命令
  i2c_dataout();
 
  if(ACKSTAT)//应答
  i2c_error();
  else if(!ACKSTAT)
  i2c_datainlast();
  i2c_stop();
  return ((unsigned int)receive);
 
}

void i2c_init()
{
  SSPSTAT=0x00;
  TRISC=0xD8;
  SSPADD=19;
  SSPIE=0;
  SSPCON=0x28;  
}


//在主程序中,先i2c_init();然后开始读/写24LC256中数据,经多次运行
no bug
//程序中的寄存器必须芯片内部包含,否则无法实现硬件iic读写。