历史上的今天
返回首页

历史上的今天

今天是:2025年03月29日(星期六)

2020年03月29日 | MSP430G2553 flash操作例子

2020-03-29 来源:eefocus

/* 实际适用于MSP430x2xx系列单片机,包含以下10个常用功能函数: 

(1)初始化。Flash_Init(unsigned char Div,unsigned char Seg ):依据SMCLK频率计算设定Flash的时钟的分频系数,靠Seg段号码确定计划操作的段起始地址。 

(2)整段擦除。Flash_Erase():段擦除函数。 

(3)读字节。Flash_ReadChar(unsigned int Addr):读取偏移地址Addr位置1个字节的数据。 

(4)读字。Flash_ReadWord(unsigned int Addr):读取偏移地址Addr位置1个字的数据。 

(5)读一串字节到RAM数组。Flash_ReadSeg(unsigned int Addr, unsigned int SegSize,char * Array):读取起始偏移地址为Addr,长度SegSize个字节数据到RAM的Array数组。 

(6)直接写1个字节。Flash_Direct_WriteChar(unsigned int Addr):直接写偏移地址Addr位置1个字节的数据。 

(7)直接写1个字。Flash_Direct_WriteWord(unsigned int Addr):直接写偏移地址Addr位置1个字的数据。 

(8)备份后写1字节。Flash_Bak_WriteChar(unsigned int Addr):先备份段内其他数据,擦写后,在偏移地址Addr位置写1个字节的数据,再还原段内其他数据。(仅限信息flash段,使用RAM备份) 

(9)备份后写1个字。Flash_Bak_WriteWord(unsigned int Addr):先备份段内其他数据,擦写后,在偏移地址Addr位置写1个字的数据,再还原段内其他数据。(仅限信息flash段,使用RAM备份)。 

(10)读SegA专用函数。Flash_SegA_ReadChar(unsigned int Addr):读取SegA段偏移地址Addr位置1个字节的数据。 


说明:  1、块写函数需要在RAM中调用函数指针来使用,本库函数未涉及 

        2、其他长字节的数据类型读写需使用结构体,本库函数未涉及 

        3、所有函数均针对无符号整型数据,如需使用有符号整型,需修改函数 

        4、对InfoA段单独处理,只有读字节函数Flash_SegA_ReadChar(),不提供擦写函数。 

        5、其他函数的段操作首地址SegAddr被Flash_Init()函数“限定”,不易发生误写 */ 


#include   "MSP430G2553.h" 

unsigned  int SegAddr=0;                        //全局变量 

unsigned  int SegPre=0;                         //全局变量  当前信息段 

/******************************************************************************************************  

* 名     称:Flash_Init() 

* 功       能:对Flash时钟进行初始化设置 

* 入口参数:Div:根据SMCLK频率计算的所需分频值,可设定为1-64 

*           选择原则: SMCLK分频后,落在257kHz~476kHz

*        Seg:段号,可设为"0"-"31"或”"A"、"B"、"C"、"D"。 

* 出口参数:1:配置成功 

*           0:配置失败 

* 说     明:操作Flash其他函数前,需要调用该初始化函数设置时钟分频和待操作段首地址。 

*            其他函数中均不出现绝对地址,防止误操作。 

* 范     例:  Flash_Init(3,'B' ) 3分频、对Info B段操作 

******************************************************************************************************/ 

unsigned char Flash_Init(unsigned  char Div,unsigned  char Seg ) 

  //-----设置Flash的时钟和分频,分频为恰好为最低位,直接用Div-1即可----- 

  if(Div<1) Div=1; 

  if(Div>64) Div=64; 

  FCTL2 = FWKEY + FSSEL_2 + Div-1;    //  默认使用SMCLK,分频系数参数传入 

  //-----操作对象为主Flash段的情况,可通过512的倍数设置段起始地址----- 

  SegPre = Seg;            //获取当前段 

  if (Seg <= 31)             //判断是否处于主Flash段 

    { 

    SegAddr=0xFFFF-(Seg+1)*512+1;         //计算段起始地址 

         return(1);                   //赋值成功后即可退出并返回成功标志”1“ 

    } 

  //-----操作对象为信息Flash段的情况,穷举即可----- 

  switch(Seg)                //判断是否处于信息Flash段 

  { 

  case  'A':  case'a':    SegAddr=0x10C0; break; 

  case  'B':  case'b':    SegAddr=0x1080; break; 

  case  'C':  case'c':    SegAddr=0x1040; break; 

  case  'D':  case'd':    SegAddr=0x1000; break; 

  default:    SegAddr=0x20FF;  return(0);       //0x20FF地址为空白区,保护Flash 

  } 

  return(1); 

/******************************************************************************************************  

* 名    称:Flash_Erase() 

* 功    能:擦除Flash的一个数据块,擦写段由初始化函数 Flash_Init()的SegAddr变量决定 

* 入口参数:无 

* 出口参数:无 

* 说    明:函数中给出了擦除InfoFlashA段的操作代码(已注释掉了),但不建议初学者使用。 

* 范    例:无 

******************************************************************************************************/ 

void Flash_Erase() 

   unsigned char  *Ptr_SegAddr;                     //Segment  pointer 

   Ptr_SegAddr = (unsigned char *)SegAddr;        //Initialize Flash  pointer 

   FCTL1 = FWKEY + ERASE;                       //段擦除模式 

   FCTL3 = FWKEY;                                  //解锁 

   //FCTL3 = FWKEY+LOCKA;                     //对InfoFlashA也解锁 

   _DINT(); 

   *Ptr_SegAddr = 0;                              //擦除待操作段 

   while(FCTL3&BUSY);                           //Busy 

   _EINT(); 

   FCTL1 = FWKEY;                                //取消擦模式 

   FCTL3 = FWKEY+LOCK;                          //上锁 

// FCTL3 = FWKEY+LOCK+LOCKA;              //对InfoFlashA也上锁 

/******************************************************************************************************  

* 名    称:Flash_ReadChar() 

* 功    能:从Flash中读取一个字节 

* 入口参数:Addr:存放数据的偏移地址 

* 出口参数:Data:读回的数据;当偏移溢出时返回0 

* 说    明:无 

* 范    例:无 

******************************************************************************************************/ 

unsigned char Flash_ReadChar  (unsigned  int Addr) 

   unsigned char Data=0; 

   unsigned  int *Ptr_SegAddr,temp=0;                       //Segment  pointer 

   //-----  段范围限定。为了内存管理安全,只允许本段操作----- 

   if((SegPre<=31&&Addr>=512) ||(SegPre>31&&Addr>=64) ) 

     return 0; 

   temp =SegAddr+Addr; 

   Ptr_SegAddr =(void*)temp;                     //initialize Flash  pointer 

   Data=*(Ptr_SegAddr); 

   return(Data); 

/******************************************************************************************************  

* 名    称:Flash_ReadWord() 

* 功    能:从FlashROM读回一个整型变量,地址应为偶数 

* 入口参数:Addr:存放数据的偏移地址,仍按字节计算,需为偶数 

* 出口参数:Data:读回的整型变量值  ;当偏移溢出时返回0 

* 说    明:无 

* 范    例:无 

******************************************************************************************************/ 

unsigned  int Flash_ReadWord (unsigned  int Addr) 

   unsigned  int *Ptr_SegAddr; 

   unsigned  int temp=0,Data=0;                             //Segment  pointer 

   //-----  段范围限定。为了内存管理安全,只允许本段操作----- 

   if((SegPre<=31&&Addr>=512) ||(SegPre>31&&Addr>=64) ) 

     return 0; 

   temp = SegAddr+Addr; 

     Ptr_SegAddr = (void  *)temp;                  //Initialize Flash pointer 

   Data=*(Ptr_SegAddr); 

   return(Data); 

/******************************************************************************************************  

* 名    称:Flash_ReadSeg() 

* 功    能:将Flash段内一串数据拷贝到RAM的Array数组 

* 入口参数:Addr:起始偏移地址 

*          SegSize:数据个数 

*          *Array:RAM中数组的头指针 

* 出口参数:返回出错信息  0:偏移溢出 ;1:正常工作 

* 说    明:无 

* 范    例:无 

******************************************************************************************************/ 

