你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32掉电时存数据到FLASH

[复制链接]
STMCU小助手 发布时间:2022-1-30 01:00
一、STM32FLASH简介
  不同的STM32它的FLASH大小也是不一样的,分为大、中、小容量,容量由16K到1024K不等。这次实验用的开发板FLASH容量大小为128K。
  STM32的闪存模块由:主存储器、信息块和闪存存储器接口寄存器三部分组成。
  主存储器:该部分主要是用来存放代码和数据常数,被划分为128页,每页1K字节(小容量产品也是每页1K字节,大容量为每页2K字节)。主存储器的起始地址就是0X08000000, B0、B1都接GND的时候,就是从0X08000000开始运行代码的。
  信息块:该部分分为2个小部分,其中启动程序代码,是用来存储ST自带的启动程序,用于串口下载代码,当B0接V3.3,B1接GND的时候,运行的就是这部分代码。用户选择字节,则一般用于配置写保护、读保护等功能。
  闪存存储器接口寄存器:该部分用于控制闪存读写等,是整个闪存模块的控制机构。 
  对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压由内部产生。
  在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作
闪存的读取
  内置闪存模块可以在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相应的数据。读接口在闪存端包含一个读控制器,还包含一个AHB接口与CPU衔接。这个接口的主要工作是产生读闪存的控制信号并预取CPU要求的指令块,预取指令块仅用于在I-Code总线上的取指操作,数据常量是通过D-Code总线访问的。这两条总线的访问目标是相同的闪存模块,访问D-Code将比预取指令优先级高。
  这里要特别留意一个闪存等待时间,因为CPU运行速度比FLASH快得多,STM32F103的FLASH最快访问速度≤24Mhz,如果CPU频率超过这个速度,那么必须加入等待时间,比如我们一般使用72Mhz的主频,那么FLASH等待周期就必须设置为2,该设置通过FLASH_ACR寄存器设置。
闪存的编程和擦除
  编程过程:
  ·检查FLASH_CR的LOCK是否解锁,如果没有则先解锁
  ·检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作
  ·设置FLASH_CR寄存器的PG位为’1’
  ·在指定的地址写入要编程的半字
  ·等待BSY位变为’0’
  ·读出写入的地址并验证数据
  擦除过程(页擦除)
  ·检查FLASH_CR的LOCK是否解锁,如果没有则先解锁
  ·检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作
  ·设置FLASH_CR寄存器的PER位为’1’
  ·用FLASH_AR寄存器选择要擦除的页
  ·设置FLASH_CR寄存器的STRT位为’1’
  ·等待BSY位变为’0’
  ·读出被擦除的页并做验证
