X57187422 发表于 2012-4-27 07:33:52

STC12C5A60S2单片机如何使用EEPROM

本人新手,求教各位大侠,STC12C5A60S2单片机如何使用EEPROM。我看了说明书没看明白。最好能有段程序,和说明,

liudaolunhui 发表于 2012-4-27 07:36:41

去网上自己找数据手册!!!!!!!!!!!!

X57187422 发表于 2012-4-27 07:39:37

liudaolunhui 发表于 2012-4-27 07:36 static/image/common/back.gif
去网上自己找数据手册!!!!!!!!!!!!

我手里有数据手册 可是我看不明白, 不知道到程序中应该如何写出这些东西

X57187422 发表于 2012-4-27 07:45:43

liudaolunhui 发表于 2012-4-27 07:36 static/image/common/back.gif
去网上自己找数据手册!!!!!!!!!!!!

我是用C语言编程的,我上传了一下说明书的一部分,那一段我应该怎么加!我不知道应该怎么写进去。。。。

gmliwei7208 发表于 2012-4-27 08:07:39

伙计你敢在这个论他发关于STC的帖子,胆子挺肥的啊

bg6ixm 发表于 2012-4-27 08:14:06

X57187422 发表于 2012-4-27 07:45 static/image/common/back.gif
我是用C语言编程的,我上传了一下说明书的一部分,那一段我应该怎么加!我不知道应该怎么写进去。。。。 ...

你找错地方了,找C例程那一段。

ahuang227 发表于 2012-4-27 08:17:34

现在的学生是越来越懒了,都是让人喂着吃。

难道这就是富二代的象征?

asdf1776 发表于 2012-4-27 09:45:53

在datasheet里放例程,STC已经很够意思了,就这还找不到?

bg6ixm 发表于 2012-4-27 09:48:04

这相当于考试作弊找不到哪个是答案。

tcw_xny 发表于 2012-4-27 09:49:20

/****************************************************/
void Write_OneByte(unsigned char addr_h,unsigned char addr_l,unsigned char thedata)
{
        IAP_DATA=thedata;                        //起始地址高八位
        IAP_ADDRH=addr_h;                         //起始地址低八位
        IAP_ADDRL=addr_l;
        IAP_CMD=0x02;
        IAP_CONTR=0x88;
        IAP_TRIG=0x5A;
        IAP_TRIG=0xA5;
        delayus(5);
}
/****************************************************/
unsigned char Read_OneByte(unsigned char addr_h,unsigned char addr_l)
{
        IAP_ADDRH=addr_h;       
        IAP_ADDRL=addr_l;
        IAP_CMD=0x01;
        IAP_CONTR=0x80;
        IAP_TRIG=0x5A;
        IAP_TRIG=0xA5;
        return(IAP_DATA);
}
/****************************************************/
void Erase_all()
{
        unsigned char i;
        for(i=0;i<2;i++)
        {
        Erase_OneSector(0x00,0);       
        Erase_OneSector(0x02,0);
        Erase_OneSector(0x04,0);
        Erase_OneSector(0x06,0);

        Erase_OneSector(0x08,0);
        Erase_OneSector(0x0a,0);
        Erase_OneSector(0x0c,0);
        Erase_OneSector(0x0e,0);

        Erase_OneSector(0x10,0);
        Erase_OneSector(0x12,0);
        Erase_OneSector(0x14,0);
        Erase_OneSector(0x16,0);

        Erase_OneSector(0x18,0);
        Erase_OneSector(0x1a,0);
        Erase_OneSector(0x1c,0);
        Erase_OneSector(0x1e,0);

        Erase_OneSector(0x20,0);
        Erase_OneSector(0x22,0);
        Erase_OneSector(0x24,0);
        Erase_OneSector(0x26,0);

        Erase_OneSector(0x28,0);
        Erase_OneSector(0x2a,0);
        Erase_OneSector(0x2c,0);
        Erase_OneSector(0x2e,0);

        Erase_OneSector(0x30,0);
        Erase_OneSector(0x32,0);
        Erase_OneSector(0x34,0);
        Erase_OneSector(0x36,0);

        Erase_OneSector(0x38,0);
        Erase_OneSector(0x3a,0);
        Erase_OneSector(0x3c,0);
        Erase_OneSector(0x3e,0);

        Erase_OneSector(0x40,0);
        Erase_OneSector(0x42,0);
        Erase_OneSector(0x44,0);
        Erase_OneSector(0x46,0);

        Erase_OneSector(0x48,0);
        Erase_OneSector(0x4a,0);
        Erase_OneSector(0x4c,0);
        Erase_OneSector(0x4e,0);
        delayms(2);
        }
}
/****************************************************/
void Erase_OneSector(unsigned char addr_h,unsigned char addr_l)
{
        IAP_ADDRH=addr_h;
        IAP_ADDRL=addr_l;
        IAP_CMD=0x03;
        IAP_CONTR=0x80;
        IAP_TRIG=0x5A;
        IAP_TRIG=0xA5;
}

