51单片机如何利用IAP实现数据掉电不丢失?相应程序怎么写?

51单片机如何利用IAP实现数据掉电不丢失?相应程序怎么写?,第1张

IAP的方式是写入到程序Flash区保持数据不丢失

写之前要保证区域内没有会被执行到的程序。否则写入数据后会导致程序死机会不断重启。

支持IAP的单片机类型比较多,请提供具体型号

以IAP15F2K61S2为例(STC官方代码)

//IAP特殊功能寄存器

sfr IAP_DATA    =   0xC2           //IAP数据寄存器

sfr IAP_ADDRH   =   0xC3           //IAP地址寄存器高字节

sfr IAP_ADDRL   =   0xC4           //IAP地址寄存器低字节

sfr IAP_CMD     =   0xC5           //IAP命令寄存器

sfr IAP_TRIG    =   0xC6           //IAP命令触发寄存器

sfr IAP_CONTR   =   0xC7           //IAP控制寄存器

//IAP工作模式

#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 ENABLE_IAP 0x81           //if SYSCLK<24MHz

#define ENABLE_IAP  0x82            //if SYSCLK<20MHz

//#define ENABLE_IAP 0x83           //if SYSCLK<12MHz

//#define ENABLE_IAP 0x84           //if SYSCLK<6MHz

//#define ENABLE_IAP 0x85           //if SYSCLK<3MHz

//#define ENABLE_IAP 0x86           //if SYSCLK<2MHz

//#define ENABLE_IAP 0x87           //if SYSCLK<1MHz

//测试地址

#define IAP_ADDRESS 0x0400

/*----------------------------

扇区擦除

----------------------------*/

void IapEraseSector(WORD addr)//擦除扇区是以512字节为单位

{

    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()

}

/*----------------------------

写一字节数据到ISP/IAP区域

----------------------------*/

void IapProgramByte(WORD addr, BYTE dat)

{

    IAP_CONTR = ENABLE_IAP         //使能IAP

    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()

}

/*----------------------------

从ISP/IAP/EEPROM区域读取一字节

----------------------------*/

BYTE IapReadByte(WORD addr)//由于在程序储存区内也可以用MOVC指令读取

{

    BYTE dat                       //数此丛据缓冲区

    IAP_CONTR = ENABLE_IAP         //使能IAP

    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                     //返回

}

/*----------------------------

关闭IAP

----------------------------*/

void IapIdle()

{

    IAP_CONTR = 0                  //关闭IAP功能

    IAP_CMD = 0                    //清除命令寄存器

    IAP_TRIG = 0                   //清除触发寄存器

    IAP_ADDRH = 0x80               //将地址设置到非IAP区域

    IAP_ADDRL = 0

}

通过以上代码即可对Flash区进行写入 *** 作

不用重新写,只需要在你原来的没有IAP的工程代码上加上一些东西。

最重要的一点就是凳蠢差向量表需要重新定位,使用相关枣皮函数即可,具体的你稍微搜索一下就能知道如何重新定义一个中断向量的偏移地址。

另外需要说明的是,根据我的经验,app里面不像网上说的那样,从IAP跳转到APP后,AAP第一句代码就是重新设置向量偏移,应该要先初始化系统时钟,再执行向量偏移的修改。

除了向量偏移修改这个必选项之外,档禅也可以自定义加一些代码和IAP配合,用来实现如何通过命令来使得APP运行程序时可以跳转到IAP,一般来说是按条件软件复位,以及要让IAP知道是跳转还是升级代码这一标志位如何传递等。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12543714.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存