char Flash_ReadSeg(unsigned  int Addr, unsigned  int SegSize,unsigned char * Array) 

  unsigned  int i=0,temp=0; 

  unsigned char  *Ptr_SegAddr;                        //Segment  pointer 

     //-----  段范围限定。为了内存管理安全,只允许本段操作----- 

  if((SegPre<=31&&(Addr+SegSize)>512) ||(SegPre>31&&(Addr+SegSize)>64) ) 

     return 0; 

  for(i=0;i  { 

    temp=SegAddr+Addr+i;             //防止编译器处理指针偏移出错 

    Ptr_SegAddr = (unsigned char *)temp;             //Initialize Flash  pointer 

    Array[i]=*Ptr_SegAddr;            //指针移位方法赋值 

  } 

     return 1; 

/******************************************************************************************************  

* 名    称:Flash_Direct_WriteChar() 

* 功    能:强行向Flash中写入一个字节(Char型变量),而不管是否为空 

* 入口参数:Addr:存放数据的偏移地址 

            Data:待写入的数据 

推荐阅读

史海拾趣

Astro Industries Inc公司的发展小趣事

Astro Industries Inc的创始人在电子行业拥有丰富的经验,他们看到了市场对于高性能电子产品的迫切需求。于是,公司从创立之初就专注于技术创新,投入大量资源进行研发。经过不懈的努力,Astro Industries Inc成功推出了一款具有颠覆性的电子产品,其性能远超当时市场上的同类产品,迅速获得了市场的认可。

Baumer Electric Ag公司的发展小趣事

Baumer Electric Ag公司创立于1952年,初期主要专注于微动开关的生产。面对市场竞争的激烈,公司创始人Herbert Baumer凭借其敏锐的市场洞察力和坚定的决心,带领团队不断研发新产品,提升技术水平。1960年,公司成功推出首个程序控制系列,标志着Baumer在电控生产流程监控和控制领域取得了重要突破。

微芯(CMOSIC)公司的发展小趣事

随着全球化的加速发展,微芯生物也积极开展国际合作与交流。他们与国际知名医药企业、科研机构以及高校建立了紧密的合作关系,共同开展新药研发和技术创新。通过国际合作与交流,微芯生物不仅吸收了国际先进的研发理念和技术经验,还为公司的发展带来了更广阔的市场空间和合作机会。

Electro-Term/Hollingsworth公司的发展小趣事

面对全球电子市场的不断变化,Electro-Term公司及时调整了市场布局和战略方向。公司深入分析了不同地区的市场需求和消费者偏好,制定了有针对性的市场推广策略。同时,公司还加强了与国际知名企业的合作,共同开发新技术和产品。这些努力使Electro-Term在全球市场上取得了显著的成绩。

Ericsson公司的发展小趣事

Ericsson公司始终将创新作为企业发展的核心动力。从早期生产电话机、电话交换机到今天提供端到端全面通信解决方案以及专业服务,Ericsson不断定义电信行业“进步”的含义,并通过实现每一个“进步”引领全球电信业的技术发展与变革。特别是在移动通信领域,Ericsson一直处于领先地位,为全球所有主要移动通信标准提供设备和服务。

德艺隆(DEALON)公司的发展小趣事

德艺隆自创立之初,就专注于电子开关、插座和连接器的研发与生产。在创始人陈建新的带领下,公司聚集了一批从业多年的设计开发、生产管理等技术人员。他们日夜兼程,不断攻克技术难关,逐渐在行业内树立了技术领先的地位。一次,公司接到一个要求极高精度的连接器订单,技术人员经过反复试验,最终成功研发出符合要求的连接器,赢得了客户的赞誉,也为公司赢得了更多的市场份额。

问答坊 | AI 解惑

基于单片机的电子密码锁实际设计

基于单片机的电子密码锁实际设计…

查看全部问答>

MMU地址映射表问题!

目前在做一个SRAM驱动,写成的是流驱动,驱动写好了! 但是在做MMU地址映射表时出问题了!具体如下: 原来的g_oalAddressTable[DATA] 表为 g_oalAddressTable         DCD     0x80000000, ...…

查看全部问答>

Pos机的原理,用什么语言开发?C#?Java?

公司交给我让我先了解下pos机,但是我对Pos机一点不了解,公司做的pos机是和银行没有关系的。就是给本公司的会员使用 想问下大虾: 1:Pos机的相关硬件有什么设备 2:用什么语言开发,能运行到什么系统,是否认能兼容 3:软硬件两者怎么相互嵌 ...…

查看全部问答>

SD WiFi 插拔之后工作不正常(Wince 5.0) Urgent

SD WiFi在首次插入后均可以与指定AP(Access Point)成功连接,后经过一次拔插后,就无法工作了,只有重新系统才可以。经Trace log可知,无法得到BSSI List,其列表为空,由此可知,WiFi Adapter处于异常状态,至今没有找到具体原因,曾试过NdisReset ...…

查看全部问答>

STM32 ,用固件库写一个流水灯的程序需要哪些库?

STM32 ,用固件库写一个流水灯的程序需要哪些库?我知道肯定要用GPIO,RCC要用到USART,NVIC吗?为什么啊? 初学者求助…

查看全部问答>

方法和技术——《使用2790型数字源表开关系统测试双安全气囊充气机模块》

机械臂接口 – 数字I/O 2790内置的数字接口能够直接控制器件机械臂。数字接口包含五路TTL兼容数字输出和两路输入,以及外部供电的继电器和地线连接。五路输出提供测试通过/失败通知。可以定义两个上限和两个下限用于任何数字万用表测试。每个测 ...…

查看全部问答>

有谁用过CC430及CC1111的吗?

本帖最后由 paulhyde 于 2014-9-15 03:39 编辑 有谁用过CC430及CC1111的吗?有没有相关的资料,最好是中文的  …

查看全部问答>

求教FPGA程序JTAG及AS口加载问题

今天调新板子,程序从JTAG和AS口都下不进去,且提示不同。 加载JTAG,程序烧到48%,出ERROR:  CFG_DONE pin failed to go high. 用万用表测,CFG_DONE 角经电阻10K接到3.3V,且 CFG_nCE 已接地。 换成AS口,在选择目标POF文件时就出错 ...…

查看全部问答>

出售二手书,价格好商量,联系qq972758172

出售二手书,价格好商量,联系qq972758172 …

查看全部问答>