当前位置: 首页 > news >正文

stm32 Flash读写[库函数]

stm32 的内置可编程Flash在许多场合具有十分重要的意义。如其支持ICP特性使得开发人员对stm32可以警醒调试开发,可以通过JTAG和SWD接口对stm32进行程序烧写;支持IAP特性使得开发人员可以在stm32运行程序的时候对其内部程序进行更新操作。对一些对数据安全有要求的场合,可编程FLASH可以结合stm32内部唯一的身份标识实现各种各样的防破解方案。并且stm32的FLASH在一些轻量级的防掉电存储方案中也有立足之地。
 
一. stm32的FLASH分为
1.主存储块:用于保存具体的程序代码用户数据,主存储块是以页为单位划分的,
      一页大小为1KB。范围为从地址0x08000000开始的128KB内。
2.信息块   :用于负责由stm32出厂是放置2KB的启动程序(Bootloader)和512B的用户配置信息区
二.操作原则
对Flash 的写入操作要 “先擦除后写入”的原则;
 stm32的内置flash 编程操作都是以页为单位写入的,而写入的操作必须要以16位半字宽度数据位单位,允许跨页写,写入非16位数据时将导致stm32内部总线错误
进行内置flash读写时,必须要打开内部Rc振荡器

#include "stm32f10x.h"
#include "stdio.h"

#define  PRINTF_ON  1

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);

u32 count=0;

u16 data[5]={0x0001,0x0002,0x0003,0x0004,0x0005};

int main(void)
{
   RCC_Configuration();
 GPIO_Configuration();
 USART_Configuration();

 RCC_HSICmd(ENABLE);//Enables or disables the Internal High Speed oscillator (HSI).

 FLASH_Unlock();  /* Unlocks the FLASH Program Erase Controller.*/

/*将flash三个标志位全清*/

 FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);

 FLASH_ErasePage(0x8002000);

 while(count < 5)
 {
  FLASH_ProgramHalfWord((0x8002000 +count*2),data[count]);  //flash  为一个字节存储,16位数据必须地址加2

  count++;
 
 }

 FLASH_Lock();

 count = 0;

 printf("\r\n The Five Data Is : \r\n");

 while(count < 5)
 {
  
  printf("\r %d \r",*(u8 *)(0x8002000 + count*2));   //读取方法

  count++;
 

 }

 while(1);
 
}

void GPIO_Configuration(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
   GPIO_Init(GPIOA , &GPIO_InitStructure); 
 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
   GPIO_Init(GPIOA , &GPIO_InitStructure); 
}

void RCC_Configuration(void)
{
 /* 定义枚举类型变量 HSEStartUpStatus */
 ErrorStatus HSEStartUpStatus;

   /* 复位系统时钟设置*/
   RCC_DeInit();
   /* 开启HSE*/
   RCC_HSEConfig(RCC_HSE_ON);
   /* 等待HSE起振并稳定*/
   HSEStartUpStatus = RCC_WaitForHSEStartUp();
 /* 判断HSE起是否振成功,是则进入if()内部 */
   if(HSEStartUpStatus == SUCCESS)
   {
     /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
     RCC_HCLKConfig(RCC_SYSCLK_Div1); 
     /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
     RCC_PCLK2Config(RCC_HCLK_Div1); 
     /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
     RCC_PCLK1Config(RCC_HCLK_Div2);
     /* 设置FLASH延时周期数为2 */
     FLASH_SetLatency(FLASH_Latency_2);
     /* 使能FLASH预取缓存 */
     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
     /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
     /* 使能PLL */ 
     RCC_PLLCmd(ENABLE);
     /* 等待PLL输出稳定 */
     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
     /* 选择SYSCLK时钟源为PLL */
     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
     /* 等待PLL成为SYSCLK时钟源 */
     while(RCC_GetSYSCLKSource() != 0x08);
   } 
   /* 打开APB2总线上的GPIOA时钟*/
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);

 //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
 //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE);
  
}

 
void USART_Configuration(void)
{
 USART_InitTypeDef USART_InitStructure;
 USART_ClockInitTypeDef USART_ClockInitStructure;

 USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
 USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
 USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                      
 USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
 USART_ClockInit(USART1 , &USART_ClockInitStructure);

 USART_InitStructure.USART_BaudRate = 9600;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
 USART_Init(USART1,&USART_InitStructure);

  USART_Cmd(USART1,ENABLE);
}

#if  PRINTF_ON

int fputc(int ch,FILE *f)
{
 USART_SendData(USART1,(u8) ch);
 while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
 return ch;
}

#endif

转载于:https://www.cnblogs.com/Ph-one/p/4157210.html

相关文章:

  • strlen与sizeof区别
  • stm32 Flash读写独立函数[库函数]
  • 器件封装及尺寸问题
  • A8逻辑篇1.点亮一个LED(S5PV210.A8)
  • 电压跟随器测量
  • RC 522模块在LINUX平台调试笔记
  • RC522 模块驱动程序
  • 基于ARM、linux的MF RC522射频读卡器
  • linux体系结构与内核结构图解
  • Linux内核源码目录说明
  • A8几种内存
  • LM358电流检测电路
  • arm-linux-ld命令
  • 从IC设计业看中国企业之发展
  • TCP/IP、Http、Socket的区别
  • 【React系列】如何构建React应用程序
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • CentOS从零开始部署Nodejs项目
  • Computed property XXX was assigned to but it has no setter
  • download使用浅析
  • Git学习与使用心得(1)—— 初始化
  • HTTP中的ETag在移动客户端的应用
  • JavaScript 一些 DOM 的知识点
  • JAVA并发编程--1.基础概念
  • Yeoman_Bower_Grunt
  • yii2中session跨域名的问题
  • 构建二叉树进行数值数组的去重及优化
  • 深入浏览器事件循环的本质
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # 飞书APP集成平台-数字化落地
  • (2)MFC+openGL单文档框架glFrame
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)fiber的基本认识
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (三)mysql_MYSQL(三)
  • (未解决)macOS matplotlib 中文是方框
  • (一)VirtualBox安装增强功能
  • (转)visual stdio 书签功能介绍
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET Micro Framework初体验(二)
  • .net 调用php,php 调用.net com组件 --
  • .net 发送邮件
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net 受管制代码
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • @Transaction注解失效的几种场景(附有示例代码)
  • @在php中起什么作用?
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [bzoj1901]: Zju2112 Dynamic Rankings
  • [C# 开发技巧]实现属于自己的截图工具
  • [C#C++]类CLASS