在上一节中我们了解到,AT24C02芯片(E2PROM存储器)内部含有256个8位字节,每一次只能对一个字节进行读写操作。因此,其只能处理unsigned char或uint8_t类型的数据,对于int、float型等大于占用一个字节的数据,需要进行额外处理。
若是对于uint16_t类型的数据,我们可以利用移位操作,将其拆成高八位与低八位存进E2PROM的两个地址中;在从E2PROM读取数据时,再分别取出高八位和低八位后存进同一个变量中。
然而,对于占用字节数更多的数据类型,或占用字节数未知,用这样的办法处理起来就显得较麻烦。下面就来介绍一种对所有数据类型都通用的处理办法——共用体(若不知道共用体是什么,可自行搜索):
union val_float
{
float value;
unsigned char data[sizeof(float)];
} val_write, val_read;
float val = 0.5;
val_write.value = val;
这样,val变量就以4个字节的形式,存储在了val_write这一共用体中,其中value的值为0.5,data[0]~data[3]分别为其4个字节。将这个值存储进E2PROM时,只需要将data数组的4个元素分别存储进4个地址中即可:
for (int i=0; i<sizeof(float); i++)
{
e2prom_write(i, val_write.data[i]);
HAL_Delay(5); //加延时保证写操作完成
}
要从E2PROM中读取数据也非常简单,只需要用data数组的4个元素分别读取4个地址,然后取出共用体的value即可:
for (int i=0; i<sizeof(float); i++)
{
val_read.data[i] = e2prom_read(i);
}
float val = val_read.value;
下面我们以第十三届蓝桥杯国赛题为例,总结第九、十两节的内容:
按键功能可以参考第四节的内容,这里不再赘述:
uint8_t X = 1;
uint8_t Y = 1;
if (key[1].single_flag==1 && view==1)
{
X++;
if (X > 4) X = 1;
key[1].single_flag = 0;
}
if (key[2].single_flag==1 && view==1)
{
Y++;
if (Y > 4) Y = 1;
key[2].single_flag = 0;
}
由于X和Y的数据类型均为uint8_t,因此直接进行E2PROM读写操作即可:
e2prom_write(0, X);
e2prom_write(1, Y);
设备重新上电时,要求从E2PROM中读取X和Y,则在初始化中读取即可:
uint8_t X = e2prom_read(0);
uint8_t Y = e2prom_read(1);
整个程序如下:
/* Cube自动生成的头文件引用 */
#include "key.h"
#include "e2prom.h"
int main(void)
{
/* Cube自动生成的初始化 */
uint8_t X = e2prom_read(0);
uint8_t Y = e2prom_read(1);
if (X!=1&&X!=2&&x!=3&&x!=4) X = 1; //第一次上电初始化
if (Y!=1&&Y!=2&&Y!=3&&Y!=4) Y = 1; //第一次上电初始化
while (1)
{
if (key[1].single_flag==1 && view==1)
{
X++;
if (X > 4) X = 1;
key[1].single_flag = 0;
}
if (key[2].single_flag==1 && view==1)
{
Y++;
if (Y > 4) Y = 1;
key[1].single_flag = 0;
}
e2prom(0, X);
e2prom(1, Y);
}
}