重写I2c 读写AT24C01

2019-04-15 12:13发布

/*陈  24C01(1K)存储器I2C总线实验   C语言例子 单字节和无符号长整型读写程序 SDA SCL可以为任意普通I/O */
//#include    
#define TRYTIME 250 //失败时,重新试着操作次数
//#define SDA P42   //数据线
//#define SCL P43   //时钟线
#define I2CWRITE 0xA0 //A2 A1 A0 为0
#define I2CREAD  0xA1

unsigned char trytime;
//函数声明
void i2c_write4byte(unsigned long j,unsigned char position);//在add区position位置写入4个字节的num,  position=1对应位置为4
unsigned long i2c_read4byte(unsigned char position);//在position位置读4个字节,  position=1对应位置为4


unsigned char i2c_read(unsigned char);
void i2c_write(unsigned char,unsigned char);


void i2c_send8bit(unsigned char);
unsigned char i2c_receive8bit(void);
void i2c_start(void);
void i2c_stop(void);
bit i2c_ack(void);


void delay()   //延时
{
kmg();   //看门狗
}
void i2c_start(void)//发送开始信号: SCL为高电平时,SDA由高变为低
{
SDA = 1;
delay();
SCL = 1;
delay();   //tSU: STA  起始信号建立时间>=0.6us
SDA = 0;
delay();   //tHD: STA  起始信号保持时间>=0.6us
SCL = 0;   //
delay();
}


