MSP430程序库十五Flash控制器.docx

上传人:b****5 文档编号:7254092 上传时间:2023-01-22 格式:DOCX 页数:16 大小:942.88KB
下载 相关 举报
MSP430程序库十五Flash控制器.docx_第1页
第1页 / 共16页
MSP430程序库十五Flash控制器.docx_第2页
第2页 / 共16页
MSP430程序库十五Flash控制器.docx_第3页
第3页 / 共16页
MSP430程序库十五Flash控制器.docx_第4页
第4页 / 共16页
MSP430程序库十五Flash控制器.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

MSP430程序库十五Flash控制器.docx

《MSP430程序库十五Flash控制器.docx》由会员分享,可在线阅读,更多相关《MSP430程序库十五Flash控制器.docx(16页珍藏版)》请在冰豆网上搜索。

MSP430程序库十五Flash控制器.docx

MSP430程序库十五Flash控制器

MSP430程序库<十五>Flash控制器

一般,在单片机中的Flash存储器用于存放程序代码,属于只读型存储器。

而在MSP430些列的单片机中,都可以通过内置的Flash控制器擦除或改写任何一段的内容。

另外,msp430的单片机内部还专门留有一段Flash区域(informationmemory),用于存放掉电后需要永久保存的数据。

利用430内部的Flash控制器,可以完成较大容量的数据记录、用户设置参数在掉电后的保存等功能。

∙硬件介绍:

要对Flash读写,首先要了解MSP430的存储器组织。

430单片机的存储器组织结构采用冯诺依曼结构,RAM和ROM统一编址在同一寻址空间中,没有代码空间和数据空间之分。

一般430的单片机都统一编址在0-64k地址范围中,只有少数高端的型号才能突破64k(如:

FG461x系列)。

绝大多数的msp430单片机都编址在64kB范围内。

地址的大概编码方式如下:

这是msp430f425的存储器分配图,其他在64k范围内的存储器的单片机编址方式与此类似:

低256B是寄存器区,然后是RAM;空白;1000H到10FFH是信息Flash区;大于1100H-0FFFFH是主存储器区(从0FFFFH开始往低地址有单片机的主Flash,多余的部分空白)。

MSP430F14x的Flash分布:

 

MSP430F16x的Flash分布:

 

主Flash部分和信息Flash部分如下(60kBFlash对应的单片机,如msp430f149、msp430f149):

主Flash分为以512B为段的单位,0段是单片机中断向量等程序入口地址,使用时不要擦除此段或改写此段,若要擦除或是改写,请先保存内容到RAM或其他段;主Flash各段内容均要避免写入或擦除,以免造成不可预料的后果。

信息Flash分为两段:

段A和段B,每段128B;可以保存用户自己的内容(主Flash也可以但是要避免与程序代码区冲突);这里就把信息Flash的两段称为InfoA(1080H-10FFh)和InfoB(1000H-10FFH)。

Flash的操作包括:

字或字节写入;块写入;段擦除;主Flash擦除;全部擦除。

任何的Flash操作都可以从Flash或从RAM中运行。

Flash操作时需要时序发生器,Flash控制器内部含有时序发生器用以产生所需的Flash时钟,Flash时钟的范围必须在257kHz到476kHz之间。

时序发生器的框图如下:

时序发生器可以选择ACLK、MCLK、SMCLK作为时钟源,通过分频获得所需的257kHz到476kHz之间的Flash操作时钟。

如果时钟频率不再这个范围内,将会产生不可预料的结果。

擦除:

擦除之后,存储器中的bit都变为1;Flash中的每一位都可以通过编程写入有1到0,但是要想由0变为1,必须通过擦除周期。

擦除的最小单位是段。

有三种擦除模式:

MERASERASEEraseMode

01Segmenterase

10Masserase(allmainmemorysegments)

11Eraseallflashmemory(mainandinformation.segments)

