MSP430G2553 flash操作例子

2024-03-26 20:08

本文主要是介绍MSP430G2553 flash操作例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/* 实际适用于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<SegSize;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:待写入的数据 
* 出口参数:返回出错信息  0:偏移溢出 ;1:正常工作 
* 范    例:Flash_Direct_WriteChar(0,123);将常数123写入0单元 Flash_Direct_WriteChar(1,a);将整型变量a写入1单元 
******************************************************************************************************/ 
char Flash_Direct_WriteChar (unsigned  int Addr,unsigned char Data) 
{ unsigned  int temp=0; unsigned char  *Ptr_SegAddr;                    //Segment  pointer //-----  段范围限定。为了内存管理安全,只允许本段操作----- if((SegPre<=31&&Addr>=512) ||(SegPre>31&&Addr>=64) ) return 0; temp = SegAddr+Addr; Ptr_SegAddr = (unsigned char *)temp;                //Initialize Flash  pointer FCTL1=FWKEY+WRT;            //正常写状态 FCTL3=FWKEY;              //解除锁定 
//  FCTL3=FWKEY+LOCKA;            //解除锁定(包括A段) _DINT();            //关总中断 *Ptr_SegAddr=Data;              //指定地址,写1字节 while(FCTL3&BUSY);            //等待操作完成 _EINT();            //开总中断 FCTL1=FWKEY;              //退出写状态 FCTL3=FWKEY+LOCK;            //恢复锁定,保护数据 
//  FCTL3=FWKEY+LOCK+LOCKA;        //恢复锁定,保护数据(包括A段) return 1; 
} 
/****************************************************************************************************** 
* 名    称:Flash_Direct_WriteWord() 
* 功    能:强行向Flash中写入一个字型变量,而不管存储位置是否事先擦除 
* 入口参数:Addr:存放数据的偏移地址,仍按字节计算,需为偶数 Data:待写入的数据 
* 出口参数:返回出错信息  0:偏移溢出 ;1:正常工作 
* 范    例:Flash_Direct_WriteWord(0,123);将常数123写入0单元 Flash_Direct_WriteWord(2,a);将整型变量a写入2单元 
******************************************************************************************************/ 
char Flash_Direct_WriteWord  (unsigned  int Addr,unsigned  int Data) 
{ unsigned  int temp=0; unsigned  int *Ptr_SegAddr;                       //Segment  pointer //-----  段范围限定。为了内存管理安全,只允许本段操作----- if((SegPre<=31&&Addr>=512) ||(SegPre>31&&Addr>=64) ) return 0; temp=SegAddr+Addr; Ptr_SegAddr = (unsigned  int *)temp;                 //Initialize Flash  pointer FCTL1=FWKEY+WRT;            //正常写状态 FCTL3=FWKEY;              //解除锁定 
//  FCTL3=FWKEY+LOCKA;            //解除锁定(包括A段) _DINT();            //关总中断 *Ptr_SegAddr=Data;              //写16位字 while(FCTL3&BUSY);            //等待操作完成 _EINT();            //开总中断 FCTL1=FWKEY;              //退出写状态 FCTL3=FWKEY+LOCK;            //恢复锁定,保护数据 
//  FCTL3=FWKEY+LOCK+LOCKA;        //恢复锁定,保护数据(包括A段) return 1; 
} 
/********************************************************************************************* ********* 
* 名    称:Flash_Bak_WriteChar() 
* 功    能:不破坏段内其他数据,向Flash中写入一个字节(Char型变量) 
* 入口参数:Addr:存放数据的地址 Data:待写入的数据 
* 出口参数:返回出错信息  0:偏移溢出 ;1:正常工作 
* 范    例:Flash_Bak_WriteChar(0,123);将常数123写入0单元 Flash_Bak_WriteChar(1,a);将变量a写入1单元 
******************************************************************************************************/  
char Flash_Bak_WriteChar (unsigned char Addr,unsigned  char Data) 
{ unsigned  int temp=0; unsigned char  *Ptr_SegAddr;                      //Segment  pointer unsigned char BackupArray[64];        //开辟64字节的临时RAM备份Seg unsigned char  i = 0; //-----  段范围限定。为了内存管理安全,只允许本段操作----- if((SegPre<=31&&Addr>=512) || (SegPre>31&&Addr>64) ) return 0; for(i=0;i<64;i++) { temp=SegAddr+i; Ptr_SegAddr = (unsigned char *)temp;           //Initialize Flash  pointer BackupArray[i]=*Ptr_SegAddr;        //指针移位方法赋值 } Flash_Erase();                 //擦除待操作段 FCTL1 = FWKEY + WRT;                           //正常写入(非块写) FCTL3 = FWKEY ;                                 //解锁 
//  FCTL3 = FWKEY ;                                  //解锁(含A段) for (i=0; i<64; i++) { _DINT();              //关总中断 if(i==Addr) { temp=SegAddr+Addr; Ptr_SegAddr = (unsigned char *)temp;            //Initialize Flash  pointer *Ptr_SegAddr =Data;                               //写数据 while(FCTL3&BUSY);                           //等待写操作完成 } else { temp=SegAddr+i; Ptr_SegAddr = (unsigned char *)temp;               //Initialize Flash  pointer *Ptr_SegAddr = BackupArray[i];                   //恢复Flash内的其他数据 while(FCTL3&BUSY);                               //等待写操作完成 } _EINT();                  //开总中断 } FCTL1 = FWKEY;                                  //清除写 FCTL3 = FWKEY + LOCK;                            //上锁 
//     FCTL3 = FWKEY + LOCK;                            //上锁(含A段) return 1; 
} 
/******************************************************************************************************  
* 名    称:Flash_Bak_WriteWord() 
* 功    能:不破坏段内其他数据,向Flash中写入一个字(int型变量) 
* 入口参数:Addr:存放数据的地址,仍然是以字节为单位的偏移地址,需为偶数 Data:待写入的数据 
* 出口参数:返回出错信息  0:偏移溢出 ;1:正常工作 
* 说    明:MSP430单片机可以对16位数据直接操作,所以为了加快速度 
*              函数中均直接对word进行操作。 
* 范    例:Flash_Bak_WriteWord(0,123);将常数123写入0单元 Flash_Bak_WriteWord(1,a);将变量a写入1单元 
******************************************************************************************************/ 
char Flash_Bak_WriteWord(unsigned int Addr,unsigned  int Data) 
{ unsigned  int *Ptr_SegAddr;                          //Segment  pointer Ptr_SegAddr = (unsigned  int *)SegAddr;               //Initialize Flash  pointer //-----注意:以下操作数全部为word16位数据类型----- unsigned  int BackupArray[32];          //开辟32字(64字节)的临时RAM备份Seg unsigned  int i = 0; //-----  段范围限定。为了内存管理安全,只允许本段操作----- if((SegPre<=31&&Addr>=512) ||(SegPre>31&&Addr>64) ) return 0; for(i=0;i<32;i++)                 //word型占两个字节 { BackupArray[i]= *(Ptr_SegAddr+i);           //指针移位方法对字赋值 } Flash_Erase();                    //擦除待操作段 FCTL1 = FWKEY + WRT;                            //正常写入(非块写) FCTL3 = FWKEY;                                  //解锁 
//     FCTL3 = FWKEY+LOCKA;                           //解锁  (含A段) for (i=0; i<32; i++)                      //word型占两个字节,需跳过奇数地址 { _DINT();               //关总中断 if(i==Addr) { *(Ptr_SegAddr+Addr) =Data;                 //写字型数据 while(FCTL3&BUSY);                              //等待写操作完成 } else { *(Ptr_SegAddr+i)= BackupArray[i];                    //恢复Flash内的其他数据,按字恢复 while(FCTL3&BUSY);                               //等待写操作完成 } _EINT();                //开总中断 } FCTL1 = FWKEY;                                  //清除写 FCTL3 = FWKEY + LOCK;                            //上锁 
//  FCTL3 = FWKEY + LOCK+LOCKA;                     //上锁(含LOCKA) return 1; 
} 
/******************************************************************************************************  
* 名    称:Flash_SegA_ReadChar() 
* 功    能:从InfoA中读取一个字节 
* 入口参数:Addr:存放数据的偏移地址 
* 出口参数:Data:读回的数据;偏移溢出时,返回 0 
* 说    明:无 
* 范    例:无 
******************************************************************************************************/ 
unsigned char Flash_SegA_ReadChar  (unsigned  int Addr) 
{ unsigned  int temp=0; unsigned char Data=0; //-----  段范围限定。为了内存管理安全,只允许本段操作----- if(Addr>=64) return 0; unsigned char  *Ptr_SegAddr;            //Segment  pointer temp = 0x10c0+Addr; Ptr_SegAddr = (unsigned char *)temp;     //Initialize Flash  pointer Data=*Ptr_SegAddr;                  //直接为InfoA首地址,未使用全局变量SegAddr return(Data); 
} unsigned char gTemp=0;
unsigned char gA;
void main()
{WDTCTL = WDTPW + WDTHOLD; //关狗   DCOCTL = CALDCO_8MHZ;                  // 先设DCO为8MHz BCSCTL1 = CALBC1_8MHZ;                        BCSCTL2 |= DIVM_1+DIVS_2;              // 2分频后到MCLK为4MHz ,4分频后到SMCLK为2MHzFlash_Init(6,'B' );                   //6分频后为333.3kHz,   操作B信息段gTemp=Flash_ReadChar(0);              //读取Flash_Bak_WriteChar (0,0x23);         //写入gTemp=Flash_ReadChar(0);              //再读取gA=gTemp;}

这篇关于MSP430G2553 flash操作例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/849707

相关文章

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Python使用DrissionPage中ChromiumPage进行自动化网页操作

《Python使用DrissionPage中ChromiumPage进行自动化网页操作》DrissionPage作为一款轻量级且功能强大的浏览器自动化库,为开发者提供了丰富的功能支持,本文将使用Dri... 目录前言一、ChromiumPage基础操作1.初始化Drission 和 ChromiumPage

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

Redis中管道操作pipeline的实现

《Redis中管道操作pipeline的实现》RedisPipeline是一种优化客户端与服务器通信的技术,通过批量发送和接收命令减少网络往返次数,提高命令执行效率,本文就来介绍一下Redis中管道操... 目录什么是pipeline场景一:我要向Redis新增大批量的数据分批处理事务( MULTI/EXE