【蓝桥杯嵌入式】stm32 EEPROM存储芯片无法写入和读取的解决方案

文章讲述了在嵌入式系统中使用EEPROM进行I2C通信时的注意事项,包括读写时序、新板初始化、以及Keil编译器版本选择对EEPROM操作的影响。作者强调了按照数据手册正确编写代码的重要性,以避免bug的发生。
摘要由CSDN通过智能技术生成

 2024-4-3补充, 如果你需要连续读或者连续写,例如

	if (x24c02_read(0xef) != 32 && x24c02_read(0xee) != 32)
	{
		x24c02_write(0,0);
		x24c02_write(0xef, 32);
		x24c02_write(0xee, 32);
	}

则需要hal_delay(1)一下子, 否则会发生太快, 而出现读取失败

	if (x24c02_read(0xef) != 32 && x24c02_read(0xee) != 32)
	{
		x24c02_write(0,0);
		HAL_Delay(1);
		x24c02_write(0xef, 32);
		HAL_Delay(1);
		x24c02_write(0xee, 32);
		HAL_Delay(1);
	}

​​​​​2024-1-29号补充,使用EEPROM的时候需要判断是否第一次使用EEPROM芯片

        因为如果是一块新的板子(例如官方调试用的板子),EEPROM里面的数据是空的,读取会读取到一个255的返回值。因此可以在特定的地方写入特定的值

        本博主是在EEPROM的0xee写入32,0xef写入64,每次程序上电后就会读取这里存储的值,如果不相等的话,则是第一次写入EEPROM芯片,需要赋予初值,然后往0xee写32,0xef写64,如果相等的话,则不进行操作。

        这样子会解决这个小问题。而且有bug出现的时候,尽量全部重新编译一下

 2024_1_29补充:发现bug,一定要按照EEPROM的读写时序来写代码,我在一次工程中,在I2Cstart()后面使用了等待ack的响应,结果读取不到,也无法写入。一定要按照数据手册上的时序图来编写代码。

uint8_t Eeprom_Read(uint8_t addr){
	uint8_t dat;
	I2CStart();
	I2CWaitAck();        //注意这里不符合EEPROM的时序,这里是bug代码,需要删除这一行
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	dat = I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	return dat;
}
void Eeprom_Write(uint8_t addr,uint8_t dat){
	I2CStart();
	I2CWaitAck();         //注意这里不符合EEPROM的时序,这里是bug代码,需要删除这一行
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

  1.  
    1. 刚开始编译的时候,keil编译版本5的编译速度实在让人难以忍受。因此我将
    2. 这里的ARM_Compiler改为版本6,编译速度是咻咻的快。直接提升十倍,但是呢,总是有奇怪的错误
    3. 所以我强烈不推荐使用版本6,使用版本6的话,EEPROM的读取和写入都会失效。因此我们选用版本5来编译。
    4. 但是为了加快编译速度,可以将下边图中的Brown Information取消勾选,这样速度也是很快,但是没办法调试,那就没办法了,为了减少潜在的错误,牺牲一点时间也是属实无奈
  2. 正文:
    1. 嵌入式组中的资源包里有模拟I2C通信的HAL_I2C的库和函数,因此我们直接使用软件模拟I2C
    2. 第一步:检查GPIO口PB6和PB7是否完整的配置好,如下图所示
    3. 第二步:检查编写的I2C函数(一个读,一个写)
      uint8_t x24c02_read(uint8_t address)
      {
      	unsigned char val;
      	
      	I2CStart(); 
      	I2CSendByte(0xa0);
      	I2CWaitAck(); 
      	
      	I2CSendByte(address);
      	I2CWaitAck(); 
      	
      	I2CStart();
      	I2CSendByte(0xa1); 
      	I2CWaitAck();
      	val = I2CReceiveByte(); 
      	I2CWaitAck();
      	I2CStop();
      	
      	return(val);
      }
      void x24c02_write(unsigned char address,unsigned char info)
      {
      	I2CStart(); 
      	I2CSendByte(0xa0); 
      	I2CWaitAck(); 
      	
      	I2CSendByte(address);	
      	I2CWaitAck(); 
      	I2CSendByte(info); 
      	I2CWaitAck(); 
      	I2CStop();
      }
    4. 之后主函数while(1)外面使用

      	val = x24c02_read(0);
      	x24c02_write(0, ++val);	
      
    5. 同时,while(1)里使用LCD显示部分查看EEPROM是否生效

      		sprintf(buf, "      PWR CNTR:%d    ", val);
      		LCD_DisplayStringLine(Line8, (uint8_t *)(buf));
      
    6. 这样子,每按一次复位键,屏幕显示的就会加1;


 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值