打印

请教!用flash单片机还是串行flash+OTP单片机?

[复制链接]
4029|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bornwong|  楼主 | 2008-8-22 09:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
forthlab| | 2008-8-22 11:07 | 只看该作者

flash区可以自己擦除的CPU的可靠性会差点

看你用在啥场合.一般用是没有问题的.比如简单的温控器等.
如果带ISP代码,会有程序代码被误擦除的情况出现!高可靠的CPU要求正常运行的CPU内部没有擦除FLASH的代码.

使用特权

评论回复
板凳
bornwong|  楼主 | 2008-8-23 20:53 | 只看该作者

程序不擦除的,只用写几个字节的数据

有ISP功能的单片机能不能只写几个字节,不对程序更新的?谢谢!

使用特权

评论回复
地板
dai_weis| | 2008-8-23 21:06 | 只看该作者

使用Bootload功能

使用特权

评论回复
5
aihe| | 2008-8-24 22:58 | 只看该作者

为什么不用片内EEROM

使用特权

评论回复
6
koolean| | 2008-8-24 23:28 | 只看该作者

有些OTP单片机内部有EEPROM

128bit的,是否适合你用?我知道PIC的有几款,义隆也有几款。低成本的。你找下看看;

使用特权

评论回复
7
bornwong|  楼主 | 2008-8-26 17:44 | 只看该作者

flash单片机才会带EEPROM吧

谢谢!我去找找!

使用特权

评论回复
8
iammercy| | 2008-8-27 09:29 | 只看该作者

推薦使用中穎單片機79Fxxx系列

SH79Fxxx Flash use as EEPROM
79Fxxx的flash可以当EEPROM用
原理:79Fxxx的flash rom是由数个sector组成,每个sector大小为2kB
如 79F161,有16K rom, 则有8个sector
可以划分一个sector作为flash eeprom,节省外围的eeprom器件,如24C02
从而节省成本。

79Fxxx Flash ROM的擦写寿命最少有1万次,若每次只需要保存8个字节,
可以把整个sector 2k空间划分为256页,每页8个字节,
当写满256页才进行擦除,这样理论上寿命可以达到128万次,大大提高可靠性能

由于每次写保存到flash rom的地址都不一样,例如采用sector 6
第一次保存数据是保存到 0x3000~0x3007,第二次写flash后数据则保存到0x3008~0x300f,
例子中通过二分法算法查询上次保存的那8个数据保存到第几页,以便读出最新写入的数据,或者继续写数据到后续空页处,
二分法算法大大提高索引效率。

程序提供2个函数,方便对flash读写操作
void WriteFlash(Byte *ptr)        //ptr is the head pointer of the write buffer
void ReadFlash(Byte *ptr)        //ptr is the head pointer of the read buffer

注意的地方:
Flash ROM的第一个sector和最后一个sector不能用作flash eeprom
因为第一个sector(即程序code区0x0000~0x0fff)包含中断向量入口,
最后一个sector的最后64个Bytes被硬件屏蔽,
eg:对于79F161,Sector 1,2,3,4,5,6可以用作flash eeprom,而Sector0和Sector7则不能用作flash eeprom

振荡器频率为8M,写周期为30us(写入一个Byte),擦周期为60ms(擦除整个Sector)
也可以根据需要使用其它振荡器频率,擦Flash和写Flash周期设置为符合规格书要求即可

具体说明及设置请查看源程序注释
程序解釋
SSP實現Flash當EEPROM驅動:
79Fxxx的flash rom是由数个sector组成,每个sector大小为2kB,79F161有16K rom, 共8个sector
程序中劃分sector6作为flash eeprom,节省外围的eeprom器件,如24C02,从而节省成本。
        
Flash ROM的第一个sector和最后一个sector不能用作flash eeprom用途
因为第一个sector包含中断向量入口,最后一个sector的最后64个Bytes被硬件屏蔽,对于79F161,Sector 1,2,3,4,5,6可以用作flash eeprom,而Sector0和Sector7则不能用作flash eeprom
#define        SECTOR1         0x0800                        //0800~0fff
#define        SECTOR2         0x1000                        //1000~17ff
#define        SECTOR3         0x1800                        //1800~1fff
#define        SECTOR4         0x2000                        //2000~27ff
#define        SECTOR5         0x2800                        //2800~2fff
#define        SECTOR6         0x3000                        //3000~37ff
#define        SECTOR         SECTOR6                        //劃分SECTOR6作為EEPROM
79Fxxx Flash ROM的擦写寿命有1萬次,程序中把整个sector 2k空间划分为256页,每页8个字节,当写满256页才进行擦除,这样理论上數據保存可以达到128万次,大大提高壽命及可靠性能
#define FLASH_PAGE_BYTES                8        //    this value divide exactly by 2048
#define FLASH_PAGE_COUNT                2048/FLASH_PAGE_BYTES        
//allocate flash eeprom area at ROM sector 6 (C:0x3000~C:0x37ff)
typedef struct 
{
                Byte        ROM[FLASH_PAGE_BYTES];
}FLASH_MEMORY;                                                                                                //flash Page datastructure
FLASH_MEMORY        code        Flash[FLASH_PAGE_COUNT]         _at_        SECTOR;                //flash eeprom datastructure
        
每次寫數據即寫一個Byte時間必須設定在30us左右,每次擦除即整個Sector清零時間必須設定在60ms左右
#define                PROGRAM_CLK                (65536 - 30)                                //*** 30us/(8*125ns) = 30us
#define                ERASE_CLK                        (65536 - 60000)                                //*** 60ms/(8*125ns) = 60000us
        
每次寫時寫到上次寫的那頁的后一頁,每次讀時返回最新寫的那一頁的數據,由于每次写保存到flash rom的地址都不一样,采用sector 6,第一次保存数据是保存到 0x3000~0x3007,第二次写flash后数据则保存到0x3008~0x300f,通过二分法算法求得上次保存的数据保存到第几页,以便读出最新写入的数据,或者继续写数据到后續的空页处,二分法算法大大提供索引效率。
        
                
判斷某一頁是否為NULL
bit        CheckFlashPageNull(Byte index)                
{
                        Byte i;
                        for(i=0;i<FLASH_PAGE_BYTES;i++)
                        {
                                if(Flash[index].ROM)
                                {
                                        return 1;
                                }        
                        }
                        return 0;
}        
        

二分法求得有效數據的頁索引號,并返回有效數據是否為NULL標記
bit        GetFlashPageIndex(Byte *index)                
{
                        Byte low  = 0;
                        Byte high = FLASH_PAGE_COUNT-1;                                
                        Byte mid;
                        bit         flag;
                
                        while(1)
                        {                
                                mid  = low+(high-low)/2;
                                flag = CheckFlashPageNull(mid);
                                if(mid == low)
                                {
                                        break;
                                }
                                if(flag)
                                {
                                        low = mid;
                                }
                                else
                                {
                                        high = mid;
                                }
                        }
                        if(CheckFlashPageNull(high))
                        {
                                *index = high;
                                return 1;
                        }
                        else
                        {
                                *index = low;
                                return        flag;        
                        }
}
SSP寫Flash函數
void        ProgramFlash(Byte pageIndex,Byte *ptr)
{
        Word        FlashAddr=Flash;
        Byte         i;
        Bit                EA_BAK = EA;                
        //---------------------------------------
        for(i=0;i<pageIndex;i++)        
        {
                FlashAddr +=FLASH_PAGE_BYTES;
        }
        EA = 0;                                                                //step 1
        IB_CLK1        =        (PROGRAM_CLK>>8)&0xff;        //step 2
        IB_CLK0        =        (PROGRAM_CLK)&0xff;
        for(i=0;i<FLASH_PAGE_BYTES;i++)
        {
                XPAGE          = HIBYTE(FlashAddr);        //step 3
                IB_OFFSET= LOBYTE(FlashAddr);
                IB_DATA         = *(ptr+i);                        //step 4
                IB_CON1         = 0x6E;                                //step 5
                IB_CON2         = 0x05;
                IB_CON3         = 0x0A;
                IB_CON4         = 0x09;
                IB_CON5         = 0x06;
                _nop_();                                                //step 6
                _nop_();
                _nop_();
                _nop_();
                FlashAddr ++;                                        //step 7
        }                                
        //---------------------------------------
        EA = EA_BAK;
}
SSP擦除Flash函數
void        EraseFlash(void)
{
                Word        FlashAddr=Flash;
                Bit                EA_BAK = EA;
                //---------------------------------------
                EA = 0;                                                                //step 1
                IB_CLK1         = (ERASE_CLK>>8)&0xff;        
                IB_CLK0         = (ERASE_CLK)&0xff;                //step 2
                XPAGE          = HIBYTE(FlashAddr);                //step 3
                IB_OFFSET= LOBYTE(FlashAddr);
                IB_CON1         = 0xE6;                                        //step 4
                IB_CON2         = 0x05;
                IB_CON3         = 0x0A;
                IB_CON4         = 0x09;
                IB_CON5         = 0x06;
                _nop_();                                                        //step 5
                _nop_();
                _nop_();
                _nop_();        
                //---------------------------------------
                EA = EA_BAK;
}
寫數據
第1次寫數據時,由于之前從未寫過數據,返回的索引號為0,且該頁為NULL,于是便把數據寫到第0頁。
第2次寫數據時,返回的索引號為0,該頁非NULL,于是便把數據保存到第1頁
….
第256次寫數據時,返回的頁索引號為0xff,該頁非NULL,先擦除整個SECTOR,再把數據寫到第0頁
void Driver_WriteFlash(Byte *ptr)
{
                bit        flag;
                Byte index;
                flag = GetFlashPageIndex(&index);
                if(index == (FLASH_PAGE_COUNT-1))
                {
                        EraseFlash();
                        index =0;
                }
                else if(flag)
                {
                        index ++;
                }
                ProgramFlash(index,ptr);
}
讀數據
根據索引值讀出有效數據,有待后續校驗
void Driver_ReadFlash(Byte *ptr)
{
        Byte i;
        Byte index;
        GetFlashPageIndex(&index);        
        for(i=0;i<FLASH_PAGE_BYTES;i++)
        {
                *ptr = Flash[index].ROM;
                ptr ++;
        }
}

使用特权

评论回复
9
gyt| | 2008-8-27 10:40 | 只看该作者

厉害

使用特权

评论回复
10
koolean| | 2008-8-31 00:34 | 只看该作者

OTP型的单片机,内部自带128BIT的EEPROM。

我查到了,PIC12/16系列都有带EEPROM,义隆的型号应该是EM78P6xx系列;合泰的是HT48Fxx和HT46Fxx,MC的也有,懒得列出来啦。如果楼主险麻烦或者不好用,那干脆就用一个低成本主芯片外加一个24C02;

使用特权

评论回复
11
bill_lan| | 2008-9-2 18:00 | 只看该作者

IAP

 这种功能应该叫IAP的.中颖的8位单片机就具备这种能力.我在电动车控制器
 上就用到了这种功能.将自学习后的数据写入flash中。
 宏晶(STC)的单片机也有这种能力.

使用特权

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

本版积分规则

3

主题

22

帖子

0

粉丝