1 引言
TI公司出品的MSP430系列单片机,是一种具有超低功耗特性的功能强大的单片机。MSP430系列正是由于具有以下一些特点:超低功耗;强大的处理能力;中断源较多,并且可以任意嵌套,使用时灵活方便;丰富的片上外围模块;方便高效利用JTAG接口或片内BOOT ROM的开发方式;适应工业级运行环境;日益受到市场的推崇。
尤其值得一提的是:TI公司的MSP430系列Flash型单片机内部集成有Flash控制器,可以采用外部编程器进行烧写,也可以利用自己的程序修改Flash的内容,且不用外加编程电压。Flash的可自编程性(Self-Programmability)是指,用Flash存储器中的驻留软件或程序对Flash存储器进行擦除/编程,但是,要求运行程序代码的存储区与待编程的存储区不在同一模块中。由于MSP430系列单片机只有一个片上Flash存储器模块的微处理器,因此不能同时进行擦除/编程Flash的操作。目前,在擦除/编程Flash的过程中,通常将CPU置于空闲状态。因此在进行系统设计时,可以利用片内的Flash保存一些运行数据,实现掉电保护;还可以修改Flash中的整个程序或局部程序,实现在系统升级。
本文详细举例介绍了在MSP430系列C语言环境下如何高效地完成对Flash存储器的参数在线保存和擦写技巧。
2 MSP430芯片Flash存储器的结构
MSP430的FLASH型芯片采用FLASH存储器作为程序代码及信息的存储,可以实现多次擦除和写入,也可以实现在线写入,其写入可以由JTAG接口来完成,也可以由芯片内的驻留软件实现,只需运行的程序代码存储区与待编程的存储区不在同一模块中。FLASH存储器的基本功能有:在程序执行时提供代码和数据;在软件或JTAG接口控制下作一段、多段或整个模块的擦除;在软件或JTAG接口控制下写入数据,在x000h~x1FFh的512字节区域内可实现双倍编程速度。Flash存储器模块是一个可独立操作的物理存储器单元。全部模块安排在同一个线性地址空间中,一个模块又可以分为多个段[4]。
当对Flash存储器段中的某一位编程时,就必须对整个段擦除,因此,Flash存储器必须分为较小的段,以方便地实现擦除和编程。如图1所示是MSP430芯片上Flash存储器模块的结构框图。该Flash存储器模块包含如下部分:
图1 FLASH存储器结构图
(1) 控制逻辑—控制Flash擦除和编程时的机器状态和时序发生器;
(2) Flash保护逻辑—避免意外的Flash擦除和编程操作;
(3) 编程电压发生器—提供Flash擦除和编程所需全部电压的集成电荷泵;
(4) 3个16位控制寄存器—FCTL1、FCTL2、FCTL3控制Flash模块的全部操作;
(5) 存储器本身。
3 Flash存储器的擦除和编程操作
以MSP430系列的MSP430F149为例,MSP430F149的一个FLASH存储器模块包含3个控制寄存器、时序发生器、提供编程及擦除电压的电压发生器和存储器本身。FLASH存储器绝大多数时间工作在读模式。这时数据、地址锁存器是透明的,时序发生器和电压发生器关闭。当数据写入FLASH存储器模块,或者它的全体或部分被擦除时,FLASH存储器改变它的工作模式。这时需要在控制寄存器FCTL1、FCTL2和FCTL3中设置适当的参数以保证编程/擦除操作的正确执行。一旦控制寄存器设置后,编程/擦除操作开始,时序发生器即控制全部执行过程,产生全部内部控制信号。如果BUSY位为“1”,就表明时序发生器还在工作,编程/擦除操作正在进行。对于段编程还有第二个控制位WAIT。
编程/擦除操作有三个基本阶段:准备编程/擦除电压阶段、时序控制编程/擦除操作及关闭编程/擦除电压。一旦编程/擦除操作开始,在BUSY位变为“0”之前无法对FLASH存储器访问。若有异常情况,则正在进行的编程/擦除操作要立即停止,可以用紧急退出位EMEX置位来实现。但是,这时操作并未完成,结果可能是不正确的。
MSP430系列芯片中只集成了一个Flash模块用作程序和数据存储器。这就意味着在对Flash进行编程时,中断向量是不起作用的,任何中断请求都得不到响应。所有可能的中断源(包括看门狗)在对Flash进行擦除/编程操作前,都应该被屏蔽掉。
4 参数设置的保存和提取
MSP430系列微处理器的信息存储器为每段128字节,取名为信息存储器A和B,主存储器每段为512字节。所有型号器件的信息存储器的地址完全相同,从1000H~10FFH.。这里给出满足所有FLASH型号器件的每一段起始和结束地址。
信息存储器A段的起始地址在1080H,结束地址在10FFH。
信息存储器B段的起始地址在1000H,结束地址在107FH。
主存储器第段的起始地址为:
主存储器第段的结束地址为:
值得注意的是:运行的程序代码存储区与待编程的存储区应不在同一段中。
5 对Flash存储器的操作介绍
由于Flash存储器由很多相对独立的段组成,因此可在一个段中运行程序,而对另一个段进行擦除或写入数据等操作。
5.1 对Flash存储器的擦除操作
对Flash段的擦除操作的顺序如下:
(1) 选择适当的时钟源和分频因子,为时序发生器提供正确的时钟输入;
(2) 如果Lock=1,则将它复位;
(3) 监视BUSY标志位,只有当BUSY=0时才可以执行下一步,否则一直监视BUSY;
(4) 如果擦除一段,则设置ERASE=1;
(5) 如果擦除多段,则设置MERAS=1;
(6) 如果整个FLASH全擦除,则设置ERASE=1同时MERAS=1;
(7) 对擦除的地址范围内任意位置作一次空写入,用以启动擦除操作。如果空写的地址在不能执行擦除操作的段地址范围内,则写入操作不起作用。
5.2 对Flash存储器的编程/写操作
Flash存储器主要用于保存用户程序或重要的数据﹑信息等一些掉电后不能丢失的数据。只有通过对Flash的编程操作,才能将这些数据写入Flash存储器。有两种方式可以对Flash编程:单个字或字节写入,多个字或字节顺序写入或块写入。程序流程图如图2所示。对Flash编程按如此下顺序进行:
图2 写Flash程序流程图
(1) 选择适当的时钟源以及合适的分频因子;
(2) 如果Lock=1,将它复位;
(3) 监视BUSY位,直到BUSY=0时才可进入下一步;
(4) 如果写入单字或单字节,则将设置WRT=1;
(5) 如果块写或多字、多字节顺序写入,则将设置WRT=1,BLKWRT=1;
(6) 将数据写入选定地址时启动时序发生器,在时序发生器的控制下完成整个过程。
下面列出了MSP430F149能连续写入数据的存储器块:
0F000H~0F03FH,0F040H~0F07FH,0F080H~0F0BFH,0F0C0H~0F0FFH,0F100H~0F13FH。
6 实际操作分析和实用技巧
6.1 基于裸机的首次参数输入保存
通常,以MSP430系列为微处理器核心的系统开发,都是由设计人员完成全部软件设计,从而实现应用系统的各个功能的要求的裸机应用开发,应用系统的实时性,可靠性和使用的人性化与设计人员的水平和经验密切相关。如图3所示,基于裸机的编程结构的核心实际上就是应用系统在上电以后不断的做一个循环,在有外部响应的的条件下根据响应级别的高低,完成相应的功能操作。
图3 基于裸机的编程结构
开发出来的产品在第一次出厂的时候MSP430F149微处理器内部Flash的空间是一堆乱码,那么如果此时直接进入循环程序,利用内部的参数那么此时计算出来的数据是无用的和不可靠的。因此,建议在系统产品化以后的第一次上电,要求用户输入所有参与计算的相关参数。
6.2 数组结构的C语言参数保存
存储单元,为了以后程序版本升级的方便,建议在系统设计时采用数组结构的存储方式,即在实际设计中预设了n个存储单元,将这n个存储单元作为一个数组,将数组中每一个数组变量与一个特定的需要保存的参数变量相对应,在每次修改完所需要修改的参数时,将新的参数赋予数组中相对应的元素,再以数组的形式把所有的没有修改的元素和已经修改的元素对数据保存段进行擦写[7]。以MSP430F149为例的C语言环境下保存参数程序如下:
void keypad_Write_Setting_To_Flash(void)
{
unsigned char i;
unsigned int *tp,*write_ptr;
tp =(unsigned int *)0x1000;
//指向information flash 首地址,segmentB
_DINT( );
FCTL1 = FWKEY + ERASE;
//写键值和允许擦除
FCTL3 = FWKEY;
//写键值,lock=0,
*tp = 0;
//空写入,确定段号
FCTL1 = FWKEY + LOCK;
//lock=1,当前段擦除完毕
FCTL3 = FWKEY;
//写键值,lock=0
write_ptr = (unsigned int *) 0x1000;
FCTL1 = FWKEY + WRT;
//写参数
FCTL3 = FWKEY;
for( i =0; i <=n; i++ ) *(write_ptr++)
= key_setting;
//逐个往Flash中写数组中的元素
FCTL1 = FWKEY; //不写
FCTL3 = FWKEY + LOCK;
_EINT( );
}
7 结束语
本文在详细介绍了MSP430系列单片机内部集成的Flash控制器的结构的基础上,以该系列的MSP430F149为例,详细介绍了对该系列单片机的Flash存储器的操作,包括了对Flash存储器的擦除操作和对Flash存储器的编程/写操作过程。并且就在实际现场的基于裸机的首次参数保存提出了实用建议,最后给出了基于数组结构参数保存的已经在实际系统中使用了的C语言例程。
文章评论(0条评论)
登录后参与讨论