void i2c_stop(void) //发送结束信号: SCL为高电平时,SDA由低变为高
{
SDA = 0;
delay();
SCL = 1;
delay(); 
SDA = 1;
delay(); //tSU: STO 停止信号建立时间 >= 0.6 us
}     
bit    i2c_ack(void)//发送接收确认信号
{
bit    ack;
SDA = 1;
delay();
SCL = 1;
delay();
ack=SDA;
SCL = 0;
delay();
return      (ack);
}
void i2c_send8bit(unsigned char b) //送八位数据 :SCL由高变低时 SDA的值 MSB
{
unsigned  char a;
for(a=0;a<8;a++)
{
SDA=(bit)((b<  //b左移a位  取最高位
delay();
SCL = 1;
delay();  //tHIGH 时钟高电平周期 >=0.6us
SCL = 0;   
delay();
}
}
unsigned char i2c_receive8bit(void) //接收八位数据  //MSB
{
unsigned  char a;
unsigned char b=0;
for(a=0;a<8;a++)
{
SCL = 1;
delay();
b=b<<1; //b左移一位
b=b|(unsigned char)(SDA);  //SDA上的数据存入b的最低位
SCL = 0;
delay();
}
return      (b);
}


void i2c_write(unsigned char Address,unsigned char Data)//选择性写 //i2c_write(地址,数据),写一个字节
{
trytime=TRYTIME; //初始化
do{
i2c_start();   //主器件发送起始命令
i2c_send8bit(I2CWRITE); //主器件发送从器件地址信息(R/W 位置零)给从器件
if(i2c_ack())   //=1,表示无确认,再次发送
{
if(0==(trytime--))
{
errno=ERROR_I2C;
return ;
}
}
else
break;
}while(1);    
i2c_send8bit(Address); //主器件发送CAT24WC01/02/04/08/16 的字节地址
i2c_ack(); //主器件在收到从器件的另一个应答信号后再


i2c_send8bit(Data);  //发送数据到被寻址的存储单元
i2c_ack(); //CAT24WC01/02/04/08/16 再次应答
i2c_stop(); //并在主器件产生停止信号后开始内部数据的擦写
//   yans(10); //在内部擦写过程中CAT24WC01/02/04/08/16 不再应答主器件的任何请求
       return;
}  
unsigned char i2c_read(unsigned char Address) //选择性读  //数据 = i2c_read(地址),读一个字节
{
unsigned char c;
trytime=TRYTIME; //初始化
do{
i2c_start();   //主器件发送起始命令
i2c_send8bit(I2CWRITE); //主器件发送从器件地址信息(R/W 位置零)给从器件
if(i2c_ack())   //=1,表示无确认,再次发送
{
if(0==(trytime--))
{
errno=ERROR_I2C;
return 0;
}
}
else
break;
}while(1);               
i2c_send8bit(Address); //发送数据到被寻址的存储单元
i2c_ack(); //主器件在收到从器件的另一个应答信号后再

do{
i2c_start(); //主器件发送起始命令
i2c_send8bit(I2CREAD); //主器件发送从器件地址信息(R/W 位置1)给从器件
}while(i2c_ack());
c=i2c_receive8bit();
i2c_ack();
i2c_stop();
//   yans(10);
       return(c);

//陈扩展  读写4字节
unsigned long i2c_read4byte(unsigned char position)//在position位置读4个字节,  position=1对应位置为4
{
unsigned long j=0;
unsigned char i;
for(i=0;i<4;i++)
{  
j=j*256+i2c_read(i+position*4);  //0x12345678     顺着读【0123】[0]12 [1]34 [2]56 [3]78
}
return j;
}
 
void i2c_write4byte(unsigned long j,unsigned char position)//在add区position位置写入4个字节的num,  position=1对应位置为4
{
unsigned char i=3;
do
{
i2c_write(position*4+i,j); //0x12345678     倒着写【3210】 [0]12 [1]34 [2]56 [3]78
j/=256;
}while(i--);

}




/*
void i2c_writesz(unsigned char *Wdata,unsigned char Address,unsigned char number) //批量写 //OK
{
trytime=TRYTIME; //初始化
do{
i2c_start();   //主器件发送起始命令
i2c_send8bit(I2CWRITE); //主器件发送从器件地址信息(R/W 位置零)给从器件
if(i2c_ack())   //=1,表示无确认,再次发送
{
if(0==(trytime--))
{
errno=ERROR_I2C;
return ;
}
}
else
break;
}while(1); 
i2c_send8bit(Address);
i2c_ack();
for(;number!=0;number--)
{
i2c_send8bit(*Wdata);
i2c_ack();
Wdata++;
}
i2c_stop();
}
//读有问题
void  i2c_readsz(unsigned char *RamAddress,unsigned char Address,unsigned char number) //批量读
{
trytime=TRYTIME; //初始化
do{
i2c_start();   //主器件发送起始命令
i2c_send8bit(I2CWRITE); //主器件发送从器件地址信息(R/W 位置零)给从器件
if(i2c_ack())   //=1,表示无确认,再次发送
{
if(0==(trytime--))
{
errno=ERROR_I2C;
return ;
}
}
else
break;
}while(1);               
i2c_send8bit(Address); //发送数据到被寻址的存储单元
i2c_ack(); //主器件在收到从器件的另一个应答信号后再

do{
i2c_start(); //主器件发送起始命令
i2c_send8bit(I2CREAD); //主器件发送从器件地址信息(R/W 位置1)给从器件
}while(i2c_ack());




for(;number!=1;number--)
{
*RamAddress=i2c_receive8bit();
i2c_ack();
RamAddress++;
}
*RamAddress=i2c_receive8bit();
i2c_ack();
i2c_stop();
}
//陈扩展  读写4字节 OK
unsigned long i2c_read4byte(unsigned char position)//在position位置读4个字节,  position=1对应位置为4
{
unsigned long j=0;
unsigned char i;
i2c_readsz(sz,position*4,4); //批量读
// xssztest();
for(i=0;i<4;i++)
{  
j=j*256+sz[i];  //0x12345678     顺着读【0123】[0]12 [1]34 [2]56 [3]78
}
return j;
}  


void i2c_write4byte(unsigned long j,unsigned char position)//在add区position位置写入4个字节的num,  position=1对应位置为4
{
unsigned char i=3;
do
{
sz[i]=j;
// i2c_write(position*4+i,j); //0x12345678     倒着写【3210】 [0]12 [1]34 [2]56 [3]78
j/=256;
}while(i--);
i2c_writesz(sz,position*4,4); //批量写

}
*/