可以通过MERAS、ERASE位来设置擦除的模式:

段擦除,主Flash擦除,全部擦除。

对要擦除段内的一个地址空写入启动擦出周期:

空写入可以启动时序发生器和擦除操作。

空写入后BUSY位立即变高直到擦除周期结束,这一位变为低(0)。

BUSY,MERAS和ERASE位在擦除周期结束后会自动复位。

擦除周期的时间和要擦出的Flash大小无关,每次擦除的时间对于MSP430F1xx系系列单片机来说,所需时间是一样的。

擦除的时序如下:

当空写入到的地址不在要擦除的段地址范围内的时候,空写入无效,直接被忽略。

在擦除周期内,应该关中断,直到擦除完成,重新开中断,擦除期间的中断已经置标志位,开中断后立即响应。

从Flash中启动的擦除操作:

擦除操作可以从Flash中启动或是从RAM中启动。

当操作是从Flash中启动的时候,Flash控制器控制了操作时序,CPU运行被暂停直到擦除结束。

擦除周期结束后,CPU继续执行,从空写入之后的指令开始运行。

当从Flash中启动擦除操作时,可以擦除即将运行的程序所在的段,如果擦除了即将运行的程序所在的Flash段时,擦除结束后,CPU的运行不可预料。

从Flash启动时擦除周期如下:

用户指南里面的示例汇编程序如下:

;SegmentErasefromflash.514kHz

;AssumesACCVIE=NMIIE=OFIE=0.

MOV#WDTPW+WDTHOLD,&WDTCTL;DisableWDT

DINT//;Disableinterrupts

MOV#FWKEY+FSSEL1+FN0,&FCTL2;SMCLK/2

MOV#FWKEY,&FCTL3;ClearLOCK

MOV#FWKEY+ERASE,&FCTL1;Enablesegmenterase

CLR&0FC10h;Dummywrite,eraseS1

MOV#FWKEY+LOCK,&FCTL3;Done,setLOCK

...;Re-enableWDT?

EINT;Enableinterrupts

从RAM中启动擦除操作:

任意擦除周期都可以从RAM启动,这时CPU不再暂停而是继续从RAM中运行接下来的程序。

CPU可以访问任何Flash地址之前,必须检查BUSY位以确定擦除周期结束。

如果BUSY=1访问Flash,这是一个访问冲突,这时ACCVIFG将被设置,而擦除的结果将是不可预测的的。

从RAM中启动擦除操作时,过程如下:

要在擦除之前确认没有访问Flash,然后擦除完成之前不允许访问Flash。

;SegmentErasefromRAM.514kHz

;AssumesACCVIE=NMIIE=OFIE=0.

MOV#WDTPW+WDTHOLD,&WDTCTL;DisableWDT

DINT;Disableinterrupts

L1BIT#BUSY,&FCTL3;TestBUSY

JNZL1;Loopwhilebusy

MOV#FWKEY+FSSEL1+FN0,&FCTL2;SMCLK/2

MOV#FWKEY,&FCTL3;ClearLOCK

MOV#FWKEY+ERASE,&FCTL1;Enableerase

CLR&0FC10h;Dummywrite,eraseS1

L2BIT#BUSY,&FCTL3;TestBUSY

JNZL2;Loopwhilebusy

MOV#FWKEY+LOCK,&FCTL3;Done,setLOCK

...;Re-enableWDT?

EINT;Enableinterrupts

写Flash操作:

写入的模式由WRT和BLKWRT位来确定:

BLKWRTWRTWriteMode

01Byte/wordwrite

11Blockwrite

这两种模式中块写入大约是字或字节写操作时的两倍快,因为在块写入完成之前,变成电压一直维持直到块写入完成。

同一个位置不能在擦除周期之前写入两次或以上,否则将发生数据损坏。

写操作时,BUSY位被置1,写入完成后,BUSY被自动清零。

