STM32F4 内部flash驱动(寄存器操作)

发布者:Jinyu521最新更新时间:2019-07-11 来源: eefocus关键字:STM32F4  内部flash驱动  寄存器操作 手机看文章 扫描二维码
随时随地手机看文章

stm32f4_flash.c


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

 * 文件名: stm32f4_flash.c

 * 功能: STM32F4 内部FLASH编程驱动函数

 * 作者: cp1300@139.com

 * 创建时间: 2013-10-20

 * 最后修改时间: 2018-01-13

 * 详细: 用于STM32F4内部flash读写驱动

2018-01-13:初始版本,默认位宽为32位,写入的数据必须32位对齐,供电必须在2.7-3.6V之间,建议使用3.3V供电

2018-01-16:修复扇区擦除时没有解锁问题

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

#include "stm32f4_flash.h"

#include "system.h"

 

//FLASH 扇区的起始地址

#define ADDR_FLASH_SECTOR_0     ((u32)0x08000000) //扇区0起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_1     ((u32)0x08004000) //扇区1起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_2     ((u32)0x08008000) //扇区2起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_3     ((u32)0x0800C000) //扇区3起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_4     ((u32)0x08010000) //扇区4起始地址, 64 Kbytes  

#define ADDR_FLASH_SECTOR_5     ((u32)0x08020000) //扇区5起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_6     ((u32)0x08040000) //扇区6起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_7     ((u32)0x08060000) //扇区7起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_8     ((u32)0x08080000) //扇区8起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_9     ((u32)0x080A0000) //扇区9起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_10    ((u32)0x080C0000) //扇区10起始地址,128 Kbytes  

#define ADDR_FLASH_SECTOR_11    ((u32)0x080E0000) //扇区11起始地址,128 Kbytes  

 

 

 

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

* 函数 : void STM32FLASH_Unlock(void)

* 功能 : 解锁STM32的FLASH

* 参数 : 无

* 返回 : 无

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2013-10-20

* 说明 :

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

void STM32FLASH_Unlock(void)

{

FLASH->KEYR=FLASH_KEY1; //写入解锁序列.

FLASH->KEYR=FLASH_KEY2;

}

 

 

 

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

* 函数 : void STM32FLASH_Lock(void)

* 功能 : 上锁STM32的FLASH

* 参数 : 无

* 返回 : 无

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2018-01-13

* 说明 :

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

void STM32FLASH_Lock(void)

{

FLASH->CR|=(u32)1<<31; //上锁

}

 

 

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_GetStatus(void)

* 功能 : 得到FLASH状态

* 参数 : 无

* 返回 : STM32FLASH_STATUS

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2018-01-03

* 说明 :

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

STM32FLASH_STATUS STM32FLASH_GetStatus(void)

{

u32 temp=FLASH->SR; 

if(temp&(1<<16))return STM32FLASH_BUSY; //忙

else if(temp&(1<<4))return STM32FLASH_WPRERR; //写保护错误

else if(temp&(1<<5))return STM32FLASH_PGAERR; //编程对齐错误

else if(temp&(1<<6))return STM32FLASH_PGPERR; //并行位数错误

else if(temp&(1<<7))return STM32FLASH_PGSERR; //编程顺序错误

return STM32FLASH_OK; //操作完成

}

 

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)

* 功能 : 等待操作完成

* 参数 : time:要延时的长短,单位us

* 返回 : STM32FLASH_STATUS

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2018-01-03

* 说明 :

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

STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)

{

STM32FLASH_STATUS status;

if(time < 1) time = 1;

do

{

status=STM32FLASH_GetStatus(); //获取状态

if(status!=STM32FLASH_BUSY)break; //非忙,无需等待了,直接退出.

Delay_US(1);

time--;

}while(time);

 

return status;

}

 

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)

* 功能 : 扇区擦除

* 参数 : sectoraddr:扇区地址,0-11

* 返回 : STM32FLASH_STATUS

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2018-01-03

* 最后修改时间 : 2018-01-03

* 说明 : 扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区

128KB扇区擦除足最大2秒

2018-01-16:修复扇区擦除时没有解锁问题

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

STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)

{

STM32FLASH_STATUS status;

status=STM32FLASH_WaitDone(200000); //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过

STM32FLASH_Unlock(); //解锁 

if(status==STM32FLASH_OK) //没有错误

FLASH->CR&=~(3<<8); //清除PSIZE原来的设置

FLASH->CR|=2<<8; //设置为32bit宽,确保VCC=2.7~3.6V之间!!

FLASH->CR&=~(0X1F<<3); //清除原来的设置

FLASH->CR|=sectoraddr<<3; //设置要擦除的扇区 

FLASH->CR|=1<<1; //扇区擦除 

FLASH->CR|=1<<16; //开始擦除

status=STM32FLASH_WaitDone(200000); //等待操作结束,最大2s  

if(status!=STM32FLASH_BUSY) //非忙

{

FLASH->CR&=~(1<<1); //清除扇区擦除标志.

}

}