二、软件实现
  flash.c文件
  1. #include "flash.h": O7 h" H1 l1 ~
  2. #include "delay.h"- I( `4 g; n, X6 p% l& O9 i& z
  3. #include "usart.h"
    3 {: x5 C( [9 H9 R
  4. " y2 y2 |$ P3 d2 M! |
  5. /***flash解锁*****/
    4 A; C( B1 m2 q
  6. void STMFLASH_Unlock(void)* z( j4 G$ R* T* X' ^
  7. {
    $ J& w% ], W$ F+ u
  8.   FLASH->KEYR=FLASH_KEY1;                                        //写入解锁序列6 p  U* r9 h0 i' A3 t+ m
  9.   FLASH->KEYR=FLASH_KEY2;5 e3 O' W' i5 m# M1 r
  10. }" G* K3 A( n2 B

  11. 0 a1 ]) B; @) [1 E9 a% i( Y& R
  12. //flash上锁
    9 T, X3 T% ^. o; P+ _
  13. void STMFLASH_Lock(void)
    ' m; l0 X" k- f7 P. D' u
  14. {
      `6 M- k# [: @; o; _% o( w5 {
  15.   FLASH->CR|=1<<7;                                              //上锁
    + s( u" J8 ~1 c9 u. B2 f
  16. }
    # V3 M* A5 R, m2 F* Z9 W" F% y/ ^

  17. ( X6 C# A- b% r/ [
  18. //得到FLASH状态) {4 [) h, w8 w/ T  x
  19. u8 STMFLASH_GetStatus(void)
    7 @% [4 F: |* C& j2 H$ _
  20. {   
    ( u% k; Q7 u9 u+ \
  21.    u32 res;         
    9 Q$ ?! X1 k  ^) P, B6 A
  22. " u9 E6 U/ S& G$ o  n! J' P* e9 D6 ~
  23.    res=FLASH->SR;
    , E5 z( o: g; _6 G" h# B. I
  24.    if(res&(1<<0))return 1;                                          //忙4 X! t3 ]% S4 K7 g+ W/ \  s
  25.    else if(res&(1<<2))return 2;                                     //编程错误
    , @# \; i6 L" h
  26.    else if(res&(1<<4))return 3;                                     //写保护错误: X0 b* @" c% w3 c5 v' ?
  27.    return 0;                                                        //操作完成3 n' j) |0 F: X; U) a6 h; ^
  28. }- Z- ~8 M8 R& h8 t: ?4 F3 U

  29. 9 A" [: @$ T/ E3 a, a. N
  30. //等待操作完成. ^! H9 u* R) I
  31. //time:延时长短
    " g. w! H0 F% _
  32. //返回值:状态.# M# J% k& ~& m& ?. V
  33. u8 STMFLASH_WaitDone(u16 time)
    , C# Q. u& c# z3 a- G, W5 q; \& @
  34. {
    + M0 [" g0 P) @% E
  35.    u8 res;
    $ P6 n5 G; @- v' t

  36. - r9 P! I8 \/ r$ M" g( w4 j5 b
  37.    do
      `/ G3 v* H8 n4 b+ g
  38.    {
      k+ u& D0 I" f5 A* x2 J
  39.       res=STMFLASH_GetStatus();: o1 m4 C3 p! [- \
  40.       if(res!=1)break;                                            //非忙,无需等待,直接退出.
    ; |" v7 r* L" s+ e6 C( r) k
  41.       Delay_us(1); time--;             : ]1 a2 f! _  C# g# X/ M  |+ q
  42.     }while(time);" v" q% w( o* u) {' q
  43.     if(time==0)res=0xff;                                           //TIMEOUT( z+ F+ O7 U. w  k! ]  }
  44.     return res;
    ( B# {7 O* F$ u$ z& u: c" y
  45. }$ A" v/ k" @5 N& k4 j& Q' j
  46. , |6 L" ?) _# i: G
  47. //擦除页- g0 e, [) N7 J* i
  48. //paddr:页地址6 D' i: \# M, V& x6 {
  49. //返回值:执行情况
    $ ?/ d6 s# k8 X; k6 ?
  50. u8 STMFLASH_ErasePage(u32 paddr)
    . |7 Q: ]& A6 H% T: v3 r( o

  51. ! T& u9 }/ k" r5 K
  52. {9 T1 h& ~+ Q2 C: M9 q' k+ J
  53.        u8 res=0;# C0 Q+ H" O- p9 z% L

  54. ( N3 s5 p& x4 A# ~
  55.        res=STMFLASH_WaitDone(0X5FFF);                              //等待上次操作结束,>20ms   - p1 d7 q: p7 T
  56.        if(res==0)7 N7 E$ `7 _6 K! W! z& G
  57.        {
    ) F- x5 [# l/ K' y1 z& x
  58.               FLASH->CR|=1<<1;                                      //页擦除
    ) K& o. K' u( S% _- P* t7 n) u
  59.               FLASH->AR=paddr;                                      //设置页地址
    ' w4 @7 @' B/ @8 {  F( |
  60.               FLASH->CR|=1<<6;                                      //开始擦除           
    + o9 W. {* Y2 W& Y& D; i$ Q
  61.               res=STMFLASH_WaitDone(0X5FFF);                       //等待操作结束,>20ms
    $ Q5 e8 t; Z9 _3 X
  62.               if(res!=1)                                             //非忙( \9 ?: T+ }2 y: G! L
  63.               {. }, B# L0 Q( }7 d& n
  64.                      FLASH->CR&=~(1<<1);                           //清除页擦除标志.
    # X1 q8 c1 P. f# O3 A% {8 j0 Q( m; r/ B4 F; T
  65.               }
    / e$ z1 @  d9 W' u* a2 [
  66.        }) a6 U2 [3 ~9 D' t& M" L
  67.        return res;' a8 h8 w- l. o$ y5 [
  68. }
    , B2 J7 q* y* t' c, c; C

  69. 0 b- ?7 U8 c& z5 N
  70. //读出指定地址的半字(16位数据)
    1 k! f0 m/ u: D2 j
  71. //faddr:读地址(此地址必须为2的倍数!!)2 L) i/ t& s+ o) p% j4 s
  72. //返回值:对应数据.& \& Q  k* M6 U: }+ j: X: s
  73. u16 STMFLASH_ReadHalfWord(u32 faddr)
    9 {) H9 Y) {% V
  74. {
    / U' w6 U* K) \7 H
  75.     return *(vu16*)faddr;
    , P: `. m( ]5 J7 L" J9 J$ O
  76. }. B' E2 z- i% ~" n
  77. #if STM32_FLASH_WREN                                               //如果使能了写   ( ?5 d, `( M0 [) {2 b5 h
  78. //不检查的写入
    # a$ a0 d& x, z" K* _
  79. //WriteAddr:起始地址6 S- c7 G* ^# T7 p7 i2 ^
  80. //pBuffer:数据指针
      F; z. F$ i6 a1 W
  81. //NumToWrite:半字(16位)数   
    2 I" r0 w% c$ F. @1 x5 j, ^. y# z
  82. void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
    ! g) ]! m0 O# |5 w# P
  83. {                       
    # H7 ^3 O8 P# S5 a
  84.     u16 i;- v9 S2 h! ]% y3 `7 @/ e' d
  85.     for(i=0;i<NumToWrite;i++)* S" L6 ?3 ~# q- p! p1 n8 h
  86.     {
    - d9 ^3 C8 o' V/ d) ]. t- a8 D
  87.         FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
    ! h. \5 ~  e# O) `0 f- O- C
  88.         WriteAddr+=2;                                           //地址增加2.
    5 o" w3 ]- n4 x/ W2 F: ^4 s& v1 o
  89.     }  
    ' ~7 b9 T  J* F8 N
  90. }
    # p& c; I  V1 V' n$ P
  91. //从指定地址开始写入指定长度的数据
    7 Z) R2 ~1 }: S  Q3 H* w, `
  92. //WriteAddr:起始地址(此地址必须为2的倍数!!)
    & `  U4 D3 l. o6 A, \) v. L4 C
  93. //pBuffer:数据指针
    , o( e* ]) S! c! T/ a
  94. //NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    + X0 ^! b% V! I6 c7 `  P
  95. #if STM32_FLASH_SIZE<256
    2 G* T" h$ \2 D  C3 f; j
  96. #define STM_SECTOR_SIZE 1024                                       //字节
    $ X* \3 f; P) c. C3 ^9 v, _
  97. #else
    0 D- }( F' @  j
  98. #define STM_SECTOR_SIZE    2048
    ; [# S& i" W  s  }. w5 W8 |
  99. #endif         
    3 o3 G8 \8 }& M/ t  S, C3 k" u: A
  100. u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];                               //最多是2K字节6 b& k4 g- r* \. h5 c0 t5 _- g

  101. 0 Y6 B% m3 ^; R  I% \1 g$ l
  102. void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
    * ]' a% s. J6 k' D- A' }
  103. {3 [  ~+ ^# n' z' ?
  104.     u32 secpos;                                                     //扇区地址
    1 X$ H; S3 @: N
  105.     u16 secoff;                                                     //扇区内偏移地址(16位字计算)/ B3 M8 t; v5 R  i5 I) n4 O; O
  106.     u16 secremain;                                                  //扇区内剩余地址(16位字计算)       9 K/ x$ C9 u/ ^
  107.      u16 i;   
    / _( `& D1 k8 k2 c/ ]" C
  108.     u32 offaddr;                                                    //去掉0X08000000后的地址
    & h% z# S7 e( w& j
  109.    
    : a- b! s* T% f4 T. @
  110.     if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址; e0 _4 M" P) i7 q
  111.     FLASH_Unlock();                                                 //解锁
    : S+ l. M4 v; v2 p" z
  112.     offaddr=WriteAddr-STM32_FLASH_BASE;                             //实际偏移地址.% G% ]& S* o) \
  113.     secpos=offaddr/STM_SECTOR_SIZE;                                 //扇区地址  0~127 for STM32F103RBT6
    " C+ ]9 Y% T) i" [$ q- }! M" _; a
  114.     secoff=(offaddr%STM_SECTOR_SIZE)/2;                             //在扇区内的偏移(2个字节为基本单位.)
    % s) {3 x1 b* Q( {7 W4 O$ g7 V
  115.     secremain=STM_SECTOR_SIZE/2-secoff;                             //扇区剩余空间大小  5 }4 Z7 W, v% m
  116.     if(NumToWrite<=secremain)secremain=NumToWrite;                 //不大于该扇区范围1 @' ]: d% g) F4 T" j7 B9 Y
  117.     while(1) 4 [. c: V" q; p+ c/ D
  118.     {    8 W/ r4 ~. s4 t+ y; b! s
  119.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
      ?* X) J; l, _7 \' Z
  120.         for(i=0;i<secremain;i++)                                   //校验数据
    # k0 a1 W, G% P) ^, M
  121.         {9 C" D5 t- S3 [. z/ \
  122.             if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;              //需要擦除      
    * S4 }$ @' v, V+ a: O1 [$ [
  123.         }
    4 B  u1 @6 W# e9 @
  124.         if(i<secremain)                                            //需要擦除5 Y7 i1 Z8 J8 v$ ]% ]7 f! Z0 C
  125.         {' T/ Y# n1 i6 ]( u9 b4 l! j
  126.             FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);               //擦除这个扇区& N, Z  D$ p) I! ~% B
  127.             for(i=0;i<secremain;i++)                              //复制' K( u. z/ O9 s0 d1 _$ _
  128.             {
    . v) E0 @5 {! V
  129.                 STMFLASH_BUF[i+secoff]=pBuffer[i];      
    2 ?2 d) M- \% ^
  130.             }1 S' E. v# T( ^7 h2 G
  131.             STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
    3 p2 C& _' C* H
  132.         }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain); //写已经擦除了的,直接写入扇区剩余区间.                    
    # x$ G7 a7 B9 H' d8 x& G
  133.         if(NumToWrite==secremain)break;                            //写入结束了6 U: o8 H2 i& b# l
  134.         else                                                       //写入未结束: w% `. M0 P+ {% H- o6 {6 [
  135.         {/ g' t) D; \" e2 v" V+ |
  136.             secpos++;                                              //扇区地址增1
    1 z+ e& t+ E* ~% E/ S) c6 O7 @5 C
  137.             secoff=0;                                              //偏移位置为0      
      v  C5 Y% ?4 d+ R, t) d, V
  138.                pBuffer+=secremain;                                 //指针偏移
    . E, |; v% a4 P+ T7 M0 u5 o% r
  139.             WriteAddr+=secremain;                                  //写地址偏移       , l6 S  _; Z9 \
  140.                NumToWrite-=secremain;                              //字节(16位)数递减
    0 m* ?+ ?0 ?0 {( l8 J  S: c
  141.             if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
    + _0 ]  V7 _/ p* W* J/ d5 z% @7 L
  142.             else secremain=NumToWrite;                             //下一个扇区可以写完了* K; \+ n7 _1 g5 Y+ J
  143.         }       N3 e* ]- C+ q+ i
  144.     };   
    8 L+ D- J" l4 n9 d) L/ b+ p0 o$ k
  145.     FLASH_Lock();                                                  //上锁4 K( p* C( ]! d- R* j) b; t" u
  146. }
    5 E2 W- Q' d9 f1 D2 D! X9 X6 K: b
  147. #endif% J( [, L, b! _" h, z# I
  148. . t' O9 D0 |3 d- P. p
  149. //从指定地址开始读取指定长度的数据
    ( z3 Q  L- D$ P: l6 B- G, z/ F' X# k
  150. //ReadAddr:起始地址
    , c* x" _# [* m" Y& s# |. W6 K
  151. //pBuffer:数据指针
    $ b! r% J& D2 t& @/ }) ~
  152. //NumToWrite:半字(16位)数0 |! O$ z0 r, {& C. K5 n; d
  153. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
    4 y9 ~* W. a, ~, G  S5 o
  154. {$ D2 X2 u* `  L1 W9 q% M
  155.     u16 i;
    ; j4 o0 p$ J& `
  156.     for(i=0;i<NumToRead;i++)
    / d4 X0 P7 I1 ?( U$ J/ P: Y2 B
  157.     {  c  k' L/ a( U; n# ~
  158.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);               //读取2个字节.
    9 }- I; |* c" c: [8 T
  159.         ReadAddr+=2;                                              //偏移2个字节$ G: x4 m# g" }, v  Z6 W
  160.     }0 z2 {6 h4 m1 J1 x" n* A6 ]
  161. }
    3 V+ Z/ i- ?2 `2 y& K$ i& H$ w
  162. * T1 T. }$ u8 Q6 S0 i* D  [0 {. O
  163. //////////////////////////////////////////////////////////////////////////////////////////////////////
    / X0 u  x5 p, C1 W' s$ g! H5 s* G, W
  164. //WriteAddr:起始地址  A5 r, n4 {- {: R: W) j; [3 _
  165. //WriteData:要写入的数据
    4 i) O8 P; t# K" s+ t
  166. void Test_Write(u32 WriteAddr,u16 WriteData)      
    6 I# _4 L' ~6 V# P0 k$ Y* V
  167. {
    3 ~  A: q3 R; B- M. l: ?4 r
  168.     STMFLASH_Write(WriteAddr,&WriteData,1);                       //写入一个字 " u8 W2 T) h0 ~" w! I: h
  169. }
复制代码
7 c# l& o( n8 X( d6 Z
  flash.h文件
  1. #ifndef __FLASH_H__  G8 E! T% z4 T7 E" H
  2. #define __FLASH_H__
    1 m" Q2 [! G1 }7 g
  3. #include <stm32f10x.h>
    " U$ c7 B6 G6 D! G

  4. 9 W# g3 Q6 T5 o4 D) e
  5. #define FLASH_KEY1               0X45670123
    6 p) S7 H: C9 l6 U
  6. #define FLASH_KEY2               0XCDEF89AB
    ) ], c+ s8 C& t3 J6 D) ]
  7. % ^- V/ m5 w: P" W7 C
  8. #define STM32_FLASH_SIZE 128                                 //所选STM32的FLASH容量大小(单位为K)+ Z+ g4 |' v# n. D! v7 t/ W
  9. #define STM32_FLASH_WREN 1                                       //使能FLASH写入(0,不使能;1,使能): G5 n2 m% V! g, F! z0 _
  10. //////////////////////////////////////////////////////////////////////////////////////////////////////
    3 Y4 C; M3 x# I( c! u; h" S0 B8 u

  11. 6 L; H  P: ~5 a- L! E. x2 d! Y
  12. //FLASH起始地址
    & N* A# q9 M4 I$ H, g6 d( T
  13. #define STM32_FLASH_BASE 0x08000000                         //STM32 FLASH的起始地址0 E3 c3 C. H2 j1 ^- O; \, t
  14. ; a) T( I. C. P* Z: j& I7 D

  15. . Y7 ?( E- I( n1 K% n2 m
  16. void STMFLASH_Unlock(void);                                        //解锁
    8 C  V1 r7 ~9 U$ R/ k: B& M. f
  17. void STMFLASH_Lock(void);                                       //上锁
    " L5 [& B, L: T! H. ]! f
  18. u8 STMFLASH_GetStatus(void);                                       //获得状态
    , K0 Y( n9 i% d, @) B3 u' v
  19. u8 STMFLASH_WaitDone(u16 time);                                  //等待操作结束
    3 \9 e# o5 m4 K; F* @
  20. u8 STMFLASH_ErasePage(u32 paddr);                                  //擦除页
    ) W; c3 j5 O9 ?! q& U
  21. u16 STMFLASH_ReadHalfWord(u32 faddr);                               //读出半字  . H: r0 s" f3 r) w
  22. void STMFLASH_WriteLenByte(u32 WriteAddr,u32 DataToWrite,u16 Len);       //指定地址开始写入指定长度的数据5 O+ h: \  U) z3 e% I
  23. u32 STMFLASH_ReadLenByte(u32 ReadAddr,u16 Len);                       //指定地址开始读取指定长度的数据. K+ X# L5 w5 n: d4 C( E- U
  24. void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite);          //从指定地址开始写入指定长度的数据
    : @4 c9 [- Q" Z8 p& D; D, y
  25. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead);             //从指定地址开始读取指定长度的数据/ h$ E3 X2 k) s4 p8 L. H/ ~
  26. 9 D" l: X5 [4 O4 S! D# g
  27. //测试写入7 I" q  ]( I9 K5 E5 t
  28. void Test_Write(u32 WriteAddr,u16 WriteData);                                   3 c1 O! M! b8 V: h5 q& b) k
  29. #endif
复制代码

7 m) q, e# K4 N6 D3 M% U" j

/ o9 F# @) N+ a  s9 t: R
  main.c文件
  1. #include "flash.h"
    - N" V$ z6 o4 X" X8 i3 ^  a

  2. ; ^+ @/ ]9 d+ \/ _
  3. #define SIZE sizeof(TEXT_Buffer)                  ///数组长度, E6 j6 J1 V: ?- V
  4. #define FLASH_SAVE_ADDR  0X08070000   //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)9 d& F+ U' Z0 N3 }9 ]+ t$ `, T
  5. 2 q; O" g5 m7 n% [4 C% [1 ?# r6 w2 n4 Y
  6. const u8 TEXT_Buffer[]={"STM32 FLASH TEST"};
      `& u* D- w& H: _  v2 `
  7. u8 datatemp[SIZE];3 d% p8 G1 d# N

  8. $ k8 s' ]9 W- Y- ^( {4 `" H9 x
  9. int main(void)
    7 |5 V& ^0 z8 e. U+ s$ Z! [# L) o! z+ I$ B
  10. {
    4 @3 o! N% i6 @5 `- D. n( l% ~: f
  11.      while(1)% v1 R0 h8 q2 ^6 D! b
  12.     {
    % m: B" l% k$ B. ^
  13.         if(掉电)
    6 v5 i. W: C) H8 L! v+ W" W8 A- A
  14.      {/ v' B" }% ]- q9 `  k. W
  15.           STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)TEXT_Buffer,SIZE);//flash写函数5 [1 j  t. G& C8 v/ Z
  16.      }  
    0 g( k: ~& r% y% ]
  17.            STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)datatemp,SIZE);     //flash读函数   
    . ]: v) F6 F0 L9 [: R
  18.    }. h. d% g7 g4 p5 }) Y' O
  19. }
复制代码

3 T, F' C2 F# T, @; _" y) W" d! r8 c. e9 p
  以上就是flash在掉电的时候进行读写的程序,项目用到了就记录一下,方便以后查阅学习。其中的大部分代码在库函数中都能够找到参考。

& g/ [  f, h* p- v% K- K
收藏 评论0 发布时间:2022-1-30 01:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版