ysdqhwrm 发表于 2026-1-31 15:53:25

STC32G8K64读写EEPROM异常

我把读写的程序贴上来,帮忙看下有啥错误吗? 读出来的数据错误,搞不清写的错误还是读的有问题。

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

/* IAP读数据 参数addr是16位地址 */
char IapRead(int addr)
{
        char dat;

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

        return dat;
}

/* IAP写数据 参数addr是16位地址 dat是要写入的数据 */
void IapProgram(int addr, char dat)
{
        IAP_CONTR = 0x80;                         //使能IAP
        IAP_TPS = 35;                           // 当前主频35M
        IAP_CMD = 2;                              //设置IAP写命令
        IAP_ADDRL = addr;                           //设置IAP低地址
        IAP_ADDRH = addr >> 8;                      //设置IAP高地址
        IAP_DATA = dat;                           //写IAP数据
        EA=0;
        _nop_();
        _nop_();
        IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
        IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
        _nop_();
                _nop_();
        _nop_();
        _nop_();
        _nop_();
        EA=1;
        IapIdle();                                  //关闭IAP功能
}

/* IAP擦除数据参数addr是要擦除的16位地址
   该命令会擦除参数所在地址的512个字节 */
void IapErase(int addr)
{
        IAP_CONTR = 0x80;                         //使能IAP
        IAP_TPS = 35;                           // 当前主频35M
        IAP_CMD = 3;                              //设置IAP擦除命令
        IAP_ADDRL = addr;                           //设置IAP低地址
        IAP_ADDRH = addr >> 8;                      //设置IAP高地址
        EA=0;
        _nop_();
        _nop_();
        IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
        IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();        //
        EA=1;
        IapIdle();                                  //关闭IAP功能
}

char tem,value;

void main(void)
{
        EAXFR = 1;        //允许访问扩展寄存器
        WTST= 0;
        CKCON = 0;
        P_SW2=0X80;
        I2CCFG = 0xC1;//使能IIC主机模式1110
        I2CMSST = 0x00;
        EA = 1;
        io_init();
        OLED_Init();
        IapErase(0x0000);      //擦除扇区
        IapProgram(0x0000, 9);
        IapProgram(0x0001, 8);
        IapProgram(0x0002, 7);//随意三个地址写入三个数值

while (1)
        {

               
                if(key1==1)
                {
                        tem++;   
       
                        oled_ShowNum(0,0,tem,3,16);   //按键tem自加1第一行显示tem值
                        if(tem==1)       
                        value=IapRead(0x0000);   //根据tem值变化 读EEPROM不同地址的值
                        if(tem==2)       
                        value=IapRead(0x0001);
                        if(tem==3)       
                        value=IapRead(0x0002);
                       
                        oled_ShowNum(0,2,value,3,16);//第二行显示读出来的 EEPROM值
                       
                       
                }


}
OLED的程序就不贴了, 主要是EEPROM数据这样写和读的程序有问题吗?   第一行数值可以变化,第二行和第一行同时显示完1后一直显示的是1,大佬们帮看看EEPROM程序应该修改哪里可以正确的读写EEPROM呢?


神农鼎 发表于 2026-2-1 08:24:07


参考下面的参考程序:



深圳国芯人工智能有限公司-实验箱

llyymm 发表于 2026-2-1 09:01:43

看你的程序好像只擦除了0x0000扇区,每个扇区如果要覆盖之前的数据都必须要擦除才行的

21cnsound 发表于 2026-2-1 09:51:18

手册例程中,读写擦除函数入参addr用的unsigned long addr,函数中设置了IAP_ADDRE,按官方例程修改一下试试。

Roswcr 发表于 2026-2-3 13:53:52

llyymm 发表于 2026-2-1 09:01
看你的程序好像只擦除了0x0000扇区,每个扇区如果要覆盖之前的数据都必须要擦除才行的 ...

楼主的擦除操作已经是擦除0x0000-0x01FF这第一个扇区了,后来程序写入的地址也是在这个区域。
页: [1]
查看完整版本: STC32G8K64读写EEPROM异常