STM32FLASH_Lock(); //上锁

return status; //返回状态

}

 

 

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_WriteWord(u32 addr, u32 data)

* 功能 : 在FLASH指定地址写入一个字的数据(32bit写入)

* 参数 : faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据

* 返回 : STM32FLASH_STATUS

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2018-01-03

* 最后修改时间 : 2018-01-03

* 说明 : 警告,地址必须为4的倍数

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

STM32FLASH_STATUS STM32FLASH_WriteWord(u32 faddr, u32 data)

{

STM32FLASH_STATUS status;

status=STM32FLASH_WaitDone(200); //判断状态

if(status==STM32FLASH_OK) //没有错误

{

FLASH->CR&=~(3<<8); //清除PSIZE原来的设置

FLASH->CR|=2<<8; //设置为32bit宽,确保VCC=2.7~3.6V之间!!

  FLASH->CR|=1<<0; //编程使能

*(vu32*)faddr=data; //写入数据

status=STM32FLASH_WaitDone(200); //等待操作完成,一个字编程,最多100us.

if(status!=STM32FLASH_BUSY) //非忙

{

FLASH->CR&=~(1<<0); //清除PG位.

}

return status;

 

 

 

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

* 函数 : u32 STM32FLASH_ReadWord(u32 faddr)

* 功能 : 读取指定地址的一个字(32位数据) 

* 参数 : faddr:指定地址(此地址必须为4的倍数!!);

* 返回 : 数据

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2018-01-03

* 最后修改时间 : 2018-01-03

* 说明 : 警告:地址必须是4的整数倍

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

u32 STM32FLASH_ReadWord(u32 faddr)

{

return *(vu32*)faddr; 

}

 

 

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

* 函数 : u8 STM32FLASH_GetFlashSector(u32 faddr)

* 功能 : 获取某个地址所在的扇区

* 参数 : faddr:指定地址

* 返回 : 删除编号,0-11,如果超出了也会限制到11

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2018-01-03

* 最后修改时间 : 2018-01-03

* 说明 : 地址请不要超出范围

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

u8 STM32FLASH_GetFlashSector(u32 faddr)

{

if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else if(faddr else return 11;

}

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  

* 功能 : 不检查的写入

* 参数 : WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数 

* 返回 : 状态

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2018-01-03

* 说明 : 地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)

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

STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   

{  

u16 i;

STM32FLASH_STATUS status;

if(WriteAddr STM32FLASH_Unlock(); //解锁 

for(i=0;i {

status = STM32FLASH_WriteWord(WriteAddr,pBuffer[i]);

if(status != STM32FLASH_OK) break; //写入出错,直接返回

    WriteAddr+=4; //地址增加4.

}

STM32FLASH_Lock(); //上锁

return status;

 

 

 

 

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

* 函数 : STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)

* 功能 : 从指定地址开始写入指定长度的数据(数据长度字为单位)

* 参数 : WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)

* 返回 : 0:完成;1:忙;2:错误;3:写保护

* 依赖 : 底层

* 作者 : cp1300@139.com

* 时间 : 2013-10-20

* 最后修改时间 : 2016-01-07

* 说明 : 警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据

[1] [2]
关键字:STM32F4  内部flash驱动  寄存器操作 引用地址:STM32F4 内部flash驱动(寄存器操作)

上一篇:STM32开发笔记46:STM32F0低功耗设计
下一篇:怎样用STM32 中的 I2C读写EEPROM(二)

推荐阅读最新更新时间:2024-11-10 06:54

stm32f407之基本定时器TIM6&TIM7(操作寄存器
基本定时器TIM6和TIM7包括一个由可编程分频器驱动的16位自动重载计数器。它可以用作普通的定时器,也可以用来驱动DAC。这两个定时器是完全独立的,不共享任何资源。更多时候是与DAC平配合使用。 作为定时器的配置步骤: 1.设置中断优先级分组(如果之前没有设置),这个最好一个程序里只在开头设置一次。 2.使能相关时钟。 3.设置分频。 4.清空计数器的值。 5.设置自动重装寄存器的值。 6.是否允许中断。 7.如果允许中断,设置中断优先级,使能中断。 8.使能计数器。 程序: /************************************ 标题:定时器TIM7
[单片机]
STM32学习之:STM32F4XX的三大主体部分
三大模块:电源、IO口、时钟。 一、 首先,我们来看一下电源,下面是电源框图 从上面我们可以看出,电源给内部的三大关键部分供电,一是给ADC供电,这块无需多说,二是电池备份域,VBAT引脚可以连接到一个可选的待机电压由电池供电或由另一个来源,当V DD是断开时保留的备份寄存器的内容和供给的RTC。还一部分主要用来给数字逻辑部分供电,像唤醒逻辑、看门狗、IO等,给内核、内存和数字外设的供电需要在VDD之后加上一个电压调整器。 接下来介绍的就是低功耗模式了 默认情况下,微控制器是在运行模式后,一个系统或一个上电复位。在运行模式的CPU的时钟HCLK和程序代码执行,一些低功耗模式是可用的,以节省电力时,不需要保持运行的中央处理器
[单片机]
第11章 STM32F429移植SEGGER的硬件异常分析
11.1 初学者重要提示 MDK本身也是支持硬件异常分析的,就是不够直观,此贴是MDK的硬件异常分析文档:http://www.armbbs.cn/forum.php?mod=viewthread&tid=21940 。 IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。 11.2 移植方法 直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。 MDK版本移植 源文件位于本章配套例子的UserseggerHardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。 IAR版本移植 源文件位于本章配套例子的Userseg
[单片机]
第11章 <font color='red'>STM32F4</font>29移植SEGGER的硬件异常分析
STM32F4 USART1 TX RX FIFO
USART1 TX RX FIFO /* ********************************************************************************************************* * * 模块名称 : 串口驱动模块 * 文件名称 : bsp_uart.c * 版 本 : V1.0 * 说 明 : 实现printf和scanf函数重定向到串口1,即支持printf信息到USART1 * 实现重定向,只需要添加2个函数: * int fputc(int ch, FILE *f); * int fgetc(FILE
[单片机]
STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(寄存器操作
依然,直接上代码 #include stm32f0xx.h #include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_gpio.h int main(void) { //IOPAEN=1,使能GPIOA的时钟 RCC- AHBENR |= RCC_AHBENR_GPIOAEN; //设置IO口工作模式,GPIOA_MODER4=0x01,通用IO口 GPIOA- MODER |= GPIO_MODER_MODER4_0; GPIOA- MODER &= ~GPIO_MODER_MODER4_1; /
[单片机]
STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(<font color='red'>寄存器</font><font color='red'>操作</font>版
stm32F407+ov7670的摄像头识别
单片机源程序如下: #include system.h #include SysTick.h #include led.h #include usart.h #include tftlcd.h #include malloc.h #include sdio_sdcard.h #include flash.h #include ff.h #include fatfs_app.h #include key.h #include font_show.h #include exti.h #include time.h #include string.h #include math.h
[单片机]
<font color='red'>stm32F4</font>07+ov7670的摄像头识别
STM32F407高速USB口速度测试
STM32F407高速USB口速度测试 1, 高速USB口,直接接USB3.0 U盘,金士顿DataTraveler G4,16G。读写文件长度3226157571字节。XP32系统。固件使用HS Device下的DualCore。 l 文件拷贝到U盘,用时3分钟。平均速度17.9MB/s=143Mbit/s l 从U盘拷出,用时2分钟。平均速度26.9MB/s=215Mbit/s l 文件从C盘拷贝,粘贴,用时2分钟。 可以看出,此时读写U盘已经是最大速度,这跟整个系统、U盘都有关系。USB操作应该没有经过MCU处理,直接用的USB缓冲区。 2, 高速USB口,连SD卡(大卡)
[单片机]
STM32 | STM32F429的USB有坑?
最近某项目需要用到USB与CAN: 拿到这样的需求,我们当然是先得保证通讯正常。于是我找了一个USB例程与一个CAN例程,分别调试验证。 经过几番折腾已经保证了USB与上位机能正常通讯了,也能保证了CAN的正常收发(拿了两块开发板做验证)。 两头都没有问题了,再加上一些数据处理就差不多完成了。USB与CAN我都是第一次用,没想到那么顺利,美滋滋,正准备放松的时候,问题就来了。这是一个整体的东西,最终都要把这两部分集合起来吧。 我把CAN工程里关于CAN的部分移到USB工程里,这时候CAN竟然用不了了。这时候我就开始在怀疑自己是不是手贱误删了哪里了,于是重新来一遍,发现还是不行。 查了代码很久也没找出什么错误了,
[单片机]
STM32 | <font color='red'>STM32F4</font>29的USB有坑?
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved