历史上的今天
返回首页

历史上的今天

今天是:2024年10月07日(星期一)

正在发生

2018年10月07日 | stm32 Flash读写[库函数]

2018-10-07 来源:eefocus

通过对stm32内部的flash的读写可以实现对stm32的编程操作。

stm32 的内置可编程Flash在许多场合具有十分重要的意义。如其支持ICP特性使得开发人员对stm32可以警醒调试开发,可以通过JTAG和SWD接口对stm32进行程序烧写;支持IAP特性使得开发人员可以在stm32运行程序的时候对其内部程序进行更新操作。对一些对数据安全有要求的场合,可编程FLASH可以结合stm32内部唯一的身份标识实现各种各样的防破解方案。并且stm32的FLASH在一些轻量级的防掉电存储方案中也有立足之地。

 

stm32的FLASH分为主存储块和信息块。主存储块用于保存具体的程序代码和用户数据,信息块用于负责由stm32出厂是放置2KB的启动程序(Bootloader)和512B的用户配置信息区。

 

主存储块是以页为单位划分的,一页大小为1KB。范围为从地址0x08000000开始的128KB内。

 

对Flash 的写入操作要 “先擦除后写入”的原则;


stm32的内置flash 编程操作都是以页为单位写入的,而写入的操作必须要以16位半字宽度数据位单位,允许跨页写,写入非16位数据时将导致stm32内部总线错误。


进行内置flash读写时,必须要打开内部Rc振荡器。

 

main.c:

001#include "stm32f10x.h"
002#include "stdio.h"
003
004#define  PRINTF_ON  1
005
006void RCC_Configuration(void);
007void GPIO_Configuration(void);
008void USART_Configuration(void);
009
010u32 count=0;
011
012u16 data[5]={0x0001,0x0002,0x0003,0x0004,0x0005};
013
014int main(void)
015{
016    RCC_Configuration();
017    GPIO_Configuration();
018    USART_Configuration();
019
020    RCC_HSICmd(ENABLE);
021
022    FLASH_Unlock();
023
024    FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
025
026    FLASH_ErasePage(0x8002000);
027
028    while(count < 5)
029    {
030        FLASH_ProgramHalfWord((0x8002000 +count*2),data[count]);  //flash  为一个字节存储,16位数据必须地址加2
031
032        count++;
033
034    }
035
036    FLASH_Lock();
037
038    count = 0;
039
040    printf("\r\n The Five Data Is : \r\n");
041
042    while(count < 5)
043    {
044
045        printf("\r %d \r",*(u8 *)(0x8002000 + count*2));      //读取方法
046
047        count++;
048
049
050    }
051
052    while(1);
053
054}
055
056void GPIO_Configuration(void)
057{
058    GPIO_InitTypeDef    GPIO_InitStructure;
059
060    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
061
062    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
063    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        
064    GPIO_Init(GPIOA , &GPIO_InitStructure);
065
066    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
067    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          
068    GPIO_Init(GPIOA , &GPIO_InitStructure);
069}
070
071void RCC_Configuration(void)
072{
073    /* 定义枚举类型变量 HSEStartUpStatus */
074    ErrorStatus HSEStartUpStatus;
075
076    /* 复位系统时钟设置*/
077    RCC_DeInit();
078    /* 开启HSE*/
079    RCC_HSEConfig(RCC_HSE_ON);
080    /* 等待HSE起振并稳定*/
081    HSEStartUpStatus = RCC_WaitForHSEStartUp();
082    /* 判断HSE起是否振成功,是则进入if()内部 */
083    if(HSEStartUpStatus == SUCCESS)
084    {
085        /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
086        RCC_HCLKConfig(RCC_SYSCLK_Div1);
087        /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
088        RCC_PCLK2Config(RCC_HCLK_Div1);
089        /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
090        RCC_PCLK1Config(RCC_HCLK_Div2);
091        /* 设置FLASH延时周期数为2 */
092        FLASH_SetLatency(FLASH_Latency_2);
093        /* 使能FLASH预取缓存 */
094        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
095        /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
096        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
097        /* 使能PLL */
098        RCC_PLLCmd(ENABLE);
099        /* 等待PLL输出稳定 */
100        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
101        /* 选择SYSCLK时钟源为PLL */
102        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
103        /* 等待PLL成为SYSCLK时钟源 */
104        while(RCC_GetSYSCLKSource() != 0x08);
105    }
106    /* 打开APB2总线上的GPIOA时钟*/
107    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
108
109    //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
110
111    //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
112    //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE);
113
114}
115
116
117void USART_Configuration(void)
118{
119    USART_InitTypeDef USART_InitStructure;
120    USART_ClockInitTypeDef USART_ClockInitStructure;
121
122    USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
123    USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
124    USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                     
125    USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
126    USART_ClockInit(USART1 , &USART_ClockInitStructure);
127
128    USART_InitStructure.USART_BaudRate = 9600;
129    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
130    USART_InitStructure.USART_StopBits = USART_StopBits_1;
131    USART_InitStructure.USART_Parity = USART_Parity_No;
132    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
133    USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
134    USART_Init(USART1,&USART_InitStructure);
135
136    USART_Cmd(USART1,ENABLE);
137}
138
139#if  PRINTF_ON
140
141int fputc(int ch,FILE *f)
142{
143    USART_SendData(USART1,(u8) ch);
144    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
145    return ch;
146}
147
148#endif


推荐阅读

史海拾趣

Advanced Energy公司的发展小趣事

在发展过程中,AE公司不断突破技术瓶颈,实现了多项重要技术的创新。这些技术突破不仅提升了公司产品的性能和质量,也推动了整个电子行业的发展。随着技术的不断进步,AE公司开始将业务拓展至全球市场。通过与各国客户的合作与交流,AE公司不断了解市场需求,优化产品设计,为全球客户提供更加优质的电源解决方案。

HEC Inc公司的发展小趣事

Advanced Energy公司成立于1981年,总部位于美国科罗拉多州的丹佛市。在成立之初,AE公司便专注于电源技术的研发与创新。当时,电子行业的电源技术正处于快速发展阶段,AE公司凭借其前瞻性的技术视野和扎实的研发实力,迅速在市场中崭露头角。公司不断推出具有创新性的电源产品,满足了当时电子行业对高效、稳定电源的需求,逐渐在行业内建立了良好的声誉。

Hi-Tron Semiconductor Corp公司的发展小趣事

Advanced Energy公司成立于1981年,总部位于美国科罗拉多州的丹佛市。在成立之初,AE公司便专注于电源技术的研发与创新。当时,电子行业的电源技术正处于快速发展阶段,AE公司凭借其前瞻性的技术视野和扎实的研发实力,迅速在市场中崭露头角。公司不断推出具有创新性的电源产品,满足了当时电子行业对高效、稳定电源的需求,逐渐在行业内建立了良好的声誉。

Bedford Opto公司的发展小趣事

Bedford Opto公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,致力于减少生产过程中的污染和能耗。同时,公司还积极参与公益事业,为社会做出积极贡献。

泰科天润(GPT)公司的发展小趣事

Bedford Opto公司在成立初期,面临着激烈的市场竞争和技术瓶颈。然而,公司的研发团队通过不懈努力,成功开发出一款具有革命性的光电传感器。这款产品不仅提高了信号传输的效率,还降低了能耗,迅速在市场上获得了认可。Bedford Opto公司因此逐渐在电子行业中崭露头角。

Elpac公司的发展小趣事

在电子行业的激烈竞争中,Elpac公司凭借其在电源管理领域的技术革新,逐渐崭露头角。公司创始人李明在创办之初就坚信,只有不断创新才能在市场中立足。他带领团队深入研究市场需求,不断推出具有创新性的电源管理产品。其中,一款高效节能的电源转换器在市场上引起了广泛关注,其出色的性能和稳定性赢得了客户的青睐。随着产品的热销,Elpac公司逐渐在电子行业中建立了自己的品牌地位。

问答坊 | AI 解惑

为什么GPIO中有的 Pin要设为Pull_Up/Pull_Down?

如题,其中有的pin为输入pin,有的pin为输出pin,但是为什么要设置一些pin的属性为pull up或者为pull down,pull up/pull down到底是干吗用的?怎么知道为什么要设为这个呢,聆听各位大虾的教诲!!…

查看全部问答>

2N6227可以用ORCAD中哪个元件替换

2N6227可以用ORCAD中哪个元件替换…

查看全部问答>

C100或6410摄像头捕捉视频显示的问题(有视频,有真相)

先说下我是怎么玩的,模拟摄像头->TW9910->C100 CameraIF->Post Processor->Frame Buffer->LCD 问题描述请看视频: http://v.youku.com/v_show/id_XMTc3OTc3MDU2.html 视频的左侧大概2/5有时候会跑到右边去,但是刷新界面,或者改变界面后,会变 ...…

查看全部问答>

如何将控制台数据自动分工位显示到终端

如何将控制台数据自动分工位显示到终端 例: 工位号分为  A 、B 、C 、D 、E 、F     分别显示到 A 、B 、C 、D 、E 、F 终端 …

查看全部问答>

L298能驱动额定电流为1.5A的57步进电机吗?

芯片L298最大电压为50V,电流2A,峰值为4A。如图,A\\B\\C\\D端用51单片机输入信号端,A1\\B1\\C1\\D1为输出端,也就是接步进电机的,用这个驱动器驱动只有零点几安的小四相步进电机没有问题,我想驱动一下大点的电机,比如57步进电机,3A的可能不 ...…

查看全部问答>

USB学习板EASY USB 51 PROGRAMER使用说明书

Easy USB 51 Programer 源自百合电子工作室一款开源项目,这里它的使用说明书 …

查看全部问答>

stm32f10x中为什么设置输入捕获编译都通不过??

  TIM_ICInitStructure.TIM_ICMode= TIM_ICMode_ICAP;//配置为输入捕获模式    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;  TIM_ICInitStructure ...…

查看全部问答>

无锡华大国奇科技有限公司招custom layout工程师一名

各位同学,我是官志勇。无锡华大国奇科技有限公司IP开发部门招custom layout工程师一名。 工作地点是在上海,具体在汉口路400号华盛大厦20层。 要求: 1. 有三-五年的ASIC产品版图设计经验;当然长一点也可以,主要要求是可以独立工作; 2. 能 ...…

查看全部问答>

Google官方公布Google Glass技术细节,显示效果如同2.4米外的25英寸高清屏幕

Google 今天正式公布了即将发货的Google Glass的技术细节。这款 Google Glass 是开发者版,鼻托可调整,以适应不同脸型,共有两种。显示效果如同 2.4 米外的 25 英寸高清屏幕,我比划了下,如果这块屏幕够清晰的话还凑合,当然看小说肯定是不太可 ...…

查看全部问答>

一个结构 更加开放自由的 12864模块

     写一个12864是一种很简单的事情,网上的例程一抓一大把。但是,如果你要根据你的MCU请选择不同的例程。受写uLib(前身是uS)的影响,我在写12864的时候,尽可能使其独立于单片机。      随着不断整理 ...…

查看全部问答>