找回密码
 立即注册
楼主: vb2002

请教下这位老哥说的,可以减少eeprom的磨损.

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-2 15:57:47 来自手机 | 显示全部楼层
Lkck8210 发表于 2024-8-2 15:16
但不会每次开机都换档吧?
有换档才在关机时更新EEProm

现在就是每次关机开机,包括换挡都会写入eeprom,我有点懊恼,
还没完善好。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-2 19:59:31 | 显示全部楼层
Debu*** 发表于 2024-8-2 14:35
没有,这段文字直接翻译成C语言就是代码了

这个是千问模型给出的答案,

我运行很多错误
麻烦您看看大体差不多吧!
  1. #define EEPROM_SIZE 4096
  2. #define SECTOR_SIZE 512
  3. #define NUM_SECTORS 8
  4. #define DATA_SECTORS (NUM_SECTORS - 1)
  5. #define POINTER_SECTOR 0
  6. #define DATA_SECTOR_START 1
  7. #define POINTER_BIT_COUNT 3584
  8. #define DATA_STATE_COUNT 128
  9. #define DATA_STATE_BITS 7
  10. #define DATA_FLAG_BIT 7
  11. typedef struct {
  12.     int sector;
  13.     int byte;
  14. } Pointer;
  15. typedef struct {
  16.     int valid;
  17.     int state;
  18. } Data;
  19. // 声明实际的EEPROM读写函数
  20. unsigned char eeprom_read_byte(unsigned char *addr);
  21. void eeprom_write_byte(unsigned char *addr, unsigned char value);
  22. // 假设的EEPROM读写函数
  23. unsigned char readEEPROM(int address) {
  24.     // 使用实际的EEPROM读取函数
  25.     return eeprom_read_byte((unsigned char *)address);
  26. }
  27. void writeEEPROM(int address, unsigned char value) {
  28.     // 使用实际的EEPROM写入函数
  29.     eeprom_write_byte((unsigned char *)address, value);
  30. }
  31. // 读取指针
  32. Pointer readPointer() {
  33.     int pointerBitIndex = 0; // 从第0位开始
  34.     unsigned char bitMask = 1;
  35.     int byteIndex = pointerBitIndex / 8;
  36.     int bitIndex = pointerBitIndex % 8;
  37.     // 读取位计数器的指针位置
  38.     unsigned char pointerByte = readEEPROM(POINTER_SECTOR * SECTOR_SIZE + byteIndex);
  39.     while ((pointerByte & bitMask) == 0) { // 跳过已用的位
  40.         bitMask <<= 1;
  41.         if (bitMask > 0xFF) {
  42.             bitMask = 1;
  43.             byteIndex++;
  44.             pointerByte = readEEPROM(POINTER_SECTOR * SECTOR_SIZE + byteIndex);
  45.         }
  46.         bitIndex++;
  47.         pointerBitIndex++;
  48.     }
  49.     // 计算指针位置
  50.     Pointer p = {DATA_SECTOR_START, pointerBitIndex / 8};
  51.     return p;
  52. }
  53. // 写入指针
  54. void writePointer(const Pointer* p) {
  55.     int byteIndex = p->byte * 8;
  56.     int bitIndex = byteIndex % 8;
  57.     unsigned char byte = readEEPROM(POINTER_SECTOR * SECTOR_SIZE + byteIndex / 8);
  58.     // 设置位
  59.     byte &= ~(1 << bitIndex); // 清除位
  60.     writeEEPROM(POINTER_SECTOR * SECTOR_SIZE + byteIndex / 8, byte);
  61. }
  62. // 读取数据
  63. Data readData(const Pointer* p) {
  64.     unsigned char dataByte = readEEPROM(p->sector * SECTOR_SIZE + p->byte);
  65.     Data d = {
  66.         .valid = !(dataByte & (1 << DATA_FLAG_BIT)),
  67.         .state = dataByte & ((1 << DATA_STATE_BITS) - 1)
  68.     };
  69.     return d;
  70. }
  71. // 处理数据
  72. void processData(Data* d) {
  73.     if (!d->valid) {
  74.         // 处理无效数据
  75.         d->state++;
  76.         if (d->state >= DATA_STATE_COUNT) {
  77.             d->state = 0;
  78.         }
  79.         d->valid = 1;
  80.     }
  81. }
  82. // 更新数据
  83. void updateData(const Pointer* p, Data* d) {
  84.     unsigned char dataByte = d->state | (d->valid ? 0 : (1 << DATA_FLAG_BIT));
  85.     writeEEPROM(p->sector * SECTOR_SIZE + p->byte, dataByte);
  86. }
  87. // 主函数示例
  88. int main() {
  89.     Pointer p = readPointer();
  90.     Data d = readData(&p);
  91.     processData(&d);
  92.     updateData(&p, &d);
  93.     writePointer(&p);
  94.     // 根据需要重复上述过程
  95.     return 0;
  96. }