如果写操作是从RAM发起的,在BUSY=1时,程序不能访问Flash,否则会发生访问冲突,置位ACCVIFG,Flash写入操作不可以预料。

字或字节写入:

字或字节写入可以从Flash内部发起,也可以从RAM中发起。

如果是从Flash中启动的写操作,时序将由Flash控制,在写入完成之前CPU运行将被暂停。

写入完成后CPU将继续运行。

操作时序如下:

若是从RAM中启动写Flash,程序将继续从RAM中运行。

CPU再次访问Flash之前必须确认BUSY位已经清零,否则会发生访问冲突,置位ACCVIFG,写入的结果将不可预料。

字或字节写入模式下,内部产生的编程电压时适用于完整的64个字节块的写入

Inbyte/wordmode,theinternally-generatedprogrammingvoltageisapplied

tothecomplete64-byteblock,eachtimeabyteorwordiswritten,for32ofthe

35fFTGcycles.Witheachbyteorwordwrite,theamountoftimetheblockis

subjectedtotheprogrammingvoltageaccumulates.Thecumulative

programmingtime,tCPT,mustnotbeexceededforanyblock.Ifthecumulative

programmingtimeismet,theblockmustbeerasedbeforeperformingany

furtherwritestoanyaddresswithintheblock.

从Flash发起写字节或字时:

;Byte/wordwritefromflash.514kHz

;Assumes0FF1Ehisalreadyerased

;AssumesACCVIE=NMIIE=OFIE=0.

MOV#WDTPW+WDTHOLD,&WDTCTL;DisableWDT

DINT;Disableinterrupts

MOV#FWKEY+FSSEL1+FN0,&FCTL2;SMCLK/2

MOV#FWKEY,&FCTL3;ClearLOCK

MOV#FWKEY+WRT,&FCTL1;Enablewrite

MOV#0123h,&0FF1Eh;0123h−>0FF1Eh

MOV#FWKEY,&FCTL1;Done.ClearWRT

MOV#FWKEY+LOCK,&FCTL3;SetLOCK

...;Re-enableWDT?

EINT;Enableinterrupts

从RAM中启动写入操作时:

;Byte/wordwritefromRAM.514kHz

;Assumes0FF1Ehisalreadyerased

;AssumesACCVIE=NMIIE=OFIE=0.

MOV#WDTPW+WDTHOLD,&WDTCTL;DisableWDT

DINT;Disableinterrupts

L1BIT#BUSY,&FCTL3;TestBUSY

JNZL1;Loopwhilebusy

MOV#FWKEY+FSSEL1+FN0,&FCTL2;SMCLK/2

MOV#FWKEY,&FCTL3;ClearLOCK

MOV#FWKEY+WRT,&FCTL1;Enablewrite

MOV#0123h,&0FF1Eh;0123h−>0FF1Eh

L2BIT#BUSY,&FCTL3;TestBUSY

JNZL2;Loopwhilebusy

MOV#FWKEY,&FCTL1;ClearWRT

MOV#FWKEY+LOCK,&FCTL3;SetLOCK

...;Re-enableWDT?

EINT;Enableinterrupts

块写入:

当需要写入连续的多个字或字节时,块写入能够能够提高Flash访问速度。

块写入时,内部产生的编程电压一直存在在64个字节的块写入期间。

块写入不能有Flash存储器内启动,必须从RAM中发起块写入操作。

块写入期间,BUSY位被置位。

在写入每个字节或字时必须检测WAIT位。

下一个字或字节能够被写入时,WAIT位被置位。

块写入的过程如下:

 

;Writeoneblockstartingat0F000h.

;MustbeexecutedfromRAM,AssumesFlashisalreadyerased.

;514kHz

;AssumesACCVIE=NMIIE=OFIE=0.

MOV#32,R5;Useaswritecounter

MOV#0F000h,R6;Writepointer

MOV#WDTPW+WDTHOLD,&WDTCTL;DisableWDT

