EEPROM.C
#include "EEPROM.h"
volatile INT8U cnt = 0; //存储PCA计时溢出次数
volatile INT32U count0 = 0; //记录上一次的捕获值
volatile INT32U count1 = 0; //记录本次的捕获值
volatile INT32U length = 0; //存储信号的时间长度
/**************************************************************************
* 描 述 : 禁止访问ISP/IAP
* 入 参 : 无
* 返回值 : 无
*************************************************************************/
void Disable_EEPROM(void)
{
IAP_CONTR = 0x00; //对ISP/IAP控制寄存器赋值,IAPEN位为0,禁止ISP/IAP操作
IAP_CMD = 0x00; //清零ISP/IAP命令寄存器各位,去除ISP/IAP命令
IAP_TRIG = 0x00; //清零ISP/IAP命令触发寄存器各位,防止ISP/IAP命令误触发
IAP_ADDRH = 0x80; //ISP/IAP地址寄存器高8位赋值
IAP_ADDRL = 0x00; //ISP/IAP地址寄存器低8位赋值,指向非EEPROM区,防止误操作
}
/***************************************************************************
* 描 述 : 从指定EEPROM首地址读出n个字节放指定的缓冲
* 入 参 : EE_address: 读出EEPROM的首地址
DataAddress: 读出数据放缓冲的首地址
number: 读出的字节长度
* 返回值 : 无
**************************************************************************/
void EEPROM_read_n(uint16 EE_address,uint8 *DataAddress,uint16 number)
{
EA = 0; //禁止总中断
IAP_CONTR |= 0x80; //IAPEN位置0,允许ISP/IAP操作
IAP_CONTR |= 0x03; //WT0和WT1位置1,用于设置CPU等待时间
IAP_CONTR &= 0xFB; //WT2位置0,用于设置CPU等待时间
IAP_TPS = 11; //由系统时钟决定
IAP_CMD = 0x01; //MS0位置1,MS1位置0,对ISP/IAP进行字节读操作
do
{
IAP_ADDRH = EE_address / 256; //ISP/IAP地址寄存器高8位赋值
IAP_ADDRL = EE_address % 256; //ISP/IAP地址寄存器低8位赋值
IAP_TRIG = 0x5A; //ISP/IAP命令触发寄赋值为5AH
IAP_TRIG = 0xA5; //ISP/IAP命令触发寄赋值为A5H
_nop_(); //空命令
*DataAddress = IAP_DATA; //读出ISP/IAP数据寄存器的值送往指定缓存
EE_address++;
DataAddress++;
}while(--number);
Disable_EEPROM(); //禁止访问ISP/IAP
EA = 1; //开启总中断
}
/***************************************************************************
* 描 述 : 把指定地址的EEPROM扇区擦除
* 入 参 : EE_address: 读出EEPROM的首地址
DataAddress: 读出数据放缓冲的首地址.
number: 读出的字节长度.
* 返回值 : 无
**************************************************************************/
void EEPROM_SectorErase(uint16 EE_address)
{
EA = 0; //禁止总中断
IAP_ADDRH = EE_address / 256; //ISP/IAP地址寄存器高8位赋值
IAP_ADDRL = EE_address % 256; //ISP/IAP地址寄存器低8位赋值
IAP_CONTR |= 0x80; //IAPEN位置0,允许ISP/IAP操作
IAP_CONTR |= 0x03; //WT0和WT1位置1,用于设置CPU等待时间
IAP_CONTR &= 0xFB; //WT2位置0,用于设置CPU等待时间
IAP_TPS = 11; //由系统时钟决定
IAP_CMD = 0x03; //MS0位置1,MS1位置1,对ISP/IAP进行扇区擦除操作
IAP_TRIG = 0x5A; //ISP/IAP命令触发寄赋值为5AH
IAP_TRIG = 0xA5; //ISP/IAP命令触发寄赋值为A5H
_nop_(); //空命令
Disable_EEPROM(); //禁止访问ISP/IAP
EA = 1; //重新允许中断
}
/***************************************************************************
* 描 述 : 从指定EEPROM首地址读出n个字节放指定的缓冲
* 入 参 : EE_address: 写入EEPROM的首地址
DataAddress: 写入源数据的缓冲的首地址
number: 写入的字节长度
* 返回值 : 无
**************************************************************************/
void EEPROM_write_n(uint16 EE_address,uint8 *DataAddress,uint16 number)
{
EA = 0; //禁止总中断
IAP_CONTR |= 0x80; //IAPEN位置0,允许ISP/IAP操作
IAP_CONTR |= 0x03; //WT0和WT1位置1,用于设置CPU等待时间
IAP_CONTR &= 0xFB; //WT2位置0,用于设置CPU等待时间
IAP_TPS = 11; //由系统时钟决定
IAP_CMD = 0x02; //MS0位置0,MS1位置1,对ISP/IAP进行字节写操作
do
{
IAP_ADDRH = EE_address / 256; //ISP/IAP地址寄存器高8位赋值
IAP_ADDRL = EE_address % 256; //ISP/IAP地址寄存器低8位赋值
IAP_DATA = *DataAddress; //将指定缓存数据送往ISP/IAP数据寄存器
IAP_TRIG = 0x5A; //ISP/IAP命令触发寄赋值为5AH
IAP_TRIG = 0xA5; //ISP/IAP命令触发寄赋值为A5H
_nop_(); //空命令
EE_address++;
DataAddress++;
}while(--number);
Disable_EEPROM(); //禁止访问ISP/IAP
EA = 1; //开启总中断
}
EEPROM.H程序
#ifndef _EEPROM_H_
#define _EEPROM_H_
#include "config.h"
#define uint32 unsigned long
#define uint16 unsigned int
#define uint8 unsigned char
extern void EEPROM_read_n(uint16 EE_address,uint8 *DataAddress,uint16 number);
extern void EEPROM_SectorErase(uint16 EE_address);
extern void EEPROM_write_n(uint16 EE_address,uint8 *DataAddress,uint16 number);
#endif
.c
#include "User_Save.h"
#include "config.h"
SaveSTR save;
#define PARM_SAVE_SECTOR 0 //参数存储的扇区 2022.07.04改为从第9个扇区开始存数据
#define PARM_SAVE_ADDR PARM_SAVE_SECTOR*512 //参数存储区的首地址
/* 从EEPROM读取配置参数 */
void parmConf_read(void)
{
EEPROM_read_n(PARM_SAVE_ADDR,(u8*)&save,sizeof(save));
}
/*写配置参数到EEPROM*/
void parmConf_write(void)
{
EEPROM_SectorErase(PARM_SAVE_SECTOR);
EEPROM_write_n(PARM_SAVE_ADDR,(u8*)&save,sizeof(save));
}
/*参数配置为出厂预设值*/
void parmConf_default(void)
{
save.initFlg = PARM_INIT_FLAG;
/* 初始化数据*/
parmConf_write();
}
/*参数配置初始化*/
void parmConf_Init(void)
{
parmConf_read();
if(save.initFlg != PARM_INIT_FLAG)
{
parmConf_default(); //起始标志不符合,恢复默认配置。
}
}
.h
#ifndef _USER_SAVE_H_
#define _USER_SAVE_H_
#include "config.h"
#define PARM_INIT_FLAG (0x5A) //参数初始数据标志
struct _SaveSTR
{
//↑↑参数↑↑
u8 initFlg;
};
typedef struct _SaveSTR SaveSTR;
extern SaveSTR save;
void saveData_Init(void);
void saveData_Default(void);
void saveData_Read(void);
void saveData_Write(void);
#endif
void main(void)
{
delay_ms(10);
//XTIpll_Init();//外部晶振
parmConf_Init(); //初始化flash
}