复制代码


点评

AI写的不能信,cheat gpt 有空我写一个  详情 回复 发表于 2024-8-2 20:31
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-2 20:30:58 | 显示全部楼层
Lkck*** 发表于 2024-8-2 15:16
但不会每次开机都换档吧?
有换档才在关机时更新EEProm

那还要做掉电检测,需要使用比较器,还需要大电容储能
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-2 20:31:54 | 显示全部楼层
vb2*** 发表于 2024-8-2 19:59
这个是千问模型给出的答案,

我运行很多错误

AI写的不能信,cheat gpt
有空我写一个
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-2 21:00:36 | 显示全部楼层
Debu*** 发表于 2024-8-2 13:27
STC8H1K08,固定8K CODE,4K EEPROM,8个扇区,4096字节
可以第0扇区作为位计数器,bit有多少个0代表指针指 ...

哥,我想了一天..您说的是这个意思吗?
按您说的,好像是真的无敌哦...就是代码难倒我了!!!!



截图202408022100065586.jpg


点评

也行,最高位表示是否已使用,已使用就写成0,可以不用一个扇区当计数器了  详情 回复 发表于 2024-8-2 21:33
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-2 21:01:44 | 显示全部楼层
Debu*** 发表于 2024-8-2 20:31
AI写的不能信,cheat gpt
有空我写一个

好的,哥,,我现在指导您的思路了...真心牛逼!!!
大大延长eeprom的寿命啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-2 21:33:41 | 显示全部楼层
vb2*** 发表于 2024-8-2 21:00
哥,我想了一天..您说的是这个意思吗?
按您说的,好像是真的无敌哦...就是代码难倒我了!!!!

也行,最高位表示是否已使用,已使用就写成0,可以不用一个扇区当计数器了
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-2 21:42:51 | 显示全部楼层
wnag*** 发表于 2024-8-2 21:19
这是我之前做的磨损均衡代码,做吊顶灯,每次关机记录当前状态,共3种状态:冷光,暖光,均衡。就是普通的 ...

这个是我想的思路. 把8个扇区全部写满再擦除.     你的那个功能就是 在扇区8进行读写写写写写写,,写满扇区8 ,然后擦除扇区8  (算一次擦除.)

截图202408022142399715.jpg

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:351
  • 最近打卡:2025-05-02 00:50:51
已绑定手机

130

主题

1520

回帖

1859

积分

金牌会员

积分
1859
发表于 2024-8-3 00:14:37 | 显示全部楼层
Debu*** 发表于 2024-8-2 21:33
也行,最高位表示是否已使用,已使用就写成0,可以不用一个扇区当计数器了 ...

我试了一晚上了.
好像写之前必须要擦除
不能那样一个字节的写入,然后总体擦除
u16 add= 3584;
state=IapRead(add);
IapProgram(add, state);

点评

写只能把1变0,擦除是整个扇区变成1,一位一位写就可以一位一位的变0,一个扇区就可以当成4096bit的计数器  详情 回复 发表于 2024-8-3 00:17
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-3 00:17:24 | 显示全部楼层
vb2*** 发表于 2024-8-3 00:14
我试了一晚上了.
好像写之前必须要擦除
不能那样一个字节的写入,然后总体擦除

写只能把1变0,擦除是整个扇区变成1,一位一位写就可以一位一位的变0,一个扇区就可以当成4096bit的计数器
DebugLab
回复 支持 1 反对 0

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 02:13 , Processed in 0.148006 second(s), 113 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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