DINT;Disableinterrupts

L1BIT#BUSY,&FCTL3;TestBUSY

JNZL1;Loopwhilebusy

MOV#FWKEY+FSSEL1+FN0,&FCTL2;SMCLK/2

MOV#FWKEY,&FCTL3;ClearLOCK

MOV#FWKEY+BLKWRT+WRT,&FCTL1;Enableblockwrite

L2MOVWrite_Value,0(R6);Writelocation

L3BIT#WAIT,&FCTL3;TestWAIT

JZL3;LoopwhileWAIT=0

INCDR6;Pointtonextword

DECR5;Decrementwritecounter

JNZL2;Endofblock?

MOV#FWKEY,&FCTL1;ClearWRT,BLKWRT

L4BIT#BUSY,&FCTL3;TestBUSY

JNZL4;Loopwhilebusy

MOV#FWKEY+LOCK,&FCTL3;SetLOCK

...;Re-enableWDTifneeded

EINT;Enableinterrupts

当任何写或擦除操作是从RAM启动,而BUSY=1,CPU不能读取或写入或从任何Flash位置。

否则,发生访问冲突,ACCVIFG设置,结果是不可预知的。

此外,如果闪存写入让WRT=0,ACCVIFG中断标志设置,Flash不受影响。

如果写入或擦除操作时从Flash启动的,CPU访问下一条指令时(从Flash读取指令),Flash控制器返回03FFFH给CPU;03FFFH是指令JMPPC,这让CPU一直循环直到Flash操作完成。

Flash写入或擦除操作完成后,允许CPU继续访问接下来的指令。

当BUSY=1时,Flash访问时:

在开始Flash操作之前,需要停止所有的中断源。

如果在Flash操作期间有中断响应,读中断服务程序的地址时,将收到03FFFH作为中断服务程序的地址。

如果BUSY=1;CPU将一直执行难IMPPC指令;Flash操作完成后,将从03FFFH执行中断服务程序而不是正确的中断程序的地址。

停止写入或擦除:

任何写入和擦除操作都可以在正常完成之前,通过设置紧急退出位EMEX退出操作。

设置EMEX时,立即停止当前活动的操作,停止Flash控制器;所有的Flash操作停止,Flash返回可读模式,FCTL1的所有位复位;操作的结果不可预料。

设置和访问Flash控制器:

FCTLx是16位的、密码保护的、可读写的寄存器。

写入这些寄存器都必须在高位包含密码0A5H,如果写入的不是0A5H,将会引起复位。

读寄存器时高位读出的是96H。

在擦除或写入字或字节时写FCTL1寄存器将会引起访问冲突,置位ACCVIFG.块写入时,WAIT=1时可以写FCTL1寄存器,当WAIT=0时写FCTL1寄存器是访问冲突,置位ACCVIFG。

BUSY=1时,所有写入FCTL2寄存器都是访问冲突。

BUSY=1时,所有的FCTLx都可以读操作,不会引起访问冲突。

Flash的中断:

Flash控制器有两个中断源:

KEYV,和ACCVIFG。

ACCVIFG在访问冲突的时候被置位。

当ACCVIE在Flash操作完成后被重新使能后ACCVIFG会引起中断请求。

ACCIFG和NMI同样的中断向量,所以这个中断不需要GIE位允许即可产生中断请求。

必须通过软件检测ACCVIFG位,以确定发生了访问冲突;ACCVIFG位必须软件复位。

KEYV是关键值错误当写Flash的寄存器时没有写正确的高位密码时被置位,这是会立刻引起PUC信号复位整个硬件。

编程Flash的硬件:

编程430的Flash内容有三种选择,通过JTAG、通过BSL和用户定制。

用户定制即是通过单片机的程序访问自己的Flash。

Flash的寄存器列表如下:

RegisterShortFormRegisterTypeAddressInitialState

Flashmemorycontrolregister1FCTL1Read/write0128h09600hwithPUC

