首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

关于flash 模拟 EEPROM的问题请教

关于flash 模拟 EEPROM的问题请教

请教斑竹:

1.Freescale 宣传资料上称所有908MCU的flash都可以用作EERPOM。 但应用时在datasheet
中一般都找不到详细一些的说明, 最通用的型号 像JL/K QT/Y MR 系列都没有该项介
绍。 据说所有型号的MCU的monitor rom 中都放有对FLASH进行操作的读写子程序,但找不
到更详细的介绍

2.如果想要调用monitor rom中flash读写子程序的入口地址,用户需要自己到freescale 网
站上去搜索相关资料,对于freescale的新用户来说,有点麻烦。
举个例子: 如果想找jl3 monitor rom中flash读写 子程序的入口地址,先要到
freescale 网站找到jl3的主页,然后在近百个参考资料中把AN2504文件找出来,从中找到
jl3的该项子 程序入口,最后你才可以在你的程序中添加该EEPROM模拟程序

3.当然,每种型号的datasheet中,都有对flash 读写操作的介绍,用户可以自己编写程序对
flash 进行读写.但该方法不太方便,我试过用这种方法操作,可以达到同样效果,但是太繁
琐,不仅要自己编写程序,还要将该模块调到RAM中操作.每个模块要占用40byte左右的空
间,太浪费RAM

针对以上几点,我的问题是:
1.Freescale 该项flash 模拟EEPROM技术 是不是可以建议客户大批量应用,如果可以做一
个卖点来推广,为什么不直接在datasheet中将rom 的程序入口地址告诉客户

2.对于一些没有把入口地址公开的MCU型号,(例如MR32,即使在网站也搜索不到该项应用),
是不是不建议客户使用该项功能. 如果客户自己编写flash读写程序,将某段flash当
eeprom来用,会不会有什么隐患?

这是我自己应用freescale mcu时遇到的一些问题,一直有些疑惑,希望斑竹解答一下.其他兄弟有对这一块比较熟悉,欢迎给出你的建议.多谢
并不是所有的908芯片中都有FLASH擦写子程序。一般而言,只是那些RAM比较小的芯片中才预置了FLASH子程序。而有FLASH子程序的芯片,在其数据手册中都给出了入口地址。

