目录
基本部分
IIC及EEPROM在蓝桥杯中的考法
举例:
在ct1117e上的EEPROM的通常使用方法就如上图所示 扩展板上还有三轴加速度计使用iic通讯,这里我们稍微提一下,其使用的通讯方式还是iic通讯。只不过使用的地址和要读取的寄存器有所不同(使用扩展板时,IIC引脚也要相应改变。
IIC的基本使用方法
在赛点资源包中是由iic的驱动文件的,省赛的一般在如下路径
赛点资源数据包_嵌入式_2019\3-底层驱动代码参考\i2c.c
使用时将i2c.h,和i2c.c两个文件复制到工程里,并在i2c.c文件末尾写上自己的读写函数,代码如下:
void i2c_write(u8 add ,u8 reg ,u8 data){
I2CStart();
I2CSendByte(add);
I2CWaitAck();
I2CSendByte(reg);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
u8 i2c_read(u8 add ,u8 reg){
u8 data ;
I2CStart();
I2CSendByte(add);
I2CWaitAck();
I2CSendByte(reg);
I2CWaitAck();
I2CStart();
I2CSendByte(add+1);
I2CWaitAck();
data =I2CReceiveByte();
I2CWaitAck();
I2CStop();
return data;
}
第一个函数void i2c_write(u8 add ,u8 reg ,u8 data); 是iic通讯的写函数,第一个 add是设备的地址,如0xa0是EEPROM的地址,0x38 是扩展板上的三轴加速度计的通讯地址。 第二个形参是寄存器的地址,需要注意的是AT24C02的地址是从0x00~0xff,如果超出该地址值会出现错误。地址和写入或读取的数据的类型都是无符号字符型,其他类型的数据有可能出现错误。就是说,但个地址存入读出的值不会超过255,即存取的的数据范围是0 ~255,那我们如何存入更大范围的数据呢,这个我在后面会介绍。 第二个函数是 u8 i2c_read(u8 add ,u8 reg) 在指定的从机的指定第地址中读取一个字节数据,add是从机地址,reg是寄存器地址。 以上代码能理解就结合文档中的时序图理解,不好理解的话直接背下来也是可以的,自己多敲几遍就好了,关键要熟练。 为了帮助理解,可以参考这篇文章 iic的读取时序问题
代码需要注意的点(出现问题也可依次检查)
读取的操作结束后,都建议延迟几毫秒,实测如果不延迟数据极有可能会出错,延迟操作可以加到函数末尾,也可在函数调用后。
调用函数之前,要先使用i2c.c文件中已有的函数i2c_init()来初始化iic要使用到的时钟,引脚等。
读写函数并不能直接存取超过范围的数,如果存入的数不在0到255之间,肯定会出错,地址也一样,要注意范围。
应用部分
简单应用
存取标志位,阈值等:
u8 flag=0;
i2c_write(0xa0,0,flag);
flag=i2c_write(0xa0,0,flag);
进阶应用
存取更大的数,比如无符号16进制数,范围是0-65535
u16 data;
u8 data_h,data_l;
data_h=(data&0xff00)>>8;
data_l=data&0x00ff;
i2c_write(0xa0,0,data_h);
Delay_Ms(5);
i2c_write(0xa0,1,data_l);
Delay_Ms(5);
data_h=i2c_read(0xa0,0);
Delay_Ms(5);
data_l=i2c_reaad(0xa0,1);
Delay_Ms(5);
data=((u16)data_h<<8)|data_l;
实际上,更大的数,或者浮点数都可以用类似的方法储存,只是就更为繁琐了,下面给出一种更为通用的方法。
存取结构体,在结构体中就可以放各种类型的数据了,不管是多大的数,是整型,浮点,还是数组,都可以放到一起,具体代码如下:
void writebuffer(u8 *buffer ,int len){
int i=0 ;
for(i=0;i<len;i++){
i2c_write(0xa0,i,buffer[i]);
Delay_Ms(5);
}
}
void readbuffer(u8 *buffer ,int len){
int i=0;
for(i=0;i<len;i++){
buffer[i]=i2c_read(0xa0,i);
Delay_Ms(5);
}
}
typedef struct{
u8 data1;
int data2;
float data3;
}Data;
Data data_tosave={0,-1,2.2};
u8 length=sizeof(Data);
u8 buffer[length];
memcpy(buffer,&data_tosave,length)
writebuffer(buffer,length);
readbuffer(buffer,length);
其关键思想是将结构体的数据拷贝到一个数组中,再依次存储和读去,当然,代码量较大,没有必要还是尽量不要使用。
|