BXAK 发表于 2012-4-27 09:49:41

结合手册的C例程看(例程中也有相应注释)

jackielau 发表于 2012-4-27 11:09:44

有个疑问,擦出一个扇区需要大约21mS,在擦出的这段时间,cpu还在运行吗??

X57187422 发表于 2012-4-27 11:16:07

gmliwei7208 发表于 2012-4-27 08:07 static/image/common/back.gif
伙计你敢在这个论他发关于STC的帖子,胆子挺肥的啊

啊 这个不让发STC的?
我不知道。。

X57187422 发表于 2012-4-27 11:19:12

ahuang227 发表于 2012-4-27 08:17 static/image/common/back.gif
现在的学生是越来越懒了,都是让人喂着吃。

难道这就是富二代的象征?

不是的。。。。我是车辆专业的学生。。。不是学这个的但我做东西需要这个知识 可是现在学习已经来不及了。。。。看自己需要的部分看不懂。。看初级的需要的时间又太多。。而且看不到想要的。。。

BXAK 发表于 2012-4-27 13:46:23

jackielau 发表于 2012-4-27 11:09 static/image/common/back.gif
有个疑问,擦出一个扇区需要大约21mS,在擦出的这段时间,cpu还在运行吗?? ...

STC的“EEPROM”在擦除扇区区间,cpu就耗在那里了啥也不干

jackielau 发表于 2012-4-27 14:47:53

BXAK 发表于 2012-4-27 13:46 static/image/common/back.gif
STC的“EEPROM”在擦除扇区区间,cpu就耗在那里了啥也不干

就是说CPU停止工作了?

wangshaosh123 发表于 2012-4-27 15:15:55

jackielau 发表于 2012-4-27 14:47 static/image/common/back.gif
就是说CPU停止工作了?

CPU在EEROM擦除期间可以干其他事,不过有必要么?
一般都是擦除之后要写入的EEPROM的所以都是在等

BXAK 发表于 2012-4-27 16:28:25

jackielau 发表于 2012-4-27 14:47 static/image/common/back.gif
就是说CPU停止工作了?

停止工作21ms

BXAK 发表于 2012-4-27 16:34:40

wangshaosh123 发表于 2012-4-27 15:15 static/image/common/back.gif
CPU在EEROM擦除期间可以干其他事,不过有必要么?
一般都是擦除之后要写入的EEPROM的所以都是在等 ...

STC的片内“ EEPROM ” 是利用ISP/IAP技术将内部Data Flash当EEPROM,擦除扇区时就会干耗着由不得人为改变

taishandadi 发表于 2012-4-27 18:41:46

没办法,这段时间cpu啥也干不了

farrtone 发表于 2012-4-27 20:04:30

去宏晶科技官网找找,有例子。

lxa0 发表于 2012-4-27 20:10:36

先把你想使用的EEPROM数据手册找到
然后搞懂原理

hongjie0216 发表于 2012-4-27 20:15:20

#include<STC8051.h>
#include <intrins.H>
/*--------------------------------------------------------------*/
typedef    unsigned char   INT8U;
typedef    unsigned int    INT16U;

/*--------------------------------------------------------------*/
//sfr IAP_DATA    = 0xC2;
//sfr IAP_ADDRH   = 0xC3;
//sfr IAP_ADDRL   = 0xC4;
//sfr IAP_CMD   = 0xC5;
//sfr IAP_TRIG    = 0xC6;
//sfr IAP_CONTR   = 0xC7;
/*--------------------------------------------------------------*/
//定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数
//#define ENABLE_ISP 0x80 //系统工作时钟<30MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x81 //系统工作时钟<24MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
#define ENABLE_ISP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x85 //系统工作时钟<3MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x86 //系统工作时钟<2MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_ISP 0x87 //系统工作时钟<1MHz 时,对IAP_CONTR 寄存器设置此值
/*-----------------------------------------------------------------------------*/

union union_temp16
{
    INT16U un_temp16;
    INT8Uun_temp8;

}my_unTemp16;

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

/*---读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节---*/

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

