定义一个全局变量数组:
const u8 TEXT_Buffer[]={"STM32F103 FLASH TEST"};    //u8和char* 写入到内存里会有什么区别???????不都是0101吗,难道一个元素占的位置大小不同?????

#define SIZE sizeof(TEXT_Buffer)                        //数组长度 sizeof是一个函数 ,函数的作用是求出括号里参数的长度
#define FLASH_SAVE_ADDR  0X08070000        //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)

然后建立一个.h文档

#ifndef __STMFLASH_H__
#define __STMFLASH_H__
#include "sys.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////
//用户根据自己的需要设置
#define STM32_FLASH_SIZE 512              //所选STM32的FLASH容量大小(单位为K)
#define STM32_FLASH_WREN 1              //使能FLASH写入(0,不是能;1,使能)
//////////////////////////////////////////////////////////////////////////////////////////////////////

//FLASH起始地址
#define STM32_FLASH_BASE 0x08000000     //STM32 FLASH的起始地址
//FLASH解锁键值

u16 STMFLASH_ReadHalfWord(u32 faddr);                                                    //读出半字  
void STMFLASH_WriteLenByte(u32 WriteAddr,u32 DataToWrite,u16 Len);     //指定地址开始写入指定长度的数据
u32 STMFLASH_ReadLenByte(u32 ReadAddr,u16 Len);                                //指定地址开始读取指定长度数据
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite);            //从指定地址开始写入指定长度的数据
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead);           //从指定地址开始读出指定长度的数据

//测试写入
void Test_Write(u32 WriteAddr,u16 WriteData);                                   
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////

然后再建一个.c文件

#include "stmflash.h"
#include "delay.h"
#include "usart.h"

//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 STMFLASH_ReadHalfWord(u32 faddr)
{
    return *(vu16*)faddr;
}
#if STM32_FLASH_WREN    //如果使能了写   
//不检查的写入
//WriteAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数   
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
{                      
    u16 i;
    for(i=0;i<NumToWrite;i++)
    {
        FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
        WriteAddr+=2;//地址增加2.
    }  
}
//从指定地址开始写入指定长度的数据
//WriteAddr:起始地址(此地址必须为2的倍数!!)
//pBuffer:数据指针
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
#if STM32_FLASH_SIZE<256
#define STM_SECTOR_SIZE 1024 //字节
#else
#define STM_SECTOR_SIZE    2048
#endif        
u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)    
{
    u32 secpos;       //扇区地址
    u16 secoff;       //扇区内偏移地址(16位字计算)
    u16 secremain; //扇区内剩余地址(16位字计算)       
     u16 i;    
    u32 offaddr;   //去掉0X08000000后的地址
    if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
    FLASH_Unlock();                        //解锁
    offaddr=WriteAddr-STM32_FLASH_BASE;        //实际偏移地址.
    secpos=offaddr/STM_SECTOR_SIZE;            //扇区地址  0~127 for STM32F103RBT6
    secoff=(offaddr%STM_SECTOR_SIZE)/2;        //在扇区内的偏移(2个字节为基本单位.)
    secremain=STM_SECTOR_SIZE/2-secoff;        //扇区剩余空间大小   
    if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
    while(1)
    {    
        STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
        for(i=0;i<secremain;i++)//校验数据
        {
            if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除        
        }
        if(i<secremain)//需要擦除
        {
            FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
            for(i=0;i<secremain;i++)//复制
            {
                STMFLASH_BUF[i+secoff]=pBuffer[i];      
            }
            STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区  
        }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                    
        if(NumToWrite==secremain)break;//写入结束了
        else//写入未结束
        {
            secpos++;                //扇区地址增1
            secoff=0;                //偏移位置为0     
               pBuffer+=secremain;      //指针偏移
            WriteAddr+=secremain;    //写地址偏移       
               NumToWrite-=secremain;    //字节(16位)数递减
            if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
            else secremain=NumToWrite;//下一个扇区可以写完了
        }    
    };    
    FLASH_Lock();//上锁
}
#endif

