打印

怎么写入int数据保存到STC EEPROM中,程序怎么改实现读写

[复制链接]
937|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
19943183944|  楼主 | 2020-4-29 14:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

//-----------------------------------------------

sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;

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控制寄存器

#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 0x0400

void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);

void main()
{
    WORD i;
    i=35632;
   
    P3M0 = 0x00;
    P3M1 = 0x00;

   IapProgramByte(i);    //i=35632;怎么读写入EEPROM
   IapReadByte(i);     //i=35632;怎么读写入EEPROM
    while (1);
}

/*----------------------------
软件延时
----------------------------*/
void Delay(BYTE n)
{
    WORD x;

    while (n--)
    {
        x = 0;
        while (++x);
    }
}

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

/*----------------------------
从ISP/IAP/EEPROM区域读取一字节
----------------------------*/
BYTE IapReadByte(WORD addr)
{
    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;                     //返回
}

/*----------------------------
写一字节数据到ISP/IAP/EEPROM区域
----------------------------*/
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();
}

/*----------------------------
扇区擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
    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();
}

使用特权

评论回复

相关帖子

沙发
ayb_ice| | 2020-4-29 14:44 | 只看该作者
本帖最后由 ayb_ice 于 2020-4-29 14:52 编辑

#define IAP_START_ADDR        (0x2000)
void IAP_Write(u16 usIapAddr, u8* pAddr, u8 ucNum);
void IAP_Read(u16 usIapAddr,u8* pAddr, u8 ucNum);

void Test(void)
{
        u16 i = 12345;
        u16 k;
        
        IAP_Write(IAP_START_ADDR, (u8*)&i, 2);
        k = 0;
        IAP_Read(IAP_START_ADDR, (u8*)&k, 2);
        
        if (i != k)
        {
                __nop();
                //error();
        }
}

使用特权

评论回复
板凳
19943183944|  楼主 | 2020-4-29 15:27 | 只看该作者
ayb_ice 发表于 2020-4-29 14:44
#define IAP_START_ADDR        (0x2000)
void IAP_Write(u16 usIapAddr, u8* pAddr, u8 ucNum);
void IAP_ ...

这程序怎么实现我还是看不明白

使用特权

评论回复
地板
ayb_ice| | 2020-4-29 15:39 | 只看该作者
19943183944 发表于 2020-4-29 15:27
这程序怎么实现我还是看不明白

就三个参数
第 一个是IAP的地址,就是变量想存在什么地方的地址
第二个是变量的首地址,可以是任意变量,包括结构体,
第三个就是数量,以字节为标准,一个整形就是是2个字节,一个浮点数是4个字节

具体实现与MCU有关,我没有去实现

使用特权

评论回复
5
jyzhzn| | 2020-4-30 15:17 | 只看该作者
本帖最后由 jyzhzn 于 2020-4-30 15:19 编辑
19943183944 发表于 2020-4-29 15:27
这程序怎么实现我还是看不明白

void Write_eep()                 //写入EEPROM                                                                           
{               
        unsigned char i,j;

        for(j=0;j<=1;j++)
        {
            for(i=0;i<=7;i++)
            {
                IAP_CONTR=0x83;//设置等待时间且允许对EEPROM进行操作
            IAP_CMD=0x02;//对EEPROM进行写操作
            IAP_ADDRL=i;//送入扇区地址的低8位
            IAP_ADDRH=j;//送入扇区地址的高8位
                        IAP_DATA=Automatic_Count[j];//将数据送至数据寄存器            
            IAP_TRIG=0x5A;//启动触发
            IAP_TRIG=0xA5;
                _nop_( );
            }
        }
}
这是我写的写入一个二维数组Automatic_Count[8][2],地址从0开始,你也可以在地址i和j上加一个偏移值,改到其它地址。

使用特权

评论回复
6
hwpga| | 2020-4-30 21:04 | 只看该作者
本帖最后由 hwpga 于 2020-4-30 21:18 编辑
jyzhzn 发表于 2020-4-30 15:17
void Write_eep()                 //写入EEPROM                                                       ...

你这个用for循环数据小还好说
数据量大基本没法用的

STC15W一个字节要写55US
1MS最多写18个字节
打个7折,1MS最多也就写12个字节差不多

STC8倒是快了不少,一个字节写7US
1MS最多写142个字节
打个7折,1MS最多也就写100字节差不多
一个10UF的电容,放个10来个MS的电是完全是没问题的
没必须要一次性写完






使用特权

评论回复
7
William1994| | 2020-5-2 09:33 | 只看该作者
hwpga 发表于 2020-4-30 21:04
你这个用for循环数据小还好说
数据量大基本没法用的

10uF倒是不小了,关键你的dying信号是什么时候给的。如果在10uF前的电感前,或者更前面取的还行。如果从10uF上比较出来的,还是要测试时间够不够。

Q1=C*3.1;  //3.3V正常工作,3.1V产生dying信号
Q2=C*2.9; //2.9V保存完
Q2-Q1=It ; //I只考虑单片机0.01A(不考虑其它电路用这个电),Q的单位是法拉第,
t = 10u*(3.3-3.1)/0.01 = 200us

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

42

帖子

0

粉丝