您的位置:首页 > 其它

stm32 Flash读写[库函数]

2015-03-05 14:00 288 查看
转自:http://www.ichanging.org/stm32-flash.html

通过对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_ON1
005
006
void
RCC_Configuration(
void
);
007
void
GPIO_Configuration(
void
);
008
void
USART_Configuration(
void
);
009
010
u32
count=0;
011
012
u16
data[5]={0x0001,0x0002,0x0003,0x0004,0x0005};
013
014
int
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
TheFiveDataIs:\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
056
void
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
071
void
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)时钟源为SYSCLK1分频*/
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)时钟源为HSE1分频,倍频数为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
117
void
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
141
int
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: