/*陈 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); //批量写
}
*/