多次写入外部 eeprom 会破坏以前的数据

如何解决多次写入外部 eeprom 会破坏以前的数据

我使用 AT24C02 external eeprom 连接 stm32f401 nucleo。我面临的问题很少。

让我们考虑一些地址

/* 24c02 Device Address */
#define EEPROM_ADDRESS                          (uint8_t)0xA0

/*Demo addr*/
#define DEMO_BYTE_ADDR                          (uint16_t)0x01
#define DEMO_WORD_ADDR                          (uint16_t)0x02
#define DEMO_FLOAT_ADDR                         (uint16_t)0x06
#define DEMO_STRING_ADDR                        (uint16_t)0x0A

1.写作和阅读同时进行。
我能够同时向 eeprom 写入和读取数据。

/*Writing Byte*/
uint8_t byte;
eep_write_byte(DEMO_BYTE_ADDR,50);
eep_read_byte(DEMO_BYTE_ADDR,&byte);

/*Wrinting word*/
uint32_t word;
eep_write_word(DEMO_WORD_ADDR,123456789);
word = eep_read_word(DEMO_WORD_ADDR);

/*Writing float*/
float fData;
eep_write_float(DEMO_FLOAT_ADDR,9876.54);
fData = eep_read_float(DEMO_FLOAT_ADDR);

这段代码工作正常。下面是输出的快照。

OUTPUT OF THE ABOVE CODE

2.写字符串的问题 在上面的代码部分之后,我写了一些行来写字符串和读字符串。正如您在输出缓冲区中看到的,dest 包含一些值。

uint8_t dest[50] = {0};
eep_write_string(DEMO_STRING_ADDR,(uint8_t*)"Hello World!",strlen("Hello World!"));
eep_read_string(DEMO_STRING_ADDR,dest,strlen("Hello World!"));

3.写入所有这些值后,读数显示损坏的数据 在代码的上述部分之后,如果我读回我写的所有地址会给我损坏的数据。

eep_read_byte(DEMO_BYTE_ADDR,&byte);
word = eep_read_word(DEMO_WORD_ADDR);
fData = eep_read_float(DEMO_FLOAT_ADDR);
eep_read_string(DEMO_STRING_ADDR,strlen("Hello World!"));

下面是这段代码的截图。

Corrupted Data

如您所见,所有数据现在都已损坏。

您可以从此链接 https://pastebin.com/2vYWYhnw 中找到 eeprom.c 或直接滚动到下方。

/*
 * eeprom.c
 *
 *  Created on: 04-Jan-2021
 *      Author: DEVJEET MANDAL
 */

#include "i2c.h"
#include "eeprom.h"

#include "stdio.h"
#include "stdlib.h"

/* Low Level function */
void eep_small_delay(void)          {
    for (uint32_t i = 0; i < 65535; i++)
        __asm__("NOP");
}

void i2c_error(void)    {
    HAL_I2C_DeInit(&hi2c1);     //De-init i2c bus
    __asm__("NOP");
    HAL_I2C_Init(&hi2c1);       //re-init i2c bus
    __asm__("NOP");
}

eep_status_t i2c_write(uint16_t u8_reg_addr,uint8_t *u8_data,uint16_t len)            {
    HAL_StatusTypeDef xStatus = HAL_ERROR;
    xStatus = HAL_I2C_Mem_Write(&hi2c1,EEPROM_ADDRESS,u8_reg_addr,I2C_MEMADD_SIZE_16BIT,u8_data,len,100);
    HAL_Delay(5);
    if (xStatus != HAL_OK)  {i2c_error();}
    return xStatus;
}

eep_status_t i2c_read(uint16_t u8_reg_addr,uint16_t len)         {
    HAL_StatusTypeDef xStatus = HAL_ERROR;
    xStatus = HAL_I2C_Mem_Read(&hi2c1,100);
    eep_small_delay();
    if (xStatus != HAL_OK)  {i2c_error();}
    return xStatus;
}

/* High Level Functions */
eep_status_t eep_write_byte(uint16_t u8_reg_addr,uint8_t u8_data)      {
    return i2c_write(u8_reg_addr,&u8_data,1);
}

eep_status_t eep_read_byte(uint16_t u8_reg_addr,uint8_t *u8_data)      {
    return i2c_read(u8_reg_addr,1);
}

eep_status_t eep_is_data_avaiable(void)                     {
    eep_status_t xStatus = EEP_ERROR;
    uint8_t data = 0;
    eep_read_byte(EEPROM_DATA_AVAILABLE_ADDR,&data);
    if (data == 0)      {xStatus = EEP_ERROR;}
    else if (data == 1) {xStatus = EEP_OK;}
    else                {xStatus = EEP_ERROR;}
    return xStatus;
}

eep_status_t eep_set_data_available(uint8_t val)            {
    return eep_write_byte(EEPROM_DATA_AVAILABLE_ADDR,val);
}

eep_status_t eep_write_word(uint16_t reg_addr,uint32_t value)      {
    uint8_t val_byte[4] = {0};
    val_byte[0] = (value >> 24) & 0xFF;
    val_byte[1] = (value >> 16) & 0xFF;
    val_byte[2] = (value >> 8) & 0xFF;
    val_byte[3] = (value >> 0) & 0xFF;
    return i2c_write(reg_addr,val_byte,4);
}

eep_status_t eep_write_float(uint16_t reg_addr,float value)        {
    union FtoHex{
        float fval;
        uint32_t hval;
    }float_to_hex;

    float_to_hex.fval = value;
    return eep_write_word(reg_addr,float_to_hex.hval);
}

uint32_t eep_read_word(uint16_t reg_addr)                   {
    uint8_t val_buff[4] = {0};
    i2c_read(reg_addr,val_buff,4);
    return ((val_buff[0] << 24) | (val_buff[1] << 16) | (val_buff[2] << 8) | (val_buff[3] << 0));
}

float eep_read_float(uint8_t reg_addr)  {
    union FtoHex{
        float fval;
        uint32_t hval;
    }float_to_hex;

    float_to_hex.hval = eep_read_word(reg_addr);
    return float_to_hex.fval;
}

void eep_write_string(uint16_t reg_addr,uint8_t *src,uint16_t len)        {
    i2c_write(reg_addr,src,len);
}

void eep_read_string(uint16_t reg_addr,uint8_t *dest,uint16_t len)            {
    i2c_read(reg_addr,len);
}

//---------------------------------------------------------------------

差点忘了说我正在运行 I2C @400Khz。虽然我试过 100KHz 结果相同。 下面是 HAL 生成的 I2C init。

/* I2C1 init function */
void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

} 

现在的问题是为什么会出现这个问题。基本上 HAL 应该处理所有情况,我只会向它发送数据。任何帮助将不胜感激。

问候。

解决方法

您错过了 AT24C02 以 16 字节(写)页的形式组织。 损坏是由在写入以@ offset 0x0A 开头的字符串时翻转/换行@ offset 0x0F 引起的。 详情请参阅数据表。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-