找回密码
 立即注册
查看: 233|回复: 5

使用eeprom时写入无返回错误,但读不出数据

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-04-14 00:31:51
已绑定手机

5

主题

43

回帖

355

积分

中级会员

积分
355
发表于 2025-2-28 01:05:04 | 显示全部楼层 |阅读模式

各位大佬先且看我的代码和log打印

#define CMD_IDLE    0               //空闲模式
#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令
#define ENABLE_IAP 0x80             //if SYSCLK<30MHz
#define IAP_TPS_CONSTANT ((FOSC/1000000)+1)
static const unsigned long iapTps = IAP_TPS_CONSTANT;
//********************关闭IAP*******************************ok
static void IapIdle()
{
    IAP_CONTR = 0;                  //关闭IAP功能
    IAP_CMD = 0;                    //清除命令寄存器
    IAP_TRIG = 0;                   //清除触发寄存器
    IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

//************************从ISP/IAP/EEPROM区域读取一字节****************************ok
static BYTE IapReadByte(WORD addr)
{
    BYTE dat;                       //数据缓冲区
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_TPS = iapTps; //设置等待参数 ********************************************STC8C2K64S2
    IAP_CMD = CMD_READ;             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
    IapIdle();                      //关闭IAP功能
    return dat;                     //返回
}

//*********写一字节数据到ISP/IAP/EEPROM区域*************************************ok
static BYTE IapProgramByte(WORD addr, BYTE dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_TPS = iapTps; //设置等待参数 ********************************************STC8C2K64S2
    IAP_CMD = CMD_PROGRAM;          //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();						//关闭IAP功能
    return FIND_BIT(IAP_CONTR, 4);
}

//**************************************扇区擦除************************************ok
static BYTE IapEraseSector(WORD addr)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_ERASE;            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();						//关闭IAP功能
    return FIND_BIT(IAP_CONTR, 4);
}
BYTE* eepRom_Read_DevAddr(void)
{
    unsigned char cnt;
    const unsigned char DevIdLen = EEPROM_DEVID_END_ADDR - EEPROM_DEVID_START_ADDR;
    memset(eepRomBuffer, 0, sizeof(eepRomBuffer));
    for ( cnt = 0; cnt < DevIdLen; cnt++ )
        eepRomBuffer[cnt] = IapReadByte(EEPROM_DEVID_START_ADDR + cnt);
    return eepRomBuffer;
}

int eepRom_Save_DeviceAddress(const char* DevId)
{
    unsigned char cnt = 0;
    BYTE Flag_QRcodeShow = 0;
    const int DevIdLen = EEPROM_DEVID_END_ADDR - EEPROM_DEVID_START_ADDR;
    if ( *(DevId + DevIdLen) != '\0' || DevId == NULL )
        return EEPROM_ERR_ARG; // 没有结束符或参数为NULL
    Flag_QRcodeShow = IapReadByte((WORD)EEPROM_QRCODE_FLAG_ADDR);
    DebugPrint(TAG, "frist, save QRcode flag: %bu", Flag_QRcodeShow);

    if ( IapEraseSector(IAP_ADDRESS2) )
        goto _EEPROM_ERR;

    DebugPrint(TAG, "erase successes... will write data: %s", DevId);
    for ( cnt = 0; cnt < DevIdLen; cnt++ )
    {
        if ( IapProgramByte((WORD)(IAP_ADDRESS2 + cnt), (BYTE)(*(DevId + cnt))) )
        {
            DebugPrint(TAG, "write eepRom error");
            goto _EEPROM_ERR;
        }

    }
    IapProgramByte((WORD)EEPROM_QRCODE_FLAG_ADDR, Flag_QRcodeShow);
    DebugPrint(TAG, "save data..");

    DebugPrint(TAG, "write data: %s", eepRom_Read_DevAddr());
    return (strcmp(DevId, eepRomBuffer) == 0) ? EEPROM_OK : EEPROM_FAIL;
_EEPROM_ERR:
    CLEAR_BIT(IAP_CONTR, 4); // 清除IAP错误
    return (int)IapEraseSector(IAP_ADDRESS2);
}

正是这么一段代码,但打印出了以下log

                    ----bufAddr status (ok), len 108 from UART2:
                    id.a001...a001
                  
                  
                    ----send to UART1
                    bufAddr:x:0689, bufferLen:0
                    [protocol]:funcString: id
                    [protocol]:into command 'ID'
                    [protocol]:print DevID
                    [eepRom]:frist, save QRcode flag: 0
                    [eepRom]:erase successes... will write data: a001
                    [eepRom]:save data..
                    [eepRom]:write data: 
                    [protocol]:save DevId status: fail

我一开始以为是没接收到数据,但并不是接收不到数据。我怀疑是数据根本就没有写入,但为什么会出现这种情况呢?若写入有报错了,我的代码应当返回错误值而不是继续写。还有,根据手册上的描述, IAP_TPS是一个等待时间控制寄存器,故此 _nop_()函数是必要的吗?能否用自定义的定时器延时函数替代?

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-04-14 00:31:51
已绑定手机

5

主题

43

回帖

355

积分

中级会员

积分
355
发表于 2025-2-28 01:09:58 | 显示全部楼层

在11.0592MHz的时候能正常写入
在27MHz的时候就没写进去

penxue

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-04-14 00:31:51
已绑定手机

5

主题

43

回帖

355

积分

中级会员

积分
355
发表于 2025-2-28 01:10:28 | 显示全部楼层

希望来个大佬为我答疑解惑🙏🙏🙏

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-04-14 00:31:51
已绑定手机

5

主题

43

回帖

355

积分

中级会员

积分
355
发表于 2025-2-28 01:23:02 | 显示全部楼层

有点玄学了。。。

从11.0592MHz试过OK以后,我将频率逐渐提升到33.1776MHz也写入正常了yiwen

我一时间分辨不清楚,是真的能写了还是只有这个能写了。。。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9138

积分

超级版主

DebugLab

积分
9138
发表于 2025-2-28 06:46:05 | 显示全部楼层
_nop_()函数是必要的
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9138

积分

超级版主

DebugLab

积分
9138
发表于 2025-2-28 06:47:32 | 显示全部楼层
  1. void Iap_Idle(void)
  2. {
  3.         IAP_CONTR&=~IAPEN;
  4.         IAP_CMD=IAP_IDL;
  5.         IAP_TRIG=0x00;
  6.         IAP_ADDRH=0x80;
  7.         IAP_ADDRL=0x00;
  8. }
  9. unsigned char Iap_Read_Byte(unsigned char sector,unsigned int addr)
  10. {
  11.         return *(CBYTE+IAP_OFFSET+sector*0x0200+addr);
  12. }
  13. //unsigned char Iap_Read_Byte(unsigned char sector,unsigned int addr)
  14. //{
  15. //        unsigned char dat;
  16. //        unsigned int add;
  17. //        add=sector*0x0200+addr;
  18. //        IAP_CONTR|=IAPEN;
  19. //        IAP_TPS=IAP_TPS_;
  20. //        IAP_CMD=IAP_READ;
  21. //        IAP_ADDRL=add;
  22. //        IAP_ADDRH=add>>8;
  23. //        IAP_TRIG=0x5A;
  24. //        IAP_TRIG=0xA5;
  25. //        _nop_();
  26. //        dat=IAP_DATA;
  27. //        Iap_Idle();
  28. //        return dat;
  29. //}
  30. void Iap_Program_Byte(unsigned char sector,unsigned int addr,unsigned char dat)
  31. {
  32.         unsigned int add;
  33.         add=sector*0x0200+addr;
  34.         IAP_CONTR|=IAPEN;
  35.         IAP_TPS=IAP_TPS_;
  36.         IAP_CMD=IAP_WRITE;
  37.         IAP_ADDRL=add;
  38.         IAP_ADDRH=add>>8;
  39.         IAP_DATA=dat;
  40.         IAP_TRIG=0x5A;
  41.         IAP_TRIG=0xA5;
  42.         _nop_();
  43.         Iap_Idle();
  44. }
  45. void Iap_Erase_Sector(unsigned char sector)
  46. {
  47.         unsigned int add;
  48.         add=sector*0x0200;
  49.         IAP_CONTR|=IAPEN;
  50.         IAP_TPS=IAP_TPS_;
  51.         IAP_CMD=IAP_ERASE;
  52.         IAP_ADDRL=add;
  53.         IAP_ADDRH=add>>8;
  54.         IAP_TRIG=0x5A;
  55.         IAP_TRIG=0xA5;
  56.         _nop_();
  57.         Iap_Idle();
  58. }
复制代码


DebugLab
回复 支持 1 反对 0

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-16 13:02 , Processed in 0.169701 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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