STM32之内部FLASH例程

发布者:馥睿堂最新更新时间:2019-03-07 来源: eefocus关键字:STM32  内部FLASH 手机看文章 扫描二维码
随时随地手机看文章


#include "stm32f10x.h"

#include

 

/* STM32 内部 FLASH 配置 */

#define STM32_FLASH_SIZE        512 /* 所选STM32的FLASH容量大小(单位为K)  */

 

#if STM32_FLASH_SIZE < 256

  #define STM_SECTOR_SIZE  1024    /* < 256为1K字节页,  >=256 为2K页 */

#else 

  #define STM_SECTOR_SIZE 2048

#endif

 

/* 应用程序区域 */

#define APP_REGION (0x8000000 + 0x80000 - STM_SECTOR_SIZE)

 

/* RCC时钟配置 */

void RCC_config()

ErrorStatus HSEStartUpStatus;

 

/* RCC寄存器设置为默认配置 */

RCC_DeInit();

/* 打开外部高速时钟 */

RCC_HSEConfig(RCC_HSE_ON);

/* 等待外部高速时钟稳定 */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS) 

/* 设置HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* 设置PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div1);

/* 设置PCLK1 = HCLK / 2 */

RCC_PCLK1Config(RCC_HCLK_Div2);

/* 设置FLASH代码延时 */

FLASH_SetLatency(FLASH_Latency_2);

/* 使能预取址缓存 */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/* 设置PLL时钟源为HSE倍频9 72MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

/* 使能PLL */

RCC_PLLCmd(ENABLE);

/* 等待PLL稳定 */

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

/* 设置PLL为系统时钟源 */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* 等待系统时钟源切换到PLL */

while(RCC_GetSYSCLKSource() != 0x08);

}

}

 

/* 扇区缓冲区 */

static uint8_t flash_buf[STM_SECTOR_SIZE];

 

/* 读flash */

void read_flash(uint32_t addr, uint8_t *buf, uint16_t size)

{

uint16_t i;

 

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

{

buf[i] = *(__IO uint8_t *)(addr + i);

}  

 

/* 写flash */

void write_flash(uint32_t addr, uint8_t *buf, uint16_t size)

{

uint32_t addr_base;

uint16_t len;

uint16_t i;


/* 检查地址合法性 */

if(addr < FLASH_BASE ||(addr >= (FLASH_BASE + 1024 * STM32_FLASH_SIZE)))

assert_param(0);

 

/* 将数据循环写入flash */

while(size)

{

/* 扇区基地址 */

addr_base = (addr / STM_SECTOR_SIZE) * STM_SECTOR_SIZE;

/* 读出整个扇区内容 */

read_flash(addr_base, flash_buf, STM_SECTOR_SIZE);

/* 需要写入的长度 */

len = ((addr + size) > (addr_base + STM_SECTOR_SIZE)) ? (addr_base + STM_SECTOR_SIZE - addr) : size;

/* 将需要改变的内容替换掉 */

memcpy(flash_buf + addr - addr_base, buf, len);


/* 解锁 */

FLASH_Unlock();

/* 擦除整片扇区 */

FLASH_ErasePage(addr_base);

/* 写使能 */

FLASH->CR &= FLASH_CR_OPTWRE; 

/* 重新将内容写入扇区 */

for(i = 0; i < STM_SECTOR_SIZE / 2; i++, addr_base += 2) /* 从头写到尾 */

FLASH_ProgramHalfWord(addr_base, *((uint16_t *)flash_buf + i));

/* 锁定 */

FLASH_Lock();

 

/* 将数据偏移len */

addr += len;

buf += len;

size -= len;

}

}

 

int main()

{

uint8_t buf[5] = {1, 2, 3, 4, 5};

uint8_t test[5];

 

/* 时钟配置 */

RCC_config();

 

write_flash(APP_REGION, buf, 5);

read_flash(APP_REGION, test, 5);


while(1)

{

 

}

}


关键字:STM32  内部FLASH 引用地址:STM32之内部FLASH例程

上一篇:STM32之SDIO例程
下一篇:STM32之内部FLASH原理

推荐阅读最新更新时间:2024-03-16 16:25

STM32基础之SPI
SPI简介 SPI协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。 SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200。 SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。SPI接口的读写操作,都是由主设备
[单片机]
<font color='red'>STM32</font>基础之SPI
利用stm32+app inventor与esp8266通信
本章实验的目的是将手机连接上ESP8266提供的WIFI网络,打开自定义的app连接ESP8266的ip地址及端口号,实现app与ESP8266模块的通信,进而达到app控制32开发板的目的,并将开发板上面的数据返回到app上显示出来。 关于stm32与esp8266之间的通信,在前面的文章中已经介绍得差不多了,本文章主要介绍的是app inventor的制作,然后生成app二维码,最后在手机端下载app,进而实现通过WIFI局域网控制stm32开发板,当然关于stm32与esp8266之间的一些东西也会粗略讲一下。 本章所用到的器件如下: STM32F103ZET6最小系统板 ESP8266-01S模块 USB转micr
[单片机]
利用stm32+app inventor与esp8266通信
IAR STM32 函数和变量的绝对地址定位
昨天我突然冒出个想法,能否利用函数和变量的绝对定位,实现程序的模块化更新。 也就是说,如果我要改变某个函数,只需要更新flash里面一个局部,也许只需要更新几百个字节,而无须重新下载整个上百K的程序。 经过查找资料和反复实验,终于实现了,现总结如下: 1) 把函数定位在FLASH高端的指定位置,以后更新,只更新那小块地方就可以了。 方法一: IAR里面进行函数定位, 必须要在.icf里面,进行定义。 void sendstr(unsigned *buf,unsigned short len) @ .sendstr { .... } .icf文件,加入这样一句: place at add
[单片机]
安全启动 - STM32安全启动架构
安全需要一个起点。 现在我们理解,没有安全启动,设备平台的安全难以得到保证。安全启动要求启动的位置一定是固定在某个地方。那么固定启动位置靠什么保证? 必须靠硬件 。软件本身的特点,决定了它很容易被修改,即使做了加密和加扰,破解的难度依然比硬件低很多。所以,安全启动一定是靠 STM32 硬件来保证。 脱离硬件谈安全启动基本上是不可能的 。 实现 Root of Trust(信任根)通用的做法是什么呢?一般是, 芯片有一个 Bootrom 启动只读存储区 。硬件的设计保证,芯片加电启动一定是从这个只读的甚至不可见的 Bootrom 里执行。 事实上,保持安全启动的原则不变,但是实现的方式可以不一样。 对于这个 Bootrom,
[单片机]
如何使用STM32_V3.5版本固件库建立工程模板
准备工作如下: 1:下载STM32_V3.5的固件库 去论坛上找,很多 2:准备Keil uVision4 软件,并安装到电脑上。 3:不要带板凳了,带上你的脑袋就行,因为板凳不会思考。 开始: 1:首先解压缩下载的固件库(保留一个备份,你懂的) 里面有, _htmresc : ST的 logo完全无用,不用理会, Libraries: 比较重要的文件 包含STM32的系统文件和大量头文件,也就是库文件了。 Project: 包含大量外设的例程,和各个软件版本的评估版工程模板。 KEIL对应的就是 MDK-ARM 文件下的工程模板。你也可以利用这
[单片机]
如何使用STM32_V3.5版本固件库建立工程模板
STM32的CubeMX关于串口中断
1、关于串口的初始化函数: MX_USART2_UART_Init()---波特率、奇偶校验等配置 HAL_UART_Init()---会将 huart- RxState = HAL_UART_STATE_READY; HAL_UART_MspInit()---GPIO,中断优先级等配置 2、当需要使用中断接收时需要调用 HAL_UART_Receive_IT()---配置接收的缓冲区指针,数量,huart- RxState = HAL_UART_STATE_BUSY_RX;,最后使能相应中断 3、当中断发生时,执行 HAL_UART_IRQHandler()--判断中断的类
[单片机]
<font color='red'>STM32</font>的CubeMX关于串口中断
STM32开发笔记83: SX1268驱动程序设计(芯片复位)
单片机型号:STM32L053R8T6 本系列开发日志,将详述SX1268驱动程序的整个设计过程,本篇介绍芯片复位驱动程序。 一、数据手册 1、NRESET是芯片第15引脚,低有效。 2、通过15引脚NREST,可以达到完整的芯片复位。复位后,会执行标准的校准程序,先前的内容将丢失。复位最短时间为50us,给100us较为合适。 3、这张图是芯片各个模式的引脚的状态表,可以看到除复位模式外,其余模式NREST引脚的状态都为IN PU,其意思是输入上拉,其上拉值为50K。 二、程序 1、由于其内部上来,我们可以给出低功耗的程序,不将单片机控制NREST的引脚设置为输出,而设置为analog引脚,程序如下: c
[单片机]
<font color='red'>STM32</font>开发笔记83: SX1268驱动程序设计(芯片复位)
全面掌握stm32的GPIO知识
1 初学者重要提示 本文主要是以stm32H7系列为主。 对于不使用的引脚,推荐设置为模拟模式,悬空即可。 GPIO的速度等级高的时候,最好使能IO补偿单元。 2 GPIO功能简介 STM32H7的GPIO特性如下: 输出状态:开漏/推挽 + 上拉/下拉电阻。 通过输出数据寄存器(GPIOx_ODR)或者外设(GPIO设置为复用模式时)输出数据。 GPIO速度等级设置。 输入状态:浮空,上拉/下拉,模拟。 通过输入数据寄存器(GPIOx_IDR)或者外设(GPIO设置为复用模式)输入数据。 通过寄存器GPIOx_BSRR实现对寄存器GPIOx_ODR的位操作。 通过配置寄存器GPIOx_LCKR的锁机制,实现冻结IO口配置。 每两
[单片机]
全面掌握<font color='red'>stm32</font>的GPIO知识
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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