另外,对于那些没有预置FLASH子程序的芯片,也可以在飞思卡尔的网站上找到相应的参考说明及源程序。
海纳百川  有容乃大
MC68HC908QY4单片机FLASH模拟EEPROM的方法 MC68HC908QY4的FLASH写入10个字节,仅需1ms,是EEPROM的10倍。它的擦除时间为4ms。它的擦写次数为1万次。 MC68HC908QY4的FLASH是以页为单位,每页64字节。它允许写入单个字节,但是擦除时,必须整页擦除。在一页内,可以依次将数据写入FLASH,当写满一页后,再全部擦除整页。比如每次写入4字节数据块,一页可以写16个数据块,写满后,再全部擦除。这样在某个页内对数据块的擦写次数可以提高16倍,即16万次。数据块的大小最好是2的n次方,并且小于32字节。这样可以一页64字节就可以全部利用。如果大于32字节,每写一次,就要擦除整页。 一般的要想对FLASH在应用编程,必须将FLASH的擦写程序拷贝到RAM中执行,但是由于MC68HC908QY4的RAM只有128字节,而且FLASH空间也有限,所以飞思卡尔把对FLASH擦写的程序在出厂前固化到了监控ROM区中。用户如需对FLASH进行编程,只需调用这几个函数即可。 ---------------------------------------------------------------------------------------------------------- ERARNGE 0x2806 //擦除函数入口地址 PGRRNGE 0x2809 //编程函数入口地址 表1 固化在ROM内的函数的入口地址 ------------------------------------------------------------------------------------------------------------ 调用编程函数时,这些函数需要访问几个固定RAM区,因此需要先对这几个RAM区赋值。如图2所示。注意:用户的应用程序中的变量不要放在这个区域内。在调用PGRRNGE时,需要编程的FLASH的起始地址需要放在变址寄存器H:X中,所以不需要在RAM区来存储。 ------------------------------------------------------------------------------------------------------------ 入口参数 RAM地址 字节数 用途 CTRLBYT $88 1 控制位 CPUSPD $89 1 总线速度(单位:0.25MHz) LSTADDR $8A-8B 2 FLASH中数据块的末尾地址 BFRSTRT $8C => 数据块的大小 数据缓冲区即要编程的数据 表2 固化在ROM内的函数用到的RAM区的地址 ------------------------------------------------------------------------------------------------------------ 另外需要注意的是CTRLBYT用来告诉擦除函数时页擦除,还是整体擦除。这里因为用户程序需要保留,所以应该选择页擦除。CPUSPD要告诉这两个函数总线的速度,以保证这些函数在执行时延时准确。在调用这两个函数时,要禁止所有的中断,在调用结束后,再打开中断。下面代码是使用示例,编程环境为codewarriorHC08 V3.1。 ------------------------------------------------------------------------------------------------------------ #include /* for EnableInterrupts macro */ #include /* include peripheral declarations */ #define FBUS 3200000 //总线速度 #define ERARNGE() {__asm jsr 0x2806;} //跳到0x2806执行 #define PGRRNGE() {__asm jsr 0x2809;} //跳到0x2809执行 #define CTRLBYT (*(volatile unsigned char*) (0x88)) //存放控制位的RAM地址 #define CPUSPD (*(volatile unsigned char*) (0x89)) //存总线速度的RAM地址 //LADDRH,LADDRL存储FLASH编程末尾地址的RAM地址 #define LADDRH (*(volatile unsigned char*) (0x8A)) #define LADDRL (*(volatile unsigned char*) (0x8B)) #define OSC_CONST FBUS/250000 //总线速度(单位:0.25MHz) #define FLASH_TEST_ADDRESS 0xFD40 //存放数据的FLASH页的首地址 #define RECEIVE_LENGTH 2 //编程数据的长度 unsigned char My_Receive[RECEIVE_LENGTH]@0x8C; //存储编程数据的RAM区 void ProgramRange(word *_ini, byte _num) //FLASH编程函数 { word _first; _first = *_ini; //要编程的起始地址 CPUSPD = OSC_CONST; //总线速度 LADDRH = ((_first + _num -1) & 0xFF00) >> 8; LADDRL = ((_first + _num -1) & 0x00FF); //要编程的末尾地址 __asm ldhx _first; //将要编程的地址装入H,X寄存器 PGRRNGE(); //调用编程函数 return; } void EraseRow(word *_row) //FLASH擦除函数 { word _address; _address = *_row; //要擦除的起始地址 CPUSPD = OSC_CONST; //总线速度 CTRLBYT &= 0xBF; //控制字,页擦除 __asm ldhx _address; //将要擦除的地址装入H,X寄存器 ERARNGE(); //调用擦除函数 return; } void main(void) { word address; word *ptr; address = FLASH_TEST_ADDRESS; EraseRow(&address); //擦除地址从FLASH_TEST_ADDRESS开始的一页 My_Receive[0] = 0x18; //要写入FLASH中的数据 My_Receive[1] = 0x08; //要写入FLASH中的数据 //从FLASH_TEST_ADDRESS开始写入RECEIVE_LENGTH个字节 ProgramRange (&address, RECEIVE_LENGTH); EnableInterrupts; /* enable interrupts */ for(;;) { ptr=(word *) (0xFD40)); //把FLASH中刚写入的值读出来 .... } } FLASH模拟EEPROM使用实例 ------------------------------------------------------------------------------------------------------------ 上面的例子只是介绍了一种基本的FLASH模拟EEPROM的方法,用户如果想写满整页之后,再擦除,可以采用查询方式,从页的首地址开始,如果FLASH的内容等于$FF,则表示为空,然后在该地址内写入数据,一直到写满。不过此时用户的数据不能等于$FF,否则会发生错误。另外,还可以采用标志位,在保存的数据后面加一个标志位,如果查到标志位,就说明此地址内已有数据,然后继续往后查询,直到最后一个标志位,此时后面的FLASH空间内可以写数据。 如果用户需要保存历史数据,则可以采用两页FLASH来存储数据,一页存放当前数据,另一页存放历史数据。当前数据页存满以后,把数据全部转移到历史数据页中,然后在擦除当前数据页,继续写入新数据。 另外用户的应用程序为了避免意外的被擦除,应该把存放用户程序的FLASH保护起来。寄存器FLBPR可以用来保护从某一特定地址以上的FLASH区。因此用来存放数据的FLASH区应该尽量从地址开始,用户程序放在高地址。FLBPR寄存器的赋值需要对采用FLASH的编程方法写入。 在应用中,系统可能在编程中掉电,或由于其他原因程序中止,这样已经写入的数据可能是无效的或错误的,用户在开发阶段要考虑到这一点,尽量减少这种情况的发生,或者可以考虑采用数据恢复机制。不过由于FLASH的擦写速度快,所以发生这种情况时,它比EEPROM就更具有优势。
Application Note AN2346, “EEPROM Emulation Using FLASH in MC68HC908QY/QT MCUs”
Application Note AN1831, “Using MC68HC908 On-chip FLASH Programming Routines”
Application Note AN2183, “Using FLASH as EEPROM on the MC68HC908GP32”
收到! 多谢斑竹和三楼的回复, [em04]
返回列表