STC8A8K64D4 使用EEPROM

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

}

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STC8单片机读写内部EEPROM KEIL工程文件源码: /* STC8 内部EEPROM测试 从手册717页上可以看出 STC8的 EEPROM空间为1k 地址在0000h-03ffh 地址也是1024的大小 次程序结合手册 编写 大同小异 程序的主要目的是 先清楚地址0 到512 (一个扇区)的数据 然后读取 清楚扇区的数据 如果清楚成功 则读到的数据都为0xff 然后在向里写入 1-ff 1-ff 512个这样的字节 然后在读里面的字节 判断是否和写入的一样 整个过程都是通过串口在不停的上传给电脑 重点强调 更新数据一定是要先擦除整个扇区 才能更新 这是和外部E2的比较大的区别 但是和flash的写法差不多 要求 下载时 STC8 内部晶振为11.0592 电脑打开串口的波特率为9600 */ #include "stc8.h" #define u8 unsigned char #define u16 unsigned int #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节读命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP字节擦除命令 #define ENABLE_IAP 0X82 //if SYSCLK<20MHz //测试地址 #define IAP_ADDRESS 0X0000 //从手册上可以看出 STC15F2K60S2的EEPROM地址是0x0000- 0x03ff 正好是1k的地址空间 sbit led=P5^5; //P3.5口LED灯定义 //延时函数 void delay(u8 n) { while(n--); } //关闭IAP void IapIdle() { IAP_CONTR=0; //关闭IAP功能 IAP_CMD =0; //清除命令寄存器 IAP_TRIG =0; //清楚触发寄存器 IAP_ADDRH=0X80; //将地址设置到非IAP区域 IAP_ADDRL=0; } //从ISP/IAP/EEPROM区域读取一个字节 u8 IapReadByte(u16 addr) { u8 dat; //数据缓冲区 IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_READ; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 dat=IAP_DATA; //读ISP/IAP/EEPROM数据 IapIdle(); //关闭IAP功能 return dat; //返回 } //写一个字节数据到ISP/IAP/EEPROM区域 void IapProgramByte(u16 addr,u8 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) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 IapIdle(); //关闭IAP功能 } //扇区擦除 void IapEraseSector(u16 addr) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_ERASE; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDR

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值