void IAP_Disable();
INT8U Byte_Read(INT16U add);
void Byte_Program(INT16U add, INT8U ch);
void Sector_Erase(INT16U add);
/*-----------------------------------------------------------------------------*/
INT8U Byte_Read(INT16U add)
{
    IAP_DATA = 0x00;
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x01;               //IAP/ISP/EEPROM 字节读命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8;    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8;    //设置目标单元地址的低8 位地址

    //EA = 0;
    IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                  //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
/*-----------------------------------------------------------------------------*/

/*字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据*/

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

void Byte_Program(INT16U add, INT8U ch)
{
    IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x02;               //IAP/ISP/EEPROM 字节编程命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8;    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8;    //设置目标单元地址的低8 位地址

    IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
    //EA = 0;
    IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                  //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*-----------------------------------------------------------------------------*/

/*----------------------擦除扇区, 入口:DPTR = 扇区地址-------------------------*/

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

void Sector_Erase(INT16U add)
{
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x03;               //IAP/ISP/EEPROM 扇区擦除命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8;    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8;    //设置目标单元地址的低8 位地址

    //EA = 0;
    IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                  //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}

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

void IAP_Disable()
{
    //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    IAP_CONTR = 0;      //关闭IAP 功能
    IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    IAP_TRIG= 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
    IAP_ADDRH = 0;
    IAP_ADDRL = 0;
}

hongjie0216 发表于 2012-4-27 20:15:52

这段程序都用了好几年了 好几个项目用到

hongjie0216 发表于 2012-4-27 20:17:21

unsigned char xdata tab_flash;
void Write(unsigned char dat,unsigned int Adrr)
{
        unsigned int i;

        //Sector_Erase(0x0000);                                  /*0000h---1ffh暂存*/

        for(i=0;i<512;i++)
        {
       
             //Byte_Program(i, Byte_Read(i+Adrr+0x0200));   /*把存储区数据导到暂存*/

                // Byte_Program(i, Byte_Read((i+(unsigned int)(Adrr/512)*512)+0x0200));   /*把存储区数据导到暂存*/
               tab_flash= Byte_Read((i+(unsigned int)(Adrr/512)*512)+0x0200);

        }

        Sector_Erase((unsigned int)(Adrr/512)*512+0x0200);

        for(i=0;i<512;i++)
        {
                                                                  
          if((unsigned int)(Adrr%512)!=i)
                   {
                           //Byte_Program( (i+(unsigned int)(Adrr/512)*512+0x0200),Byte_Read(i));/*把暂存数据导到存储*/
                           Byte_Program( (i+(unsigned int)(Adrr/512)*512+0x0200),tab_flash);
                   }
                  else
                   {
                  Byte_Program(Adrr+0x0200,dat);
                   }


        }

}

/*--------------------------------------------------------------*/
INT8U read(unsigned int Adrr)
{
                   unsigned char dat;


                   dat=Byte_Read(Adrr+0x0200);

                   return dat;

}
这个是应用

hongjie0216 发表于 2012-4-27 20:18:58

把C文件打包传上来了

format 发表于 2012-4-27 20:19:11

唉,不知道是水平高了,还是玩ARM再回头看这些

很儿科,恰巧最近也在玩

就说说感想

AD的看似很多,但是不能修改参考电压

俩个PWM很鸡肋,由于定时器的限制

无法弄出3个~~~~

还有这个EEPROM,基本和没有没啥区别~~~~

不过倒是可以记录一段,定时刷新

每个寄存器写的都很明白

不想玩ARM的时候,弄个AD,弄个PWM得配置1天~~~~



jun66 发表于 2012-5-16 15:31:35

hongjie0216 发表于 2012-4-27 20:15 static/image/common/back.gif
这段程序都用了好几年了 好几个项目用到

兄弟 问下 你都用了好几年 它的稳定性怎么样呢?我也在做一个小项目 保存的东西需要经常改经常用 所以想了解下 你用后出现什么不良症状没 STC好多人都信不过 不过我是一直在使用

hongjie0216 发表于 2012-5-16 17:25:07

jun66 发表于 2012-5-16 15:31 static/image/common/back.gif
兄弟 问下 你都用了好几年 它的稳定性怎么样呢?我也在做一个小项目 保存的东西需要经常改经常用 所以想 ...

用的还可以没有发现太脆弱的地方!就是他的数据手册和技术支持太烂

ym7205 发表于 2012-6-13 08:02:24

学习了,,,谢谢

yl604922959 发表于 2012-6-13 08:36:48

有时候这个东西还是挺好用的

wzhscj 发表于 2013-1-31 13:17:09

学习学习。

fhy-123 发表于 2013-4-13 10:22:25

大哥,我想再也想学这个呢,不过数据手册有点难看啊

bbssilverkey 发表于 2013-4-13 17:11:05

BXAK 发表于 2012-4-27 13:46 static/image/common/back.gif
STC的“EEPROM”在擦除扇区区间,cpu就耗在那里了啥也不干

建议少用他内置的EEPROM,不太稳,程序运行的场合太多不可预料的地方,会变0xff的

bingshuihuo888 发表于 2019-1-18 08:48:32

很多时候我都不知道这个到底怎么用

bingshuihuo888 发表于 2019-2-27 09:12:05

这个东西还是挺好用的
页: [1]
查看完整版本: STC12C5A60S2单片机如何使用EEPROM