找回密码
 立即注册
查看: 97|回复: 2

STC32G8K64的EEPROM为什么不能正确写入读出数据 | 已解决

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-22 14:35:25
已绑定手机

2

主题

15

回帖

54

积分

注册会员

积分
54
发表于 2025-9-22 14:35:25 | 显示全部楼层 |阅读模式
子程序是copy例程的,
set[0]=CAN1_Rx.DataBuffer[0];
set[1]=CAN1_Rx.DataBuffer[1];
set[2]=CAN1_Rx.DataBuffer[2];
set[3]=CAN1_Rx.DataBuffer[3];
set[4]=0x50;
set[5]=0x51;
set[6]=0x52;
set[7]=0x53;
                                                                                                
EEPROM_SectorErase(0);            //擦除扇区
EEPROM_write_n(0,&set[20],8);    //写N个字符

EEPROM_read_n(0,set,8); // 读0x000000地址开始的8个开机设置值,读出的SET[0]-SET[7]的值不是之前送进去的数,怎么回事?


回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-9-22 14:38:00 | 显示全部楼层
您好,关于您提到的 STC32G8K64 芯片中 EEPROM 不能正确写入和读出数据 的问题,结合您提供的代码片段,我将从以下几个方面进行专业分析和排查建议:

一、EEPROM操作基本流程回顾

STC32G8K64 芯片的 EEPROM 操作通常包括以下几个步骤:

1. 扇区擦除(Sector Erase)  
EEPROM 为 Flash 类型,写入前必须先擦除。
擦除单位为扇区,每个扇区大小为 1KB。
注意:擦除后所有位为 1(即数据为 0xFF)。

2. 数据写入(Write)  
使用 EEPROMwriten(addr, buffer, len) 函数。
写入前必须确保目标地址所在的扇区已经被擦除。

3. 数据读取(Read)  
使用 EEPROMreadn(addr, buffer, len) 函数。
读取无需擦除或写入操作前置。

二、您代码中存在的关键问题分析

1. 地址参数错误:写入地址为 0x20(即十进制32),读取地址为0
  1. c
  2. EEPROMwriten(0, &set[20], 8);  // 实际写入地址为 set[20] 的地址,即 set+20
  3. EEPROMreadn(0, set, 8);        // 从地址0开始读取
复制代码
&set[20] 是一个 指针偏移操作,表示从 set 数组的第20个元素开始取地址。
如果 set 是一个大小为 8 的数组(set[8]),那么 set[20] 已经越界,导致写入地址错误。
这会导致:
数据写入到不可控的内存区域,甚至可能覆盖了其他变量。
后续读取地址 0 时,当然无法读到您期望的数据。

✅ 建议修改为:
  1. c
  2. EEPROMwriten(0, set, 8);  // 将 set[0] ~ set[7] 写入地址0
复制代码

2. 写入前是否成功擦除?
  1. c
  2. EEPROMSectorErase(0);  // 擦除扇区0
复制代码
这一行是正确的,但需确认:
函数是否返回成功?
是否等待擦除完成?
是否在写入前调用?

✅ 建议:
添加擦除结果判断,例如:
  1. c
  2. if (EEPROMSectorErase(0) != SUCCESS) {
  3.     // 处理擦除失败
  4. }
复制代码
确保擦除完成后,再进行写入。

3. EEPROM写入函数是否正确实现?
STC32 系列芯片的 EEPROM 操作依赖于库函数或自定义的 Flash 操作函数。
如果 EEPROMwriten 是用户自定义或非官方例程,请检查:
是否按页写入(Flash 写入通常按页对齐)。
是否处理了地址对齐问题。
是否等待写入完成。

✅ 建议:
使用官方 SDK 提供的 Flash 写入函数。
或者确保自定义函数正确实现了 Flash 写入逻辑。

4. 数据类型与对齐问题
set 是 uint8t 类型数组?
如果是其他类型(如 int、float、结构体),需要注意:
对齐方式。
大小端问题。
数据类型一致性。

✅ 建议:
明确 set 类型为 uint8t set[8];。
写入与读取使用相同的数据类型和顺序。

三、完整推荐代码示例
  1. c
  2. include "stc32g.h"
  3. uint8t set[8];
  4. // 假设CAN数据已正确获取
  5. set[0] = CAN1Rx[i].DataBuffer[0];
  6. set[1] = CAN1Rx[i].DataBuffer[1];
  7. set[2] = CAN1Rx[i].DataBuffer[2];
  8. set[3] = CAN1Rx[i].DataBuffer[3];
  9. set[4] = 0x50;
  10. set[5] = 0x51;
  11. set[6] = 0x52;
  12. set[7] = 0x53;
  13. // 擦除扇区0
  14. if (EEPROMSectorErase(0) != SUCCESS) {
  15.     // 错误处理
  16.     while(1); // 停止程序
  17. }
  18. // 写入8字节数据到地址0
  19. EEPROMwriten(0, set, 8);
  20. // 读取8字节数据回set
  21. EEPROMreadn(0, set, 8);
  22. // 此时 set[0]~set[7] 应为预期值
复制代码

四、常见调试建议

1. 使用调试器查看写入地址是否正确  
查看 set 数组的地址是否与写入地址一致。
使用断点或内存查看功能,确认写入后 Flash 地址内容是否正确。

2. 检查电源电压是否稳定  
Flash 操作对电压敏感,建议使用稳压电源供电。

3. 避免频繁写入  
Flash 有擦写寿命(通常 10万次左右),建议尽量减少擦写次数。

4. 确认编译器优化等级  
有时编译器优化可能导致变量地址被优化掉,影响读写。

五、总结

您遇到的问题主要集中在 地址错误写入 和 数组越界 上,导致写入与读取不在同一地址。建议:
检查 set 数组定义和写入地址是否一致。
确保写入前擦除成功。
使用调试工具验证 Flash 地址内容。
使用官方 Flash/EEPROM 操作函数以确保兼容性。

如果您能提供完整的 EEPROMwriten 和 EEPROMSectorErase 函数实现,我可以进一步分析是否存在底层实现问题。

祝您调试顺利!

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-22 14:35:25
已绑定手机

2

主题

15

回帖

54

积分

注册会员

积分
54
发表于 2025-9-22 15:03:01 | 显示全部楼层
谢谢啦,SET[20],改为SET[0]就可以了。万分感谢
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 10:27 , Processed in 0.124056 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表