找回密码
 立即注册
查看: 28|回复: 6

求助:IAP15W4K58s读写EEPROM失效

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-07-18 16:13:57
已绑定手机

1

主题

2

回帖

11

积分

新手上路

积分
11
发表于 昨天 16:13 | 显示全部楼层 |阅读模式
大神们,我用STC15库函数写IAP15W4K58s的EEPROM,好像写不进去.请各位大神帮我看下.另外库函数STC15FXXXX.H里的
#define         ISP_TRIG()        ISP_TRIG = 0x5A,        ISP_TRIG = 0xA5        其中的逗号是不是应该为分号?       




//========================================================================
void ReadParaFromEprom(void)
{
    EEPROM_read_n(EPROMSetParatAdd,EpromRecordData,SizeOfRecord);                     
    SetParaStructure.Unit=(((EpromRecordData[0]>=Unit_gf)&&(EpromRecordData[0]<=Unit_N ))?EpromRecordData[0]:SetParaInit.Unit);      
    SetParaStructure.WireFactor=(((EpromRecordData[1]>=0)&&(EpromRecordData[1]<=20 ))?EpromRecordData[1]:SetParaInit.WireFactor);     
    SetParaStructure.CloseTime=(((((u16)EpromRecordData[2]<<8|(u16)EpromRecordData[3])>=0)&&(((u16)EpromRecordData[2]<<8|(u16)EpromRecordData[3])<=3600))?((u16)EpromRecordData[2]<<8|(u16)EpromRecordData[3]):SetParaInit.CloseTime);   
    SetParaStructure.Sensitive=(((((u16)EpromRecordData[4]<<8|(u16)EpromRecordData[5])>=100)&&(((u16)EpromRecordData[4]<<8|(u16)EpromRecordData[5])<=2000))?((u16)EpromRecordData[4]<<8|(u16)EpromRecordData[5]):SetParaInit.Sensitive);   
    SetParaStructure.FlashSpeed=(((((u16)EpromRecordData[6]<<8|(u16)EpromRecordData[7])>=500)&&(((u16)EpromRecordData[6]<<8|(u16)EpromRecordData[7])<=5000))?((u16)EpromRecordData[6]<<8|(u16)EpromRecordData[7]):SetParaInit.FlashSpeed);   
    SetParaStructure.LastSaveNum=(((((u16)EpromRecordData[8]<<8|(u16)EpromRecordData[9])>=0)&&(((u16)EpromRecordData[8]<<8|(u16)EpromRecordData[9])<=127))?((u16)EpromRecordData[8]<<8|(u16)EpromRecordData[9]):SetParaInit.LastSaveNum);  
}


//========================================================================
void WritePara2Eprom(void)
{
    EEPROM_read_n(EPROMStartAdd ,EpromSectionData,SizeOfSection);                    
    EEPROM_SectorErase(EPROMStartAdd);                                      
    EpromSectionData[0]=SetParaStructure.Unit;
    EpromSectionData[1]=SetParaStructure.WireFactor;
    EpromSectionData[2]=SetParaStructure.CloseTime>>8;
    EpromSectionData[3]=SetParaStructure.CloseTime;
    EpromSectionData[4]=SetParaStructure.Sensitive>>8;
    EpromSectionData[5]=SetParaStructure.Sensitive;
    EpromSectionData[6]=SetParaStructure.FlashSpeed>>8;
    EpromSectionData[7]=SetParaStructure.FlashSpeed;
    EpromSectionData[8]=SetParaStructure.LastSaveNum>>8;
    EpromSectionData[9]=SetParaStructure.LastSaveNum;
    EEPROM_write_n(EPROMStartAdd,EpromSectionData,SizeOfSection);           
}


相关的库函数如下:

//========================================================================
void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
{
        EA = 0;                //½ûÖ¹ÖжÏ

        ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);        //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
        ISP_WRITE();                                                        //ËÍ×Ö½ÚдÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
        do
        {
                ISP_ADDRH = EE_address / 256;                //Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
                ISP_ADDRL = EE_address % 256;                //Ë͵ØÖ·µÍ×Ö½Ú
                ISP_DATA  = *DataAddress;                        //ËÍÊý¾Ýµ½ISP_DATA£¬Ö»ÓÐÊý¾Ý¸Ä±äʱ²ÅÐèÖØÐÂËÍ
                //ISP_TRIG();
        ISP_TRIG = 0x5A;
        ISP_TRIG = 0xA5;
                _nop_();
        _nop_();
        _nop_();
        _nop_();
                EE_address++;
                DataAddress++;
        }while(--number);

        DisableEEPROM();
        EA = 1;                //ÖØÐÂÔÊÐíÖжÏ
}




//========================================================================
void EEPROM_SectorErase(u16 EE_address)
{
        EA = 0;                //½ûÖ¹ÖжÏ
                                                                                        //Ö»ÓÐÉÈÇø²Á³ý£¬Ã»ÓÐ×Ö½Ú²Á³ý£¬512×Ö½Ú/ÉÈÇø¡£
                                                                                        //ÉÈÇøÖÐÈÎÒâÒ»¸ö×Ö½ÚµØÖ·¶¼ÊÇÉÈÇøµØÖ·¡£
        ISP_ADDRH = EE_address / 256;                        //ËÍÉÈÇøµØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
        ISP_ADDRL = EE_address % 256;                        //ËÍÉÈÇøµØÖ·µÍ×Ö½Ú
        ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);        //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
        ISP_ERASE();                                                        //ËÍÉÈÇø²Á³ýÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
        //ISP_TRIG();
    ISP_TRIG = 0x5A;
    ISP_TRIG = 0xA5;
        _nop_();
    _nop_();
    _nop_();
    _nop_();
        DisableEEPROM();
        EA = 1;                //ÖØÐÂÔÊÐíÖжÏ
}




//========================================================================

void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
{
        EA = 0;                //½ûÖ¹ÖжÏ
        ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);        //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
        ISP_READ();                                                                        //ËÍ×Ö½Ú¶ÁÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
        do
        {
                ISP_ADDRH = EE_address / 256;                //Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
                ISP_ADDRL = EE_address % 256;                //Ë͵ØÖ·µÍ×Ö½Ú
//                ISP_TRIG();                                                        //ÏÈËÍ5AH£¬ÔÙËÍA5Hµ½ISP/IAP´¥·¢¼Ä´æÆ÷£¬Ã¿´Î¶¼ÐèÒªÈç´Ë
//                                                                                        //ËÍÍêA5Hºó£¬ISP/IAPÃüÁîÁ¢¼´±»´¥·¢Æô¶¯
//                                                                                        //CPUµÈ´ýIAPÍê³Éºó£¬²Å»á¼ÌÐøÖ´ÐгÌÐò¡£
        ISP_TRIG = 0x5A;
        ISP_TRIG = 0xA5;
                _nop_();
        _nop_();
        _nop_();
        _nop_();
                *DataAddress = ISP_DATA;                        //¶Á³öµÄÊý¾ÝËÍÍù
                EE_address++;
                DataAddress++;
        }while(--number);

        DisableEEPROM();
        EA = 1;                //ÖØÐÂÔÊÐíÖжÏ
}



//========================================================================
void        DisableEEPROM(void)
{
        ISP_CONTR = 0;                        //½ûÖ¹ISP/IAP²Ù×÷
        ISP_CMD   = 0;                        //È¥³ýISP/IAPÃüÁî
        ISP_TRIG  = 0;                        //·ÀÖ¹ISP/IAPÃüÁîÎó´¥·¢
        ISP_ADDRH = 0xff;                //Çå0µØÖ·¸ß×Ö½Ú
        ISP_ADDRL = 0xff;                //Çå0µØÖ·µÍ×Ö½Ú£¬Ö¸Ïò·ÇEEPROMÇø£¬·ÀÖ¹Îó²Ù×÷
}




回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-07-18 16:13:57
已绑定手机

1

主题

2

回帖

11

积分

新手上路

积分
11
发表于 昨天 16:19 | 显示全部楼层
EEPRO读写地址如下:
#define     EPROMStartAdd         0xE000
#define     EPROMSetParatAdd      0xE000
#define     SizeOfSection           512
#define     SizeOfRecord            16

点评

总大小0xE800,0xE000也没有超出范围,使用的是倒数第4个扇区,地址没有问题  详情 回复 发表于 昨天 19:16
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-07-18 16:13:57
已绑定手机

1

主题

2

回帖

11

积分

新手上路

积分
11
发表于 昨天 16:29 | 显示全部楼层
您好,您回复的:
1.需确认EPROMSetParatAdd是有效的EEPROM地址(通常为0x0000~0x07FF),且SizeOfRecord不超过单次写入限制(一般为16字节)。IAP15W4K58S有效的EEPROM地址应该为:0x0000~0xE7FF吧.另外单次写入限制为什么只有16个字节?
2.建议使用轮询方式等待ISPFLAG标志位:IAP15W4K58S有ISPFLAG标志位吗?

点评

这是人工智能(AI)回答的,可能有误  发表于 昨天 17:52
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:501
  • 最近打卡:2025-07-19 08:50:15
已绑定手机

82

主题

5404

回帖

9766

积分

超级版主

DebugLab

积分
9766
发表于 昨天 17:52 | 显示全部楼层
EEPROM程序供参考:

  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.         unsigned char dat;
  12.         unsigned int add;
  13.         add=sector*0x0200+addr;
  14.         IAP_CONTR|=IAPEN;
  15.         IAP_TPS=IAP_TPS_;
  16.         IAP_CMD=IAP_READ;
  17.         IAP_ADDRL=add;
  18.         IAP_ADDRH=add>>8;
  19.         IAP_TRIG=0x5A;
  20.         IAP_TRIG=0xA5;
  21.         _nop_();
  22.         dat=IAP_DATA;
  23.         Iap_Idle();
  24.         return dat;
  25. }
  26. void Iap_Program_Byte(unsigned char sector,unsigned int addr,unsigned char dat)
  27. {
  28.         unsigned int add;
  29.         add=sector*0x0200+addr;
  30.         IAP_CONTR|=IAPEN;
  31.         IAP_TPS=IAP_TPS_;
  32.         IAP_CMD=IAP_WRITE;
  33.         IAP_ADDRL=add;
  34.         IAP_ADDRH=add>>8;
  35.         IAP_DATA=dat;
  36.         IAP_TRIG=0x5A;
  37.         IAP_TRIG=0xA5;
  38.         _nop_();
  39.         Iap_Idle();
  40. }
  41. void Iap_Erase_Sector(unsigned char sector)
  42. {
  43.         unsigned int add;
  44.         add=sector*0x0200;
  45.         IAP_CONTR|=IAPEN;
  46.         IAP_TPS=IAP_TPS_;
  47.         IAP_CMD=IAP_ERASE;
  48.         IAP_ADDRL=add;
  49.         IAP_ADDRH=add>>8;
  50.         IAP_TRIG=0x5A;
  51.         IAP_TRIG=0xA5;
  52.         _nop_();
  53.         Iap_Idle();
  54. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:501
  • 最近打卡:2025-07-19 08:50:15
已绑定手机

82

主题

5404

回帖

9766

积分

超级版主

DebugLab

积分
9766
发表于 昨天 19:07 | 显示全部楼层
应该是分号
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:501
  • 最近打卡:2025-07-19 08:50:15
已绑定手机

82

主题

5404

回帖

9766

积分

超级版主

DebugLab

积分
9766
发表于 昨天 19:16 | 显示全部楼层
sin*** 发表于 2025-7-18 16:19
EEPRO读写地址如下:
#define     EPROMStartAdd         0xE000
#define     EPROMSetParatAdd      0xE00 ...

总大小0xE800,0xE000也没有超出范围,使用的是倒数第4个扇区,地址没有问题
DebugLab
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-7-19 13:52 , Processed in 0.124817 second(s), 76 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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