本文是基于嵌入式开发板CT117E,stm32f103RBT6。"空手套白狼"就是直接利用官方给的库(v3.5),进行拷贝修改形成可以正常运行的代码。
给的资源包里面有i2c的驱动源码,所以只需要写e2prom的读和写的函数就可以了。
我们要了解e2prom的读写时序和他的地址,地址是8位的,最后一位是读写标志,0–写,1–读,其他需要参考原理图进行地址的判断,蓝桥杯的开发板看原理图可以看出,写的时候应该是0xa0,读的时候是0xa1,接下来就是时序的编程,这个需要记住,不能错任何一步;EEPROM一个地址,存入一个字节的数据,所以针对不同类型的数据,需要分离成单个字节的数据;所以地址和数据的变量都是定为u8。
写的函数较为容易: 开始—发送e2prom的地址(0xa0)—等待回应—发送我们要写的地址—等待回应–发送我们要写入的一个字节数据—等待回应----发出结束信号。
void i2c_write(u8 addr,u8 data)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
u8 i2c_read(u8 addr)
{
u8 t;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
t=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return t;
}
void u32_write(u8 addr,u32 data)
{
i2c_write(addr,data&0xff);
Delay_Ms(5);
i2c_write(addr+1,data>>8&0xff);
Delay_Ms(5);
i2c_write(addr+2,data>>16&0xff);
Delay_Ms(5);
i2c_write(addr+3,data>>24&0xff);
Delay_Ms(5);
}
u32 u32_read(u8 addr)
{
u32 t;
t+=i2c_read(addr);
Delay_Ms(5);
t+=(i2c_read(addr+1))<<8;
Delay_Ms(5);
t+=(i2c_read(addr+2))<<16;
Delay_Ms(5);
t+=(i2c_read(addr+3))<<24;
Delay_Ms(5);
return t;
}
u32_write(0x55,14253675);
read_32=u32_read(0x55);
void float_2_write(u8 addr,float data) //2位小数的写入
{
u32 t;
t=100*data;
i2c_write(addr,t&0xff);
Delay_Ms(5);
i2c_write(addr+1,t>>8&0xff);
Delay_Ms(5);
}
float float_2_read(u8 addr) //2位小数的读出
{
float t;
t+=i2c_read(addr);
Delay_Ms(5);
t+=(i2c_read(addr+1))<<8;
Delay_Ms(5);
return t/100;
}
float_2_write(0x55,100.85);
float_2=float_2_read(0x55);
for(i=0;i<sizeof(str_write);i++) //存
{
i2c_write(0x10+i,str_write[i]);
Delay_Ms(5);
}
for(i=0;i<sizeof(str_write);i++) //取
{
str_read[i]=i2c_read(0x10+i);
}
if(minus_write<0)
{
i2c_write(0x06,'-');
Delay_Ms(5);
i2c_write(0x07,-minus_write); //存正数
Delay_Ms(5);
}
if(i2c_read(0x06)=='-')
{
minus_read = 0 - i2c_read(0x07);
}
if(i2c_read(0x14)!=5) //这里按道理说程序只会执行一次;
{
LCD_DisplayStringLine(Line0,"123456");
i2c_write(0x14,5);
Delay_Ms(2); //这里一定要加延时,cpu的速度太快了,需要等待一下e2PROM
i2c_write(0x21,0); //初始化我们要写的地址
Delay_Ms(2);
}
i2c_num=i2c_read(0x21);
i2c_num++;
i2c_write(0x21,i2c_num);
sprintf((char *)i2c_buff,"i2c_num: %d ",i2c_num);
LCD_DisplayStringLine(Line0,i2c_buff);