打印
[国产单片机]

STC11F32XE单片机的EEPROM的擦除问题

[复制链接]
2135|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
tiantian815|  楼主 | 2013-10-24 10:50 | 只看该作者
有没有哪位前辈遇到过类似的问题啊?求指导

使用特权

评论回复
板凳
tiantian815|  楼主 | 2013-10-24 10:51 | 只看该作者
我都被这个问题困扰好几天了,一直不知道错在哪了,完全没有头绪,还望遇到过类似问题的前辈们不吝指导

使用特权

评论回复
地板
tiantian815|  楼主 | 2013-10-24 12:53 | 只看该作者
怎么都没人回复呢?

使用特权

评论回复
5
autopccopy| | 2013-10-24 13:56 | 只看该作者
应该是程序问题,先检查,例如扇区首地址是否正确?
量产的芯片没问题的,请使用官方例程试试。

使用特权

评论回复
6
tiantian815|  楼主 | 2013-10-24 15:45 | 只看该作者
autopccopy 发表于 2013-10-24 13:56
应该是程序问题,先检查,例如扇区首地址是否正确?
量产的芯片没问题的,请使用官方例程试试。

就是按官方手册上的例程写的,读写都正常就是擦除有问题,只能擦除前两个地址的内容

使用特权

评论回复
7
逍遥派掌门| | 2013-10-26 23:23 | 只看该作者
估计和我以前碰到的问题一样。

操作的地址,是否定义成8位的了? 这个地址要定义为16位的。

使用特权

评论回复
8
McuPlayer| | 2013-10-27 10:09 | 只看该作者
换个芯片试下,STC单片机内部那不是真正的EE,那是Flash,寿命是10W次,测试的时候很容易超过。

使用特权

评论回复
评论
autopccopy 2013-10-28 13:43 回复TA
不可能。另:STC FLASH我实测平均大于60W次刷写。 
9
tiantian815|  楼主 | 2013-10-27 18:34 | 只看该作者
逍遥派掌门 发表于 2013-10-26 23:23
估计和我以前碰到的问题一样。

操作的地址,是否定义成8位的了? 这个地址要定义为16位的。 ...

地址是16位的呢,可是就是不能正常擦除

使用特权

评论回复
10
tiantian815|  楼主 | 2013-10-27 18:36 | 只看该作者
McuPlayer 发表于 2013-10-27 10:09
换个芯片试下,STC单片机内部那不是真正的EE,那是Flash,寿命是10W次,测试的时候很容易超过。 ...

这个应该不会超的吧,因为我也没存过多少数据,我换个单片机试试看吧

使用特权

评论回复
11
逍遥派掌门| | 2013-10-27 23:43 | 只看该作者
STC的flash操作很蛋疼,启动 flash的命令都有两种(不知道是否仅有两种),不注意就跨不过那道槛。

使用特权

评论回复
12
tiantian815|  楼主 | 2013-10-28 08:46 | 只看该作者
逍遥派掌门 发表于 2013-10-27 23:43
STC的flash操作很蛋疼,启动 flash的命令都有两种(不知道是否仅有两种),不注意就跨不过那道槛。 ...

到现在我还没找出问题出在哪了呢,还是不能正常擦除,完全没有头绪,不知道怎么修改

使用特权

评论回复
13
autopccopy| | 2013-10-28 13:44 | 只看该作者
逍遥派掌门 发表于 2013-10-27 23:43
STC的flash操作很蛋疼,启动 flash的命令都有两种(不知道是否仅有两种),不注意就跨不过那道槛。 ...

没那么复杂,看看数据表,使用官方例程即可一次成功。

使用特权

评论回复
14
autopccopy| | 2013-10-28 13:52 | 只看该作者
本帖最后由 autopccopy 于 2013-10-28 13:57 编辑
tiantian815 发表于 2013-10-28 08:46
到现在我还没找出问题出在哪了呢,还是不能正常擦除,完全没有头绪,不知道怎么修改 ...


首先,要相信经过量产的芯片不会有这么低级的BUG! :)
其次,要多看数据表,往往解决后才发现原来这么简单!
===================欢乐分割线==================
1、认真查看看数据手册的312页起的相关章节,然后用万用表检查单片机的供电是否大于4.1V, 否则会无效。
2、使用STC-ISP V6.59 的【范例程序】标签,导出STC11F的EEPROM程序(见下)认真看看,确保每句都知道是什么意思和作用。该程序使用了P1口连接的LED作为指示用,你也可以加上,就很直观了。

重新使用KEIL 建立工程,编译烧写,一定可以成功的(当然必要时需换另一片芯片试试,排除损坏的可能)。

官方C源程序:
/*------------------------------------------------------------------*/
/* --- STC MCU Limited ---------------------------------------------*/
/* --- STC10/11xx Series MCU ISP/IAP/EEPROM Demo -------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-755-82905966 ----------------------------------------*/
/* --- Tel: 86-755-82948412 ----------------------------------------*/
/* --- Web: www.**.com -----------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/

#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

/*Declare SFR associated with the IAP */
sfr IAP_DATA    =   0xC2;           //Flash data register
sfr IAP_ADDRH   =   0xC3;           //Flash address HIGH
sfr IAP_ADDRL   =   0xC4;           //Flash address LOW
sfr IAP_CMD     =   0xC5;           //Flash command register
sfr IAP_TRIG    =   0xC6;           //Flash command trigger
sfr IAP_CONTR   =   0xC7;           //Flash control register