//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)       
{
    u16 i;
    for(i=0;i<NumToRead;i++)
    {
        pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
        ReadAddr+=2;//偏移2个字节.    
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//WriteAddr:起始地址
//WriteData:要写入的数据
void Test_Write(u32 WriteAddr,u16 WriteData)       
{
    STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
}

flash stm32的flash编写的更多相关文章

  1. STM32的Flash

    STM32中存储区分为:随机存取存储器RAM和只读存储器ROM. 其中: RAM为常说的内存,比如手机的2G内存4G内存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失. ROM为常说的硬 ...

  2. 关于STM32的FLASH操作【转载】

    说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置.芯片ID.自举程序等等.当然, FLASH还可以用来装数据. FLASH分 ...

  3. Nand Flash,Nor Flash,CFI Flash,SPI Flash 之间的关系

    前言:    在嵌入式开发中,如uboot的移植,kernel的移植都需要对Flash 有基本的了解.下面细说一下标题中的中Flash中的关系 一,Flash的内存存储结构    flash按照内部存 ...

  4. nor flash和nand flash的区别

    NOR和NAND是现在市场上两种主要的非易失闪存技术.Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面.紧接着,1989年,东芝公司发表了 ...

  5. (三)NAND flash和NOR flash的区别详解

    我们使用的智能手机除了有一个可用的空间(如苹果8G.16G等),还有一个RAM容量,很多人都不是很清楚,为什么需要二个这样的芯片做存储呢,这就是我们下面要讲到的.这二种存储设备我们都统称为“FLASH ...

  6. NAND flash和NOR flash的区别详解

    我们使用的智能手机除了有一个可用的空间(如苹果8G.16G等),还有一个RAM容量,很多人都不是很清楚,为什么需要二个这样的芯片做存储呢,这就是我们下面要讲到的.这二种存储设备我们都统称为“FLASH ...

  7. NOR FLASH与NAND FLASH

    整理自NOR FLASH 与NAND FLASH 1:NandFlash与NorFlash典型电路图 Nor Flash接原理图 从上图可以看出,该NorFlash采用并行地址和数据总线, 其中,21 ...

  8. NOR flash和NAND flash区别,RAM 和ROM区别

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  9. NOR flash和NAND flash区别,RAM 和ROM区别d

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

随机推荐

  1. IntelliJ IDEA 中如何配置多个jdk版本即(1.7和1.8两个jdk都可用)

    IntelliJ IDEA使用教程 (总目录篇) 有时候需要看Java源码,但是 Java 1.7 和 Java 1.8的差别的关系,有时候你想查看不同jdk版本的Java源码. 或者你的项目需要测试 ...

  2. 一起talk C栗子吧(第三十四回:C语言实例--巧用溢出计算最值)

    各位看官们.大家好,上一回中咱们说的是巧用移位的样例,这一回咱们说的样例是:巧用溢出计算最值. 闲话休提,言归正转.让我们一起talk C栗子吧! 大家都知道,程序中的变量都有一个取值范围,这个范围也 ...

  3. makeMtk- user 版本编译

    有时候我们需要在我们的手机上编译user 版本,先说一下user 跟eng版本的区别 user:这个版本是没有root权限的,当你adb shell进入后,linux下显示的是$,不可以push ap ...

  4. golang sync.WaitGroup

    //阻塞,直到WaitGroup中的所以过程完成. import ( "fmt" "sync" ) func wgProcess(wg *sync.WaitGr ...

  5. Vue的学习--怎么在vue-cli中写网页

    vue.min.js和vue-cli的区别和联系我现在还是没有太清楚,大概是还没搞清楚export default和new Vue的区别,先浅浅记录一下怎么“用vue-cli来写网页”. “vue-c ...

  6. hdu4605Magic Ball Game 树状数组

    //给一棵树.树的每个节点的子节点个数是0或2 //对于每个节点都有一个权值w[i] //一个权值为x的球在每个节点的情况有 //x=w[i] 这个球在该点不向下掉 //x<w[i] 这个球往左 ...

  7. 为什么在AJAX里面直接return 一个值,接受不到?

    1.AJAX是异步执行流程,后面的代码可能会先一步执行.把异步改为同步. 2.JS函数作用域问题,现在外面声明一个全局变量,等success后再把值给变量,这样就可以return 值了.

  8. 00092_字符输出流Writer

    1.字符输出流Writer (1)既然有专门用于读取字符的流对象,那么肯定也有写的字符流对象: (2)查阅API,发现有一个Writer类,Writer是写入字符流的抽象类.其中描述了相应的写的动作. ...

  9. JSP语法基础(一)

    一.JSP页面中的凝视 (1)HTML凝视 <!-- comment [ <%=expression %> ] --> 能在client显示的一种凝视,标记内的全部JSP脚本元 ...

  10. 字符串中的空格替换问题(Java版)

    解决方式一:时间复杂度为O(n^2) 解决方式二:时间复杂度为O(n) 代码实现: package string; public class SpaceStringReplace2 { //len为数 ...