打印
[STM8]

STM8的FLASH相当于EEPROM,可单字节写入不需要擦除

[复制链接]
26674|37
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
stm8s103|  楼主 | 2010-6-23 17:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 stm8s103 于 2010-6-24 12:07 编辑

STM8的FLASH相当于EEPROM,可单字节写入不需要擦除
沙发
winloop| | 2010-6-23 19:12 | 只看该作者
楼主这么着迷于STM8?

使用特权

评论回复
板凳
xsgy123| | 2010-6-23 21:29 | 只看该作者
本身性能也挺好嘛

使用特权

评论回复
地板
mcuisp| | 2010-6-23 22:11 | 只看该作者
是呀,用起来最爽的MCU 内置FLASH。

使用特权

评论回复
5
ShakaLeo| | 2010-6-23 22:18 | 只看该作者
内部的操作应该也是以块为单位的,就像24CXX系列的E2PROM, 虽然可以单字节写入,但内部也是基于块/页操作的。

使用特权

评论回复
6
hsbjb| | 2010-6-24 08:53 | 只看该作者
FLASH应该都是以快为单位进行操作的

使用特权

评论回复
7
pkat| | 2010-6-24 09:02 | 只看该作者
莫非可以单字节擦除,不会吧

使用特权

评论回复
8
stm8s103|  楼主 | 2010-6-24 09:31 | 只看该作者
程序里面不需要擦除。

擦除也是写0,和直接写0没区别。

使用特权

评论回复
9
zcxhe| | 2010-6-24 09:47 | 只看该作者
擦除是写1吧?FLASH写操作时只能把1变成0,只有擦除操作可以内容变为0XFF,比如原来的值是如果是0XF5,那么你写入0X55,结果是对的,但如果写入的是0XAA,那么结果就是0X00了!

使用特权

评论回复
10
stm8s103|  楼主 | 2010-6-24 09:52 | 只看该作者
本帖最后由 stm8s103 于 2010-6-24 09:55 编辑

楼上先在STM8上试验。

使用特权

评论回复
11
mcu5i51| | 2010-6-24 10:59 | 只看该作者
STM8 擦除好像是写0

使用特权

评论回复
12
xuyiyi| | 2010-6-24 11:57 | 只看该作者
STM8S 的FLASH这么强大?
先擦除写0,再写入0xaa,校正结果是对的,接着再写入0x55,校正结果也是对的,是否可证明单字节支持擦除??

使用特权

评论回复
13
stm8s103|  楼主 | 2010-6-24 12:03 | 只看该作者
从软件上来看,貌似STM8 FLASH只有写, 没有擦除。
所谓的擦除就是写0。

使用特权

评论回复
14
xuyiyi| | 2010-6-24 12:23 | 只看该作者
欧耶!
STM8的FLASH太强大了!
相当于EEPROM,可单字节写入而不需要擦除!

使用特权

评论回复
15
IJK| | 2010-6-24 16:29 | 只看该作者
STM8的FLASH确实很强,另外它的EEPROM也很好,可以擦写300k次以上

使用特权

评论回复
16
sinadz| | 2010-6-24 21:11 | 只看该作者
是的,用起来确实很不错的

使用特权

评论回复
17
yybj| | 2010-6-24 21:14 | 只看该作者
单字节写,速度会不会慢了点

使用特权

评论回复
18
IJK| | 2010-6-25 09:12 | 只看该作者
单字节写,速度会不会慢了点
yybj 发表于 2010-6-24 21:14


STM8的EEPROM,单字节写速度跟单独的EEPROM差不多吧。谁来印证一下?

使用特权

评论回复
19
hqgboy| | 2010-6-25 10:34 | 只看该作者
STM8的FLASH相当于EEPROM,可单字节写入不需要擦除
stm8s103 发表于 2010-6-23 17:49



如果保证STM8的速度呢?

使用特权

评论回复
20
zcxhe| | 2010-6-25 18:58 | 只看该作者
本帖最后由 zcxhe 于 2010-6-26 10:20 编辑

stm8s103有没有试过块操作?今天试了好久都不行!单字节跟字写可能,块操作不行!
仔细看了资料,STM8的FLASH擦除确实是写0:
“要擦除一个字节,向对应的字节简单写入’0x00’即可。”
但实际上还是存在擦除操作,:
“自动快速字节编程

根据目标地址的初始化内容的不同,编程持续时间可能也有所不同。如果字(4个字节)中包含不 为空的字节,在编程前整个字会被自动擦除。相反,如果字为空,由于不会执行擦除操作从而 编程时间变短(请参考tPROG参数,在数据手册的”Flash program memory”表中)。
然而,可以通过对FLASH_CR1中的FIX位置1来强迫执行系统擦除操作而不管其内容是否为 空,从而使编程时间固定(请参考FLASH控制寄存器)。编程总时间随之被规定为擦除时间和写 操作时间的和(请参考tPROG参数,在数据手册的”Flash program memory”表中)。
注意:为了快速写一个字节(没有擦除操作),将要被写入数据的整个字(4个字节)必须被预先擦除。因此不 可能对同一个字做连续两次快速写操作(在第二次写之前没有擦除操作):第一次写字节操作将是 快速操作但针对另外一个字节的第二次写操作将需要一个擦除操作。”


标准块写也有自动擦除作动!只有快速块写没有!注意这段话:
“一共有三种可能的块操作:
● 块编程(也叫标准块编程):整个块在编程前被自动擦除。
● 快速块编程:在编程前没有预先的块擦除操作。
● 块擦除。 在块编程时,中断被硬件自动屏蔽。
标准块编程 块编程操作允许一次对整个块进行编程,整个块在编程前被自动擦除。 为了对整个块编程,FLASH_CR2和FLASH_NCR2中的PRG/NPRG位必须预先置位/清零来使
能标准块编程(请参考4.9.2 FLASH控制寄存器2(FLASH_CR2)和4.9.3 FLASH互补控制寄存器
2(FLASH_NCR2))。然后需要向主程序存储器或DATA区域的目标地址依次写入要编程的数据,
这样数据会被锁存在内部缓存中。为编程整个块,块中的所有字节都需要被写入数据。但要注意,所有被写入缓存的数据必须位于同一个块中,这意味着这些数据必须有同样的高位地址:仅仅低6位的地址可以不一样。当目标块的最后一个字节被装载到缓存后,编程就自动开始了。编程前首先会自动执行一次擦除操作。


验证的关键在快速块编程这里:

“快速块编程

快速块编程允许不擦除存储器内容就对块进行编程,因此快速块编程的编程速度是标准块编程 的两倍。该模式仅用于被编程部分已经被擦除过的情况,同时这种模式对向空白部分写入完整的应用代码特别有用,因为这种模式可以节省相当可观的时间。
快速块编 程的步骤 和标准 块 编程的步 骤大致一 样, FLASH_CR2 和 FLASH_NCR2 中的
FPRG/NFPRG 位必须预先置位 / 清 零来使能快 速块编程 ( 请参考 4.9.2  FLASH 控制寄存器
2(FLASH_CR2)和4.9.3 FLASH互补控制寄存器2(FLASH_NCR2))。
FLASH_IAPSR中的EOP与WR_PG_DIS控制位和FLASH中断相配合,可用于检查快速块编程 操作是否被正确执行完毕。

以下这句话最关键:
警告:在执行快速块编程之前如果这个块不是空的话,不能保证写入的数据无误。”


不过我现在的程序对块操作执行不了,不知道那里不对!
针对目前已经测试的字节与字操作,STM8的FLASH确实已经可以当EEPROM用了!有点怀疑这FLASH是否是EEPROM装的?当然要用快速块编程来测试!如果确实是FLASH的,那么它事实上最小的页就该是四个字节,而不是64字节,推测写字节的时候芯片内部是先把四个字节的数据读出到内部缓冲器修改数据,然后执行擦除操作,最后再写回去!



/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/

#include "cst_h\STM8S103F3P.h" //寄存器定义

volatile unsigned char tmp1 @0x9700;
volatile unsigned char tmp2 @0x9701;

volatile unsigned char tmp3[4] @0x9700;

volatile unsigned char tmp4[64] @0x9700;


#define         FLASHMASS1     0x56
#define         FLASHMASS2     0xAE

void subpr_flash_enable_write(void)
{
    IWDG_KR = 0xAA;
    FLASH_PUKR = FLASHMASS1; //锁1密钥
    FLASH_PUKR = FLASHMASS2; //锁2密钥
    while ((unsigned char)!(unsigned char)(FLASH_IAPSR & 0x02))
    {
        _asm("NOP"); //等待解密就绪
    }
}

void subpr_flash_disenable_write(void)
{
    FLASH_IAPSR &= (unsigned char)~0x02;
}

main()
{
volatile unsigned char i;

        while (1)
        {
                //字节写               
                subpr_flash_enable_write();
               
                FLASH_CR2 = 0x00;
                FLASH_NCR2 = 0xff;
               
                _asm("NOP");
                tmp1=0xaa;
                _asm("NOP");
                tmp2=0x55;
               
                _asm("NOP");
               
                tmp1=0x55;
                _asm("NOP");
                tmp2=0xaa;
               
                _asm("NOP");
               
                //字写
                //subpr_flash_enable_write();
                FLASH_CR2 = 0x40;
                FLASH_NCR2 = (unsigned char)~0x40;
               
                _asm("NOP");
               
                tmp3[0] = 0xaa;
                tmp3[1] = 0x00;
                tmp3[2] = 0x55;
                tmp3[3] = 0xff;
               
                _asm("NOP");
               
                                //以下单步执行可以,连续运行就出错!有懂的给个正确代码,谢谢!
                //标准块编程
                //subpr_flash_enable_write();
                FLASH_CR2 = 0x01;
                FLASH_NCR2 = (unsigned char)~0x01;

                _asm("NOP");
               
                for (i = 0; i <64; i++)
                {
                        tmp4 = i;
                }
               
                _asm("NOP");
               
                //快速块编程
                //subpr_flash_enable_write();
                FLASH_CR2 = 0x10;
                FLASH_NCR2 = (unsigned char)~0x10;
               
                _asm("NOP");
               
                for (i = 0; i <64; i++)
                {
                        tmp4 = (unsigned char)(64 - i);
                }
               
                _asm("NOP");
               
                //块擦除
                //subpr_flash_enable_write();
                FLASH_CR2 = 0x20;
                FLASH_NCR2 = (unsigned char)~0x20;
               
                _asm("NOP");
               
                for (i = 0; i <16; i++)
                {
                        tmp4[(unsigned char)(i * 4)] = 0x00000000;
                }
                                       
                _asm("NOP");
                                
                subpr_flash_disenable_write();
                _asm("NOP");        

        }
}

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xuyiyi + 1
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

50

帖子

1

粉丝