/*Define ISP/IAP/EEPROM command*/
#define CMD_IDLE    0               //Stand-By
#define CMD_READ    1               //Byte-Read
#define CMD_PROGRAM 2               //Byte-Program
#define CMD_ERASE   3               //Sector-Erase

/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
//#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

//Start address for STC10/11xx EEPROM
#define IAP_ADDRESS 0x0000

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

void main()
{
    WORD i;

    P1 = 0xfe;                      //1111,1110 System Reset OK
    Delay(10);                      //Delay
    IapEraseSector(IAP_ADDRESS);    //Erase current sector
    for (i=0; i<512; i++)           //Check whether all sector data is FF
    {
        if (IapReadByte(IAP_ADDRESS+i) != 0xff)
            goto Error;             //If error, break
    }
    P1 = 0xfc;                      //1111,1100 Erase successful
    Delay(10);                      //Delay
    for (i=0; i<512; i++)           //Program 512 bytes data into data flash
    {
        IapProgramByte(IAP_ADDRESS+i, (BYTE)i);
    }
    P1 = 0xf8;                      //1111,1000 Program successful
    Delay(10);                      //Delay
    for (i=0; i<512; i++)           //Verify 512 bytes data
    {
        if (IapReadByte(IAP_ADDRESS+i) != (BYTE)i)
            goto Error;             //If error, break
    }
    P1 = 0xf0;                      //1111,0000 Verify successful
    while (1);
Error:
    P1 &= 0x7f;                     //0xxx,xxxx IAP operation fail
    while (1);
}

/*----------------------------
Software delay function
----------------------------*/
void Delay(BYTE n)
{
    WORD x;

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

/*----------------------------
Disable ISP/IAP/EEPROM function
Make MCU in a safe state
----------------------------*/
void IapIdle()
{
    IAP_CONTR = 0;                  //Close IAP function
    IAP_CMD = 0;                    //Clear command to standby
    IAP_TRIG = 0;                   //Clear trigger register
    IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
    IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
}

/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
BYTE IapReadByte(WORD addr)
{
    BYTE dat;                       //Data buffer

    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
    IapIdle();                      //Close ISP/IAP/EEPROM function

    return dat;                     //Return Flash data
}

/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
       dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    IapIdle();
}

/*----------------------------
Erase one sector area
Input: addr (ISP/IAP/EEPROM address)
Output:-
----------------------------*/
void IapEraseSector(WORD addr)
{
    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    IapIdle();
}

--------------------------------------------------
BTW: STC单片机的FLASH 官方保证10W次刷写,我使用程序破坏性实际测试过多个芯片,日常环境下基本都有60W次刷写才出现有字节的某位由0变不回1。

(92)

stc-eeprom1.jpg (120.79 KB )

stc-eeprom1.jpg

使用特权

评论回复
15
逍遥派掌门| | 2013-10-28 14:12 | 只看该作者
注意擦除指令发出后,要延时等待一段时间后,再进行读写操作。

使用特权

评论回复
16
逍遥派掌门| | 2013-10-28 14:53 | 只看该作者
最好是每种型号的芯片手册认真核对,不要轻易移植代码,我中过的招:



和14楼的对比一下。

使用特权

评论回复
评论
autopccopy 2013-10-28 19:12 回复TA
当然,每个系列都有异同,包括内核、头文件(寄存器定义)等,否则就没必要搞这么多系列了。一定要区别对待,认真看数据手册,这样就入门了! :) 
17
autopccopy| | 2013-10-28 19:17 | 只看该作者
本帖最后由 autopccopy 于 2013-10-28 19:18 编辑
逍遥派掌门 发表于 2013-10-28 14:53
最好是每种型号的芯片手册认真核对,不要轻易移植代码,我中过的招:


当然,每个系列都有异同,包括内核、头文件(寄存器定义)等,否则就没必要搞这么多系列了。一定要区别对待,认真看数据手册,这样就入门了! :)

STC的官方例程是分开不同系列的,不能张冠李戴哦。
(btw: 数据手册的例程不能复制出来,可使用STC-ISP V6.XX的【范例程序】标签导出, 例如STC15F系列有85个官方C例程,在线阅读:http://www.stcisp.com/stcisp-demo-code.html )

希望LZ能解决这个问题。我听说过一个“高手”说是FOXCON的,死活搞不定STC的ISP下载,后来“炒”老板鱿鱼,自助创业,不过我看很悬。:)

使用特权

评论回复
18
tiantian815|  楼主 | 2013-10-29 08:58 | 只看该作者
autopccopy 发表于 2013-10-28 19:17
当然,每个系列都有异同,包括内核、头文件(寄存器定义)等,否则就没必要搞这么多系列了。一定要区别对 ...

谢谢,刚开始用单片机,好多还不是很了解,你们说的建议都很用,我再好好研究研究

使用特权

评论回复
19
tiantian815|  楼主 | 2013-10-29 09:00 | 只看该作者
逍遥派掌门 发表于 2013-10-28 14:53
最好是每种型号的芯片手册认真核对,不要轻易移植代码,我中过的招:

程序之前已经加上延时了,我再好好看看手册,可能是某些细节的东西理解的太不够透彻了呢

使用特权

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

本版积分规则

1

主题

12

帖子

0

粉丝