Flashmemorycontrolregister2FCTL2Read/write012Ah09642hwithPUC

Flashmemorycontrolregister3FCTL3Read/write012Ch09618hwithPUC

InterruptEnable1IE1Read/write000hResetwithPUC

Flash的硬件部分就介绍这么多了,有什么不大懂的地方请参考TI提供的用户指南。

∙程序实现:

首先设置Flash的时钟,初始化Flash控制器:

voidFlashInit()

{

FCTL2=FWKEY+FSSEL_2+FN1;//默认SMCLK/3=333KHz

}

这个函数仅仅设置了时钟。

擦除函数:

voidFlashErase(unsignedintAddr)

{

char*FlashPtr;

FlashPtr=(char*)Addr;

FCTL1=FWKEY+ERASE;//SetErasebit

FCTL3=FWKEY;//ClearLockbit

DINT;

*FlashPtr=0;//DummywritetoeraseFlashsegmentB

WaitForEnable();//Busy

EINT;

FCTL1=FWKEY;//Lock

FCTL3=FWKEY+LOCK;//SetLockbit

}

这个和上面给出的流程一样,参数是要被擦除的段的首地址。

WaitForEnable函数等等待BUSY标志变回零即操作完成。

voidWaitForEnable()

{

while((FCTL3&BUSY)==BUSY);//Busy

}

写入字节:

voidFlashWriteChar(unsignedintaddr,charData)

{

char*FlashPtr=(char*)addr;//SegmentApointer

FCTL1=FWKEY+WRT;//SetWRTbitforwriteoperation

FCTL3=FWKEY;//ClearLockbit

DINT;

*FlashPtr=Data;//SaveData

WaitForEnable();//Busy

EINT;

FCTL1=FWKEY;//ClearWRTbit

FCTL3=FWKEY+LOCK;//SetLOCKbit

}

写入字:

voidFlashWriteWord(unsignedintaddr,unsignedintData)

{

unsignedint*FlashPtr=(unsignedint*)addr;

FCTL1=FWKEY+WRT;//SetWRTbitforwriteoperation

FCTL3=FWKEY;//ClearLockbit

DINT;

*FlashPtr=Data;//SaveData

WaitForEnable();//Busy

EINT;

FCTL1=FWKEY;//ClearWRTbit

FCTL3=FWKEY+LOCK;//SetLOCKbit

}

写入字或字节两个函数差别仅仅是指针类型不同。

读取字或字节:

charFlashReadChar(unsignedintAddr)

{

charData;

char*FlashPtr=(char*)Addr;

Data=*FlashPtr;

return(Data);

}

unsignedintFlashReadWord(unsignedintAddr)

{

unsignedintData;

unsignedint*FlashPtr=(unsignedint*)Addr;

Data=*FlashPtr;

return(Data);

}

这两个函数的差别也是仅仅指针类型不同。

这些函数和前面硬件介绍部分的程序流程相同,这里不再详细说明。

∙使用示例:

 

使用方法和之前的一样,工程中加入C文件,源代码文件中文件包含H文件,即可使用,具体参考示例项目:

演示主要程序主要如下:

#include

#include"Flash.h"

inta;

voidmain(void)

{

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

ClkInit();

FlashInit();

FlashWriteChar(InfoB,0x25);

a=FlashReadChar(InfoB);//InfoB在H文件中有宏定义

FlashWriteWord(InfoB+2,0x5669);

a=FlashReadWord(InfoB+2);

FlashErase(InfoB);

LPM0;

}

这里向InfoB(1000h)首地址开始写数据,先写一个字节再写入一个字(注意写入字时,必须是偶数地址,奇数地址会写在这个地址所在的前一个偶数地址),读出,然后擦除。

这里的程序都是在Flash中运行的,没有演示RAM中运行的程序。

如果在RAM运行程序,则需要先把程序从Fla

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1