找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1383|回复: 13
打印 上一主题 下一主题
收起左侧

STC8H单片机eeprom不能保存数据

[复制链接]
跳转到指定楼层
楼主
/******************************************************************/
#include    "eeprom.h"
#include <intrins.h>
/******************************************************************/
void IapIdle()
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

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

    return dat;
}

void IapProgram(int addr, unsigned char dat)
{
    //IAP_TPS = 12;
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_CMD = 2;                                //设置IAP写命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_DATA = dat;                             //写IAP数据
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();_nop_();_nop_();_nop_();
    IapIdle();                                  //关闭IAP功能
}

void IapErase(int addr)
{
    //IAP_TPS = 12;
    IAP_CONTR = 0x80;                           //使能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_();_nop_();                                     //
    IapIdle();                                  //关闭IAP功能
}


u8 update_admin_passwd(u8 buf[], u8 buf_len) // 第一次数据保存-临时
{
    u8 i;
    if (buf_len < 4 || buf_len > 10)
    {
        return 0;
    }
    for (i = 0; i < buf_len; i++)
    {
        old_key[i] = buf[i];
        if(buf[i]==0xff)
        {
            buf[i]=0xff; //如果内容为空,则写入初始化数据
            break;
        }
        printf("1次存储 %bd \r\n",  old_key[i]);  //第一次保存数据测试下是否其他位数也可以
        key_buf_index=0;
    }
    return 1;
}
u8 update_admin_passwd1(u8 buf1[], u8 buf_len) // 第二次对比测试-临时
{
    u8 i;
    if (byte_compare(old_key, buf1, buf_len))
    {
        EA=0; // 关闭总中断
        IapErase(EEPROM_ADD_1);
        for (i = 0; i < buf_len; i++)
        {
            new_key[i]=old_key[i];
            IapProgram(EEPROM_ADD_1 + i, new_key[i]);
            new_key[i]=IapRead(EEPROM_ADD_1 + i);
            printf("二次对比 %bd \r\n",  IapRead(EEPROM_ADD_1 + i));
        }
        printf("update_admin_passwd1 cunchu ok \r\n");
        passwd_bijiao=1;
        key_buf_index=0;
        EA=1; // 开启总中断
        return 1;
    }

调试的数据如下
[20:35:29.947]接收←12 /r/n初始化 永久,管理,临时key_value=12sys_key_state == PASSWD_UNLOCK[20:35:32.386]接收←key_value < 11key_value=3guanli[20:35:34.242]接收←key_value < 11key_value=7[20:35:34.601]接收←key_value < 11key_value=7[20:35:34.901]接收←key_value < 11key_value=7[20:35:35.170]接收←key_value < 11key_value=7[20:35:35.425]接收←key_value < 11key_value=7[20:35:35.739]接收←key_value < 11key_value=7[20:35:36.263]接收←12 /r/n初始化 永久,管理,临时key_value=12CMD_UPDATE_PASSWD17 7 7 7 7 7 [20:35:37.715]接收←key_value < 11key_value=7[20:35:38.045]接收←key_value < 11key_value=7[20:35:38.359]接收←key_value < 11key_value=7[20:35:38.629]接收←key_value < 11key_value=7[20:35:38.883]接收←key_value < 11key_value=7[20:35:39.213]接收←key_value < 11key_value=7[20:35:40.172]接收←12 /r/n初始化 永久,管理,临时key_value=12NEW_PASSWD3buf_len = 67 7 7 7 7 7 update_admin_common_pin cunchu ok [20:35:42.387]接收←key_value < 11key_value=7[20:35:42.686]接收←key_value < 11key_value=7[20:35:43.001]接收←key_value < 11key_value=7[20:35:43.374]接收←key_value < 11key_value=7[20:35:43.734]接收←key_value < 11key_value=7[20:35:44.077]接收←key_value < 11key_value=7[20:35:44.572]接收←12 /r/n管理密码模式new old_key_common du [0] = 7new old_key_common du [1] = 7new old_key_common du [2] = 7new old_key_common du [3] = 7new old_key_common du [4] = 7new old_key_common du [5] = 7key_value=12sys_key_state == PASSWD_UNLOCKin mode_yongjiu == 1 && mode_linshi == 0common_pin buf_len = 0admin_checkcommon_pin okkey_buf_index22=6[20:35:45.845]接收←new_key_yongjiu0=1new_key_yongjiu1=1new_key_yongjiu2=1new_key_yongjiu3=1
个人认为已经写入新的密码数据了,也读出来了,但是以断电 就又恢复出厂值了
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:68189 发表于 2024-9-2 08:40 | 只看该作者
单字节,指定地址读写,进行实验,如果没问题,就是你的连续读写代码有问题,另外注意连续读写跨扇区问题,STC是扇区擦除,写之前需要对当前扇区先进行擦除操作,才能写.严格按照官方的代码进行操作,一般不会出问题,另外设置等待参数为什么要注释掉呢: //IAP_TPS = 12;
回复

使用道具 举报

板凳
ID:161164 发表于 2024-9-2 09:37 | 只看该作者
代码不全,main()呢?
回复

使用道具 举报

地板
ID:961114 发表于 2024-9-2 10:13 | 只看该作者
平常不要操作 STC32G/STC8H的EEPROM:
1,上电时读到 SRAM 中;
2,平常在SRAM中改写;
3,掉电时及时保存到 EEPROM/DATA-FLASH中!
用内部比较器做外部掉电检测!!!
其他用法都是错误的用法

回复

使用道具 举报

5#
ID:961114 发表于 2024-9-2 10:14 | 只看该作者
回复

使用道具 举报

6#
ID:226055 发表于 2024-9-2 14:22 | 只看该作者
    1、你没有给出STC8H具体的单片机型号,所以一定注意,有些单片机是出厂自带EEPROM,有些没有EEPROM,而只有再手动分割FLASH出来作为EEPROM使用。手上正好有艾克姆科技的STC8H8K64U的开发板,把相关资料分享给你。

    2、STC8H8K64U是没有片内EEPROM的,所以需要在STC-ISP下载软件时分好EEPROM空间。如果芯片自带片内EEPROM,则无需分割,比如STC8H8K48U。


    3、程序源码见附件,下载程序后,打开串口助手可观察对片内EEPROM的读写操作。

EEPROM.rar

34.05 KB, 下载次数: 1

回复

使用道具 举报

7#
ID:57657 发表于 2024-9-2 16:39 | 只看该作者
STC的EEPROM的读写擦除方法:
字节读:部分系列可使用unsigned char/int/long code指针或汇编MOVC访问(STC89/90系列除外)。
字节编程:二进制1可以写为0,0不能写为1,必须擦除后才可以继续写。
扇区擦除:没有字节擦除,1次擦1扇区为512字节,擦除后全部恢复为0xFF。
回复

使用道具 举报

8#
ID:307493 发表于 2024-9-2 22:07 | 只看该作者
#include "config.h"
/*************        功能说明        **************
选择时钟 11.0592MHz (可以在配置文件"config.h"中修改).
******************************************/
/**********************************************/
int main(void)
{
    P_SW2 |= 0x80; // 允许访问扩展寄存器xsfr
    IRCDB = 0x10;  // IRCDB设置减小,增加内部高速振荡器去抖
    IAP_TPS = 11;   //设置EEPROM操作等待参数(11.0592MHz),初始化设置一次即可
    EA    = 1;     // 允许全局中断
    INT0_Init();
    Timer0_Init();
    GPIO_config();
    PrintfInit(); // 串口波特率
    ADC_config();
    Touch_Init();
    /**********************************************/
    open_flag  = 1; // 默认开的状态
    close_flag = 0;
    /**********************************************/
    mode_yongjiu = 1;  //永久模式(固定模式)
    mode_linshi  = 0;
    /**********************************************/
    while (1)
    {
       // key();
        /**********************************************/
        Touch_Scan();
        /**********************************************/
        Show_Vol(); // 显示电池的电压
        /**********************************************/
        handle_key_function(); // 状态机切换
        /**********************************************/
    }
}
回复

使用道具 举报

9#
ID:307493 发表于 2024-9-2 22:13 | 只看该作者
21:48:48.679]接收←key_value < 11
key_value=7

[21:48:48.984]接收←key_value < 11
key_value=7

[21:48:49.275]接收←key_value < 11
key_value=7

[21:48:49.551]接收←key_value < 11
key_value=7

[21:48:49.857]接收←key_value < 11
key_value=7

[21:48:50.208]接收←key_value < 11
key_value=7

[21:48:50.786]接收←12 /r/nCMD_UPDATE_PASSWD1
一次对比 key_common[0]=7
一次对比 key_common[1]=7
一次对比 key_common[2]=7
一次对比 key_common[3]=7
一次对比 key_common[4]=7
一次对比 key_common[5]=7

[21:48:51.634]接收←key_value < 11
key_value=7

[21:48:51.937]接收←key_value < 11
key_value=7

[21:48:52.212]接收←key_value < 11
key_value=7

[21:48:52.470]接收←key_value < 11
key_value=7

[21:48:52.760]接收←key_value < 11
key_value=7

[21:48:53.094]接收←key_value < 11
key_value=7

[21:48:53.688]接收←12 /r/nNEW_PASSWD3
buf_len = 6
二次对比 new_key_common[0]=7
二次对比 new_key_common[1]=7
二次对比 new_key_common[2]=7
二次对比 new_key_common[3]=7
二次对比 new_key_common[4]=7
二次对比 new_key_common[5]=7

