datasheet

基于STM32F407 HAL库的Flash编程操作

2019-05-24来源: eefocus关键字:STM32F407  HAL库  Flash  编程操作

flash的初始化,解锁flash和清除一些flash的异常状态标识


uint16_t MEM_If_Init_FS(void) 

{

 

    HAL_FLASH_Unlock(); 

    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 

                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

 

}

uint16_t MEM_If_DeInit_FS(void) 

{

    HAL_FLASH_Lock();

}

 

flash 的檫除操作


uint16_t MEM_If_Erase_FS(uint32_t start_Add,uint32_t end_Add)

{

    /* USER CODE BEGIN 3 */

    uint32_t UserStartSector;

    uint32_t SectorError;

    FLASH_EraseInitTypeDef pEraseInit;

 

    /* Unlock the Flash to enable the flash control register access *************/

    MEM_If_Init_FS();

 

    /* Get the sector where start the user flash area */

    UserStartSector = GetSector(start_Add);

 

    pEraseInit.TypeErase = TYPEERASE_SECTORS;

    pEraseInit.Sector = UserStartSector;

    pEraseInit.NbSectors = GetSector(end_Add)-UserStartSector+1 ;

    pEraseInit.VoltageRange = VOLTAGE_RANGE_3;

 

    if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)

    {

        /* Error occurred while page erase */

        return (1);

    }

 

    return (USBD_OK);

    /* USER CODE END 3 */

}

擦除操作,先解锁,然后清空所需flash所在sector。注意这里的sector使用GetSector()函数获取的,是一个整型数字(对于F4就是0~11)。

其中的NbSectors是需要清除的sector的个数。

 



下面是获取sector的编号

我们先按照用户手册上写的在文件usbd_dfu_if.h中define一些需要用到的sector起始地址


#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbyte */

#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbyte */

#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbyte */

#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbyte */

#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbyte */

#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbyte */

#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbyte */

#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbyte */

#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbyte */

#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbyte */

#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbyte */

#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbyte */


再在usbd_dfu_if.c文件末尾添加函数:


/**

  * @brief  Gets the sector of a given address

  * @param  Address: Flash address

  * @retval The sector of a given address

  */

static uint32_t GetSector(uint32_t Address)

{

  uint32_t sector = 0;

  

  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))

  {

    sector = FLASH_SECTOR_0;  

  }

  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))

  {

    sector = FLASH_SECTOR_1;  

  }

  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))

  {

    sector = FLASH_SECTOR_2;  

  }

  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))

  {

    sector = FLASH_SECTOR_3;  

  }

  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))

  {

    sector = FLASH_SECTOR_4;  

  }

  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))

  {

    sector = FLASH_SECTOR_5;  

  }

  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))

  {

    sector = FLASH_SECTOR_6;  

  }

  else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))

  {

    sector = FLASH_SECTOR_7;  

  }

  else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))

  {

    sector = FLASH_SECTOR_8;  

  }

  else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))

  {

    sector = FLASH_SECTOR_9;  

  }

  else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))

  {

    sector = FLASH_SECTOR_10;  

  }

  else

  {

    sector = FLASH_SECTOR_11;  

  }

 

  return sector;

}

 


flash写入操作


uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len)

{

    /* USER CODE BEGIN 3 */

    uint32_t i = 0;

 

    for(i = 0; i < Len; i+=4)

    {

        /* Device voltage range supposed to be [2.7V to 3.6V], the operation will

           be done by byte */

        if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(dest+i), *(uint32_t*)(src+i)) == HAL_OK)

        {

            /* Check the written value */

            if(*(uint32_t *)(src + i) != *(uint32_t*)(dest+i))

            {

                /* Flash content doesn't match SRAM content */

                return 2;

            }

        }

        else

        {

            /* Error occurred while writing data in Flash memory */

            return 1;

        }

    }

    return (HAL_OK);

    /* USER CODE END 3 */

}

flash读出操作


uint8_t *MEM_If_Read_FS (uint8_t *src, uint8_t *dest, uint32_t Len)

{

    /* Return a valid address to avoid HardFault */

    /* USER CODE BEGIN 4 */

    uint32_t i = 0;

    uint8_t *psrc = src;

 

    for(i = 0; i < Len; i++)

    {

        dest[i] = *psrc++;

    }

    return HAL_OK;

 

    /* USER CODE END 4 */

}


关键字:STM32F407  HAL库  Flash  编程操作

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic462830.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:IAR中设置了中断向量偏移时进行仿真的注意事项
下一篇:STM32F407各定时器的时钟频率

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F4定时器时钟频率和时钟源

从时钟树中我们可以得知(1)高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11的时钟来源是APB2总线(2)通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7的时钟来源是APB1总线从STM32F4的内部时钟树可知,(1)当APB1和APB2分频数为1的时候,TIM1、TIM8~TIM11的时钟为APB2的时钟,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟;(2)而如果APB1和APB2分频数不为1,那么TIM1、TIM8~TIM11的时钟为APB2的时钟的两倍,TIM2~TIM7、TIM12
发表于 2019-06-18
STM32F4定时器时钟频率和时钟源

STM32CubeMX开发stm32f103rbt6 CAN例程(二)

1、STM32CubeMX配置    2、生成代码查看  3、编写代码程序下载:http://download.csdn.net/download/white_loong/101374684、使用CAN分析仪测试(波特率125K)问题:程序CAN收发同时打开例如:1、main() {     HAL_CAN_Receive_IT();     HAL_CAN_Transmit_IT(); }  HAL_CAN_RxCpltCallback() { 
发表于 2019-06-18
STM32CubeMX开发stm32f103rbt6 CAN例程(二)

stm32f407之CAN控制器(操作寄存器)

),和can2(从),其中过滤器的设置是通过can1来设置,其他工作模式,波特率等,可以各自设置。每个控制器有三个发送邮箱,两个fifo,每个fifo有三个接收邮箱。发送:选择一个空的发送邮箱,把帧信息写到该发送邮箱的寄存器里,请求发送,控制器就会根据标识符的优先级把帧先后发送出去。接收:如果接收到的帧的标识符能过过滤表的一系列过滤,该帧信息就会保存在fifo接收邮箱的寄存器里。过滤器:stm32f407共有28组过滤器,每组过滤器可以设置关联到fifo0或者fifo1,每组都包括两个32位存储器,可以配置成一个32位有位屏蔽功能的标识符过滤器,或者两个32位完全匹配的标识符过滤器,或者两个16位有位屏蔽功能的标识符过滤器,或者四个16位完全
发表于 2019-06-18
stm32f407之CAN控制器(操作寄存器)

stm32F4 hal库之CAN通信的实现

目标:通过can总线,用stm32的CAN模块实现对电机驱动发送指令,从而实现对电机的控制。硬件设计:①收发芯片的功能:把单片机送来的信号通过收发芯片的转换从而实现信号的具体传输。②120欧终端电阻:主要是为了防止信号的干扰,一般来说,终端设备的CAN_H和CAN_L也要加上120欧终端电阻。软件设计基本知识:其实各种通信方式的本质都是一样的,均分为两个部分;①波特率:以何种速度来通信②具体准则:发送端和接收端对发送来的数据的解释。特色:CAN工作于4种模式;类似于手机的飞行模式,正常模式,待机状态,是一种感觉。CAN常用的工作模式是(1)回环模式:也就是自己发,自己收。(2)正常工作模式,也就是用于正常的接收,发送。一.公共部分(
发表于 2019-06-18
stm32F4 hal库之CAN通信的实现

STM32f407的数字采集电路ADC的设计与使用

IN5   AD_CH2_Y    PA6   ADC1 IN6   AD_CH2_X    PA7   ADC1 IN7   */ #ifndef __BSP_ADC_H#define __BSP_ADC_H #include "stm32f4xx.h" #include "stm32f4xx.h" void bsp_InitADC(void);u16 bsp_GetAdValue(u8 chx); 
发表于 2019-06-18

STM32F207运用串口空闲中断+DMA接收不定长数据

;       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);//开启DMA时钟          DMA_InitStructure.DMA_Channel = DMA_Channel_4;//通道4           DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_Address; //外设地址
发表于 2019-06-18

小广播

何立民专栏

单片机及嵌入式宝典

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

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