找回密码
 立即注册
查看: 614|回复: 8

STC8H2K08U在IAP_EEPROM验证时不能正常写入读取多个数据__已确认修复

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-05-02 21:48:56

6

主题

48

回帖

614

积分

高级会员

积分
614
发表于 2024-4-2 16:22:25 | 显示全部楼层 |阅读模式
本帖最后由 qq603599910 于 2024-6-11 10:30 编辑


2024-06-11 最终确认修复结果:之前没有确认准确原因一直在尝试,然后太多不稳定因素干扰导致一直没有找到准确原因,然后前辈回复让我尝试增加延时,我把延时增加在外部步骤代码上没有作用,需要增加在Flash_Read函数代码内部,如图.


char Flash_Read(int addr)
{
    char dat;
    EA = 0;     //禁止中断
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    IAP_CMD = 1;                                //设置IAP读命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();                  ====================================== 这里增加2个延时即输出正常.
    _nop_();                  ======================================
    _nop_();
    dat = IAP_DATA;                             //读IAP数据
    Flash_Idle();                                  //关闭IAP功能
    EA = 1;     //重新允许中断
    return dat;
}


=============原文 =======================

各位前辈,最近新拿STC8H2K08U开始做基础代码调试,在IAP_EEPROM验证时不能正常写入读取多个数据,单个地址没有发现异常,基础代码是从范例复制,偶尔烧录一次又能正常读取但没有找到规律.
1: 开始从0x0001开始擦除,然后for循环读取已擦除的5个地址原始值,理论上0x0001-0x0005擦除后应该都是0xffff,但异常是0x0001地址不能被擦除.
2: 从0x0001-0x0005一次写入"0,1,2,3,4"个数值,然后读取已写入值变成"4,0,1,2,3" .我试过N种方法,例如改数据量,用数组,改初始地址,改地址排列都不能找到规律.
3: 调试偶尔烧录后能正常写入读取数据顺序不会变所有地址擦除也正常.但可能第二次烧录后又是读取顺序异常,第一个地址不能被擦除.


以下是验证代码:========================================================
void IAP_Test(void)   //EEPROM验证.


{
    IAP_Erase(0x0001);  //从0x0001起始擦除


    for (i=0; i<5; i++)
    {
        printf("IAP_Erase,%01u:%01u\r\n",(u16)(i),(u16)IAP_Read(0x0001+i));  //读取并发送擦除的5个地址(0xFFFF)

    }

    for (i=0; i<5; i++)
    {
        IAP_Program(0x0001+i,i);   //写入5个地址数据

    }

    for (i=0; i<5; i++)
    {
        printf("IAP_Program,%01u:%01u\r\n",(u16)(i),(u16)IAP_Read(0x0001+i));//读取并发送写入5个地址的数据

    }
}



以下是打印输出:======================================

时间                      数据描述,顺序号:数据
[15:54:44.632]接收:IAP_Erase,0:0                         <<<0x0001地址这个应该是65535(0xFFFF)
                             IAP_Erase,1:65535
                             IAP_Erase,2:65535
                             IAP_Erase,3:65535
                             IAP_Erase,4:65535
                             IAP_Program,0:4                          <<<0x0001地址这个应该是0,被占了一个地址,一次后排.
                             IAP_Program,1:0
                             IAP_Program,2:1
                             IAP_Program,3:2
                             IAP_Program,4:3
                  
[15:54:46.612]接收:IAP_Erase,0:4                    <<< 0x0001地址这次数据"4"上一次写入的值.不能被擦除
                             IAP_Erase,1:65535
                             IAP_Erase,2:65535
                             IAP_Erase,3:65535
                             IAP_Erase,4:65535
                             IAP_Program,0:4
                             IAP_Program,1:0
                             IAP_Program,2:1
                             IAP_Program,3:2
                             IAP_Program,4:3



基础代码是从范例复制==================

#include "inc\eeprom.h"

void IAP_Idle()   //IAP关闭
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

char IAP_Read(int addr)   //读取IAP
{
    char dat;

    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    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数据
    IAP_Idle();                                  //关闭IAP功能

    return dat;
}

void IAP_Program(int addr, char dat)  //写IAP
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    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_();
    IAP_Idle();                                  //关闭IAP功能
}

void IAP_Erase(int addr)   //清除IAP地址
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //设置等待参数12MHz
    IAP_CMD = 3;                                //设置IAP擦除命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();                                    //
    IAP_Idle();                                  //关闭IAP功能
}

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:172
  • 最近打卡:2025-04-28 08:49:07
已绑定手机

90

主题

961

回帖

2318

积分

超级版主

积分
2318
QQ
发表于 2024-4-2 17:02:14 | 显示全部楼层
加3个nop  放慢速度 试一下
热线19952583534
www.STCAI.com
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-4-3 07:50:43 | 显示全部楼层
用官方例程测试一下,如果结果正确,再进行修改
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-05-02 21:48:56

6

主题

48

回帖

614

积分

高级会员

积分
614
发表于 2024-4-3 12:06:41 | 显示全部楼层
小*** 发表于 2024-4-3 07:50
用官方例程测试一下,如果结果正确,再进行修改

官方例程是单个数据操作没有问题的.
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-05-02 21:48:56

6

主题

48

回帖

614

积分

高级会员

积分
614
发表于 2024-4-3 12:07:33 | 显示全部楼层
国学*** 发表于 2024-4-2 17:02
加3个nop  放慢速度 试一下

谢谢!尝试了每个操作加延时5ms,还是一样.
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-4-3 14:30:51 | 显示全部楼层
1、你的系统时钟,是不是12M?
2、读数据之前关中断,读完后再打开中断
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:172
  • 最近打卡:2025-04-28 08:49:07
已绑定手机

90

主题

961

回帖

2318

积分

超级版主

积分
2318
QQ
发表于 2024-4-3 15:19:57 | 显示全部楼层
测试一下
STC8-EEPROM基本操作-P32按键通过串口1输出.zip (9.15 KB, 下载次数: 77)
热线19952583534
www.STCAI.com
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-05-02 21:48:56

6

主题

48

回帖

614

积分

高级会员

积分
614
发表于 2024-4-15 11:45:21 | 显示全部楼层

你好! 今天初步有个结论点:

1: 下载你提供的例程前两次下载是OK的, 后来下载还是EEPROM异常,异常读取值如下(可以确认下载操作是没有疏漏,和USB-CDC代码反复交替验证确认结果):

[11:33:46.470]接收:Key1 pressed.
                   Read1=0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read2=0x01 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
                  
[11:33:49.672]接收:Key1 pressed.
                   Read1=0x09 0x01 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08
                   Read2=0x0a 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
                  
[11:33:50.644]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08
                   Read2=0x0a 0x0b 0x03 0x03 0x04 0x05 0x06 0x07 0x08 0x09
                  
[11:33:51.461]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x03 0x03 0x04 0x05 0x06 0x07 0x08
                   Read2=0x0a 0x0b 0x0c 0x04 0x04 0x05 0x06 0x07 0x08 0x09
                  
[11:33:52.183]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x04 0x04 0x05 0x06 0x07 0x08
                   Read2=0x0a 0x0b 0x0c 0x0d 0x05 0x05 0x06 0x07 0x08 0x09
                  
[11:33:52.891]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x05 0x05 0x06 0x07 0x08
                   Read2=0x0a 0x0b 0x0c 0x0d 0x0e 0x06 0x06 0x07 0x08 0x09
                  
[11:33:53.541]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x06 0x06 0x07 0x08
                   Read2=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x07 0x07 0x08 0x09
                  
[11:33:54.250]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x07 0x07 0x08
                   Read2=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x08 0x08 0x09
                  
[11:33:54.880]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x08 0x08
                   Read2=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x09 0x09
                  
[11:33:55.525]接收:Key1 pressed.
                   Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x09
                   Read2=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x0a
                  
[11:33:59.472]接收:Key1 pressed.
                   Read1=0x0a 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12
                   Read2=0x0b 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13
                  
[11:34:03.953]接收:Key1 pressed.
                   Read1=0x13 0x0b 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12
                   Read2=0x14 0x0c 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13
                  
[11:34:07.878]接收:Key1 pressed.
                   Read1=0x13 0x14 0x0c 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12
                   Read2=0x14 0x15 0x0d 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13

2: 使用我自己原来的USB-CDC例程代码发现规律了,就是sys_init()打开ADC功能就EEPROM异常,关闭ADC后EEPROM一直正常读取.
void sys_init()
{
    P_SW2 |= 0x80;     //扩展寄存器(XFR)访问使能
    P_SWX1 = 0x01;          //调换P5.4切换为P1.2
    ////00->准双向 01->推挽PP 10->高阻输入Zin 11->开漏OD
    //P0M1 = 0xFF;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x01;
    P1M0 = 0x00;   //设置为准双向口
    //P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;
    P3M0 = 0x00;   //设置为准双向口
    //P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    //P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    //P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    //P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //ADC初始化寄存器  ===配置就EEPROM读取异常,关闭就正常读取EEPROM
    //ADCTIM = 0x3f;  //设置通道选择时间、保持时间、采样时间
    //ADCCFG = RES_FMT + ADC_SPEED;
    //ADC模块电源打开后,需等待1ms,MCU内部ADC电源稳定后再进行AD转换
    //ADC_CONTR = 0x80 + 0;

}


正常读取信息如下: Read1是原始值,Read2是清空后读取值,Read3是写入后的值.

[11:19:14.755]接收:Read1=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
                  
[11:19:14.956]接收:Read1=0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a
                  
[11:19:19.392]接收:Read1=0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b
                  
[11:19:19.453]接收:Read1=0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c
                  
[11:19:20.069]接收:Read1=0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d
                  
[11:19:20.177]接收:Read1=0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e
                  
[11:19:20.669]接收:Read1=0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
                  
[11:19:21.207]接收:Read1=0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10
                  
[11:19:21.330]接收:Read1=0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11
                  
[11:19:21.746]接收:Read1=0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12
                  
[11:19:22.253]接收:Read1=0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13
                  
[11:19:22.759]接收:Read1=0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13
                   Read2=0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
                   Read3=0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14









回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-05-02 21:48:56

6

主题

48

回帖

614

积分

高级会员

积分
614
发表于 2024-4-15 11:50:21 | 显示全部楼层
本帖最后由 qq603599910 于 2024-4-15 11:52 编辑

你的例程是在反复验证USB-CDC代码ADC关闭EEPROM读取正常后再烧录回你的原始bin文件都是EEPROM读取异常,但可以确认初始烧录是完全正常读取EEPROM的.现在我的USB-CDC代码关闭ADC后EEPROM读取很稳定,不过我的案子是需要启动ADC的,所以还要麻烦帮忙确认代码,感谢!!!

STC8H2K08U_EEPROM.zip

45.62 KB, 下载次数: 73

这是USB-CDC EEPROM正常读取的代码.

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 18:07 , Processed in 0.141030 second(s), 104 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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