[21:48:55.758]接收←key_value < 11
key_value=7

[21:48:56.147]接收←key_value < 11
key_value=7

[21:48:56.431]接收←key_value < 11
key_value=7

[21:48:56.716]接收←key_value < 11
key_value=7

[21:48:57.033]接收←key_value < 11
key_value=7

[21:48:57.351]接收←key_value < 11
key_value=7

[21:48:58.293]接收←12 /r/nsys_key_state == PASSWD_UNLOCK
in mode_yongjiu == 1 && mode_linshi == 0
new_key_common=7 7 7 7 7 7 -1 -1
common_pin0 = 7
common_pin1 = 7
common_pin2 = 7
common_pin3 = 7
common_pin4 = 7
common_pin5 = 7
common_pin6 = -1
common_pin7 = -1
admin_checkcommon_pin ok
key_buf_index22=6
以上为验证的数据,能够写入也能够读出来,就是断电后不能保存

1.png (25.54 KB, 下载次数: 5)

1.png

2.png (62.46 KB, 下载次数: 5)

2.png
回复

使用道具 举报

10#
ID:307493 发表于 2024-9-2 22:14 | 只看该作者
wpppmlah 发表于 2024-9-2 08:40
单字节,指定地址读写,进行实验,如果没问题,就是你的连续读写代码有问题,另外注意连续读写跨扇区问题,STC是 ...

这个main 初始化已经初始化了 ,就是根据官方改的,目前可以写可以读,就是断电不会保存
回复

使用道具 举报

11#
ID:227818 发表于 2024-9-3 08:08 | 只看该作者
本帖最后由 newlined 于 2024-9-3 09:12 编辑

前边楼层已经想到了,编辑掉了,请版主删掉此贴,谢谢。
回复

使用道具 举报

12#
ID:161164 发表于 2024-9-4 09:47 | 只看该作者
qq378912453 发表于 2024-9-2 22:07
#include "config.h"
/*************        功能说明        **************
选择时钟 11.0592MHz (可以在配置文件"con ...

update_admin_passwd和update_admin_passwd1在哪里运行?
回复

使用道具 举报

13#
ID:624769 发表于 2024-9-4 22:20 | 只看该作者
STC庄伟 发表于 2024-9-2 10:13
平常不要操作 STC32G/STC8H的EEPROM:
1,上电时读到 SRAM 中;
2,平常在SRAM中改写;

你说用比较器做掉电检测,其他用法都是错的??

那么,STC的“掉电中断”是干什么吃的? 样子货?
回复

使用道具 举报

14#
ID:307493 发表于 2024-9-7 21:00 | 只看该作者
已解决,谢谢大家
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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