找回密码
 立即注册
查看: 1522|回复: 29

EEPROM 无法存储问题 | 已解决

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-22 06:20:58 | 显示全部楼层 |阅读模式
本帖最后由 32位8051-STCAI 于 2024-5-28 13:33 编辑

截图202405220616525925.jpg

使用芯片及设置如上图;
目前状态是数据无法存储,代码如下

void update_eeprom_passwd()           //参照论坛例程
{
        EEPROM_SectorErase(0);
        EEPROM_write_n(0                     //写入的起始地址
                                , (void*)&man_data.passwd                   //buf数据存放的起始地址
                                , sizeof(man_data.passwd));    //
}


u8 update_admin_passwd(u8 buf[],u8 len)
{
        if(in_len == 0)
        {
                for(i=0;i<len;i++)
                {
                        old_key = buf;
                }
                in_len = len;
               
          TX1_write2buff(i%10+'0'); //测试用               
                return 1;
        }
        return 0;
}
//****************************************************
u8 update_admin_passwd1(u8 buf[],u8 len)
{        
/************************************************************************/        
        if(in_len != len)  //第二次输入长度不对
        {
                PrintString1("erci changdu ng\n\r");
                return 0;  //返回错误。
        }
        
        for(i=0;i<len;i++)
        {
                if(old_key != buf)
                {
                        PrintString1("erci shuju ng\n\r");
                        return 0;   //返回错误,第一次和第二次输入的不一致
                }
        }
        
        in_len = 0;    //输入正确,清零全局变量。               
        for(i=0;i<len;i++)
        {
                man_data.passwd = buf;
        }
        man_data.passwd_len = len;
        for(;i<6;i++)
        {
                man_data.passwd = 0xff;
        }
        delay_ms(20);
        update_eeprom_passwd();
        PrintString1("123123\n\r");
        return 1;
/************************************************************************/               
}


回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-22 06:25:03 | 显示全部楼层
截图202405220624471609.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:233
  • 最近打卡:2025-04-30 16:08:37

61

主题

818

回帖

1490

积分

金牌会员

积分
1490
发表于 2024-5-22 07:32:06 | 显示全部楼层

把程序发上来  这样没法看   
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-22 09:13:02 | 显示全部楼层
/******************************************************************/
#include        "eeprom.h"
/******************************************************************/
void IapIdle()
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

/********************************************************
读单片机EEPROM
********************************************************/
static  u8 read_eeprom(u16 addr)
{
    u8 dat;

    IAP_CONTR = WT_20M;                         //使能IAP
    IAP_CMD = 1;                                //设置IAP读命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //读IAP数据
    IapIdle();                                  //关闭IAP功能

    return dat;
}

/********************************************************
单片机EEPROM扇区擦除
********************************************************/
void erase_eeprom(u16 addr)
{
    IAP_CONTR = WT_20M;                         //使能IAP
    IAP_CMD = 3;                                //设置IAP擦除命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();  
                _nop_();
                _nop_();         
    IapIdle();  
}

/******************************************************************/
// void DisableEEPROM(void)  
/******************************************************************/
void DisableEEPROM(void)         //禁止IAP操作
{
        IAP_CONTR = 0;           //禁止IAP操作
        IAP_CMD   = 0;           //去除IAP命令
        IAP_TRIG  = 0;           //防止IAP命令误触发
//        IAP_ADDRH = 0xff;        //清0地址高字节
//        IAP_ADDRL = 0xff;        //清0地址低字节,指向非EEPROM区,防止误操作
        IAP_ADDRH = 0x80;        //清0地址高字节
        IAP_ADDRL = 0;           //清0地址低字节,指向非EEPROM区,防止误操作
}
/******************************************************************/
// void EEPROM_Trig(void)  
/******************************************************************/
void EEPROM_Trig(void)   //触发EEPROM
{
        F0 = EA;    //保存全局中断
        EA = 0;     //禁止中断, 避免触发命令无效
        IAP_TRIG = 0x5A; //先送5AH,再送A5H到IAP触发寄存器,每次都需要如此
        IAP_TRIG = 0xA5; //送完A5H后,IAP命令立即被触发启动//CPU等待IAP完成后,才会继续执行程序。
        _nop_();  
        _nop_();        
        _nop_();     //3个空指令等待一下
        EA = F0;    //恢复全局中断
}

/******************************************************************/
// void EEPROM_read_n(EE_address,*DataAddress,number)
// 参数: EE_address:读取EEPROM的首地址.
// DataAddress:     读取数据后给到 数组首地址.
// number:          读取的字节长度.
/******************************************************************/

void EEPROM_read_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)
{
        IAP_ENABLE(); //设置等待时间,允许IAP操作,送一次就够
        IAP_CMD = 1;  //=1读;送字节读命令,命令不需改变时,不需重新送命令
        do
        {
                IAP_ADDRH = EE_address / 256;//送地址高字节(地址需要改变时才需重新送地址)
                IAP_ADDRL = EE_address % 256; //送地址低字节
                EEPROM_Trig(); //触发EEPROM操作
                *DataAddress = IAP_DATA;//读出的数据送往
                EE_address++;
                DataAddress++;
        }
        while(--number);
        DisableEEPROM();
}
/******************************************************************/
// void EEPROM_SectorErase(unsigned int EE_address)  
/******************************************************************/
void EEPROM_SectorErase(unsigned int EE_address)
{
         IAP_ENABLE();//设置等待时间,允许IAP操作,送一次就够
         IAP_CMD = 3;//宏调用, =3,送扇区擦除命令,命令不需改变时,不需重新送命令
         IAP_ADDRH = EE_address / 256; //送扇区地址高字节(地址需要改变时才需重新送地址)
         IAP_ADDRL = EE_address % 256;//送扇区地址低字节
         EEPROM_Trig();//触发EEPROM操作
                _nop_();
                _nop_();
                _nop_();       
                _nop_();
         DisableEEPROM();//禁止EEPROM操作
}
/******************************************************************/
//EEPROM_write_n(EE_address,*DataAddress,number)
/**********************z********************************************/
// 参数: EE_address:写入EEPROM的首地址.
// DataAddress: 写入源数据的缓冲的首地址. 就是从数组读取数据,
// number:写入的字节长度.

void EEPROM_write_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)
{
IAP_ENABLE(); //设置等待时间,允许IAP操作,送一次就够
IAP_CMD = 2;//宏调用, =2,送字节写命令
do
{
         IAP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址)
         IAP_ADDRL = EE_address % 256;//送地址低字节
         IAP_DATA= *DataAddress;//送数据到IAP_DATA,只有数据改变时才需重新送
         EEPROM_Trig();//触发EEPROM操作
         _nop_();
         _nop_();
         _nop_();
         EE_address++;//下一个地址
         DataAddress++;//下一个数据
}
while(--number);//直到结束
DisableEEPROM();
}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-5-22 09:16:21 | 显示全部楼层
直接烧录附件例子到芯片里试试

STC8-EEPROM多字节读写操作-通过串口1输出.zip

8.28 KB, 下载次数: 98

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-22 09:18:33 | 显示全部楼层
通过设定的数值,与新按键的数值进行二次对比,相同就保存
#include "bijiao.h"

static u8 old_key[6];
static u8 in_len = 0;       
u8 i;
//#define BLOCK_PASS_TOTAL 80   //每个块密码存放的用户数

static U_ManageData  man_data = {{0,0,0,0,0,0},{3,4,5,3,4,5},{1,1,2,2,3,3},{0xff,0xff,0xff,0xff},6,6,6};
/******************************************************/

/******************************************************/
void update_eeprom_passwd()
{
        EEPROM_SectorErase(0);
        EEPROM_write_n(0                     //写入的起始地址
                                , (void*)&man_data.passwd                   //buf数据存放的起始地址
                                , sizeof(man_data.passwd));    //
}
/******************************************************/

/*
        更新系统的密码,这里需要输入两次密码,第一次做保存使用。
*/
u8 update_admin_passwd(u8 buf[],u8 len)
{
        if(in_len == 0)
        {
                for(i=0;i<len;i++)
                {
                        old_key[i] = buf[i];
                }
                in_len = len;
               
          TX1_write2buff(i%10+'0'); //测试用               
                return 1;
        }
        return 0;
}
//****************************************************
u8 update_admin_passwd1(u8 buf[],u8 len)
{       
/************************************************************************/       
        if(in_len != len)  //第二次输入长度不对
        {
                PrintString1("erci changdu ng\n\r");
                return 0;  //返回错误。
        }
       
        for(i=0;i<len;i++)
        {
                if(old_key[i] != buf[i])
                {
                        PrintString1("erci shuju ng\n\r");
                        return 0;   //返回错误,第一次和第二次输入的不一致
                }
        }
       
        in_len = 0;    //输入正确,清零全局变量。               
        for(i=0;i<len;i++)
        {
                man_data.passwd[i] = buf[i];
        }
        man_data.passwd_len = len;
        for(;i<6;i++)
        {
                man_data.passwd[i] = 0xff;
        }
        delay_ms(20);
        update_eeprom_passwd();
        PrintString1("123123\n\r");
        return 1;
/************************************************************************/               
}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-22 09:39:26 | 显示全部楼层
用大佬给的例程 可以进行擦除读写,如图
截图202405220938344626.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-23 09:08:10 | 显示全部楼层
自己的例程 eeprom不能保存数据,各位大佬 这个存在哪些问题

点评

示例代码都测试通过了,直接示例代码上修改自己想要的功能不就好了  详情 回复 发表于 2024-5-23 11:50
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-5-23 11:50:32 | 显示全部楼层
lier378*** 发表于 2024-5-23 09:08
自己的例程 eeprom不能保存数据,各位大佬 这个存在哪些问题

示例代码都测试通过了,直接示例代码上修改自己想要的功能不就好了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2025-03-28 11:36:20

8

主题

42

回帖

384

积分

中级会员

积分
384
发表于 2024-5-26 10:48:32 | 显示全部楼层
各位大佬在咨询下 ,
根据ISP 下载软件给 STC8H4k64TL分配2K的EEPROM 空间,
eeprom地址是从000--511 第一扇区,512--1023 第二扇区.....这样来区分吗
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 07:01 , Processed in 0.167007 second(s), 117 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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