六、【STM32】eeprom的使用 以13届省赛为例

题目要求:

 

首先将下面两个函数加到程序中(记住),比赛时应该需要自己写:在文章末尾会有一点说明。

//EEPROM_Read
void EEPROM_Read(uint8_t add,uint8_t * array,uint8_t n){
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(add);
    I2CWaitAck();
    I2CStop();
    
    I2CStart();
    I2CSendByte(0xa1);
    I2CWaitAck();
    while(n--)
    {
        *array++=I2CReceiveByte();
        if(n)
        {
            I2CSendAck();
        }
        else
        {
            I2CSendNotAck();
        }
    }
    I2CStop();
    
}



void EEPROM_Write(uint8_t add,uint8_t * array,uint8_t n){
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(add);
    I2CWaitAck();
    
    while(n--)
    {
        I2CSendByte(*array++);
        I2CWaitAck();
    }
    I2CStop();
}

接下来就是稍微麻烦的地方了,就是判断是否为第一次上电,其实以后比赛记住这种模式就可以:稍微解释一下:我们可以随便读取EEPROM里的任意单元地址(不要和我们需要保存的数据地址相同)里的数据。对该数据进行判断,是否等于一个0x27(等于别的也可以),如果不等于0x27,则读取到的是EEPROM原本存储的值,说明是第一次上电,将0xf8写进该单元,此时该单元的值等于0x27。如果等于0x27,则说明不是第一次上电。其实这种方法也有一点点误差1/256%,也可以忽略不计了吧。产生误差的原因是第一次上电eeprom读取的数据有可能和原来相应位置存储的数据相同,这就为会产生错误了。

void System_Init(){
	u8 temp;
	EEPROM_Read(0x07, &temp, 1);
	if(temp!=0x27){//不等于0x27是第一次上电
		temp = 0x27;
		EEPROM_Write(0x07,&temp,1);
		HAL_Delay(10);
		EEPROM_Write(0x00,&X_Count,1);
		HAL_Delay(10);
		EEPROM_Write(0x01,&Y_Count,1);
		HAL_Delay(10);
		EEPROM_Write(0x02,&X_Price,1);
		HAL_Delay(10);
		EEPROM_Write(0x03,&Y_Price,1);
		HAL_Delay(10);
	}
	else{//不是第一次上电
		EEPROM_Read(0x00,&X_Count,1);
		HAL_Delay(10);
		EEPROM_Read(0x01,&Y_Count,1);
		HAL_Delay(10);
		EEPROM_Read(0x02,&X_Price,1);
		HAL_Delay(10);
		EEPROM_Read(0x03,&Y_Price,1);
		HAL_Delay(10);
	}
}

题目中要求每次修改库存数量和价格时都要更新eeprom存储的值,那我们就在按键相应部分加上一条更新语句就可以啦!如下图所示>>>

EEPROM单字节读取方式

写函数

void EEPROM_Write(uint8_t add,uint8_t date)
{
	I2CStart();//起始
	I2CSendByte(0xa0);//控制字,写
	I2CWaitAck();
	I2CSendByte(add);//片内单元地址
	I2CWaitAck();
	I2CSendByte(date);//写入的字节
	I2CWaitAck();
	I2CStop();	//停止
}

读函数:

uint8_t EEPROM_Read(uint8_t add)
{
	uint8_t temp;
	
	I2CStart();//起始
	I2CSendByte(0xa0);//控制字,告诉EEPROM进行写字节操作
	I2CWaitAck();
	I2CSendByte(add);//片内单元地址
	I2CWaitAck();
	I2CStop();//停止
	
	I2CStart();//起始
	I2CSendByte(0xa1);//控制字,告诉EEPROM进行读字节操作
	I2CWaitAck();
	temp=I2CReceiveByte();//读取字节
	I2CSendNotAck();
	I2CStop();	//停止
	
	return temp;
}

AT24C02(EEPROM)片内地址从0x00到0xff共256个地址单元,每个地址单元可以存放一个字节。需要注意的是,连续多个字节写入EEPROM要进行10ms的延时,这是因为EEPROM处理数据的速度远小于单片机的速度,为了防止数据丢失,所以需要延时。
    上述代码中的add即为EEPROM的片内地址,上述代码中的date即为写入EEPROM的数据。
    以上代码就是单字节的读写函数,每次只能读写一个字节。这些代码比赛是需要我们自行编写的。
读写举例:

uint8_t date=26;
EEPROM_Write(0x00,date);//写入EEPROM的0x00单元,数据大小为26的uint8_t类型数据。
date=19;
date=EEPROM_Read(0x00);//读取EEPROM的0x00单元数据,当前date大小为26
 

 EEPROM多字节读取方式

多字节读写函数
优点:
    EEPROM不但可以单字节读写,还可以按页一次性多个字节读写,每页8个字节,所以最多可以连续读写8个字节,非常的方便。我们只需要向EEPROM传递EEPROM每页的首地址,就可以连续读写多个字节。
    除此之外,多字节读写方式对于多字节的基本数据类型的读写也非常简单。有效的解决了前面的问题。例如8个字节的double,4个字节的float,2个字节的uint16_t,很多同学都会进行相应的换算,这样着实麻烦。
    我们知道在相同的平台上,相同的数据类型,在内存中所占的字节大小是固定的,而且单个数据变量的字节在内存上的排布是连续的,所以,我们可以直接将该变量的所有字节写入EEPROM中,读取的时候,也是将相应的字节都读取出来,不用任何类型换算。

    当然理解这部分内容需要对于指针和地址,要有一点点的了解。不懂也没关系,会用就可以。

写函数

void EEPROM_Write(uint8_t add,uint8_t * array,uint8_t n)
{
	I2CStart();
	I2CSendByte(0xa0);//写操作
	I2CWaitAck();
	I2CSendByte(add);//片内单元地址
	I2CWaitAck();
	
	while(n--)//进行n次循环,写入n个数据,每次写入进行一次等待。
	{
		I2CSendByte(*array++);
		I2CWaitAck();
	}
	I2CStop();
}

读函数:

void EEPROM_Read(uint8_t add,uint8_t * array,uint8_t n)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	while(n--)
	{
		*array++=I2CReceiveByte();//读取
		if(n)//如果还有数据要读取
		{
			I2CSendAck();
		}
		else//如果没有数据要读取
		{
			I2CSendNotAck();
		}
	}
	I2CStop();
	
}

延时问题

    无论是单字节的读写方式,还是多字节的读写方式,向EEPROM写入数据的时候都要进行相应的延时,建议延时10ms,这个问题前面有讲到。主要是因为EEPROM的速度跟不上stm32的速度。

更加详细的eeprom讲解请参考:(72条消息) 蓝桥杯嵌入式(G431RBT6): EEPROM进阶学习_电子鹦鹉的博客-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值