很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,
( D: D2 Y( l& \ a4 D7 m env.c7 a a. } V0 u9 p
M: i$ ^' A6 g( p; s+ H
- #include "env.h"
% b0 c b3 C+ l! h - #define SAVE_ADDR (0X08020000-0x400)4 n+ y2 b7 Z9 |+ C
- _env_base Env;7 w3 a5 r1 g( M X% E0 b
- uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)
) m' W, M- Q0 l: v/ X - {
& g |4 s" x1 y% G3 x" l - uint16_t i=0;
( {* n: b& h' R+ s( z - uint16_t j=0;
2 f5 N1 v8 H2 a. F! G; q; x, D& x - uint16_t crc16=0xFFFF;
6 _+ |$ y3 ~; E6 p; m - for (i = 0; i < usDataLen; i++)
! }8 d- Z+ V0 Z" V6 X) W) ~4 o, t - {+ m. o' F$ C# U- `/ `
- crc16 ^= puchMsg[i];/ E4 ?. M% Z$ z9 c
- for (j = 0; j < 8; j++). q3 v+ _5 Y D8 [ @) T4 z. B/ a
- { F* p3 d6 m7 C5 x+ M x# K
- if ((crc16 & 0x01) == 1)
( y7 u: u) N. ^& M: [* s/ t# g - {8 g4 m+ N4 g; I
- crc16 = (crc16 >> 1) ^ 0xA001;5 W h7 m5 W$ o! I
- }! D) M/ y7 F) f+ ]
- else1 D: i. @' X& ?1 G" u/ M6 ?
- {$ q$ E5 D- x% l/ [/ I
- crc16 = crc16 >> 1;
6 w. o: `* |7 c0 L2 x - }- h5 S1 u1 W8 A2 F
- }, K5 Q; O8 j, J: T, \
- }8 r4 J) R6 \$ s5 M6 ?2 M
- return crc16; . e5 ~' [4 u" C9 l
- }& F9 b7 a8 _2 U# ?9 `2 c/ m
- //保存值,env没有发生变化直接退出8 c" |3 u5 w- M: G6 Q4 G
- int saveEnv()) w/ u9 D7 C) |; Z
- {4 ?5 f6 W, l0 I {) a5 q
- int i=0;
/ X* T; w; w9 m% O - uint16_t crc;2 @ w* B5 p Q1 Q
- uint32_t da; S* k* L- A- ?6 S P4 s- Z
- crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);
1 o H, N% V+ p: A - if(crc==Env.crc)return 0;
' X( r8 X3 L ]( x& k* H - Env.crc = crc;
( J- N6 P, |# B/ z0 v - FLASH_Unlock();
7 S1 f5 b) V& T) e - FLASH_ErasePage(SAVE_ADDR);
0 ?4 B l; _$ \8 U) n# K' e* r+ s- t - for(i=0;i<sizeof(_env_base)/4;i++)
5 D7 U( _% ~7 w6 q" l0 l - {
* q$ o6 |# L& v" t# t8 ` - da = *((uint32_t*)&Env + 1*i);
9 a; |0 A% M0 W$ r - FLASH_ProgramWord(SAVE_ADDR+i*4,da);1 _7 D2 @0 }5 {* D; D0 j' @
- }7 b: f6 N- a8 B" p2 I; g
- FLASH_Lock();
# ^5 v9 S/ y. Z3 ]/ O( h - return 1;( J' t# E$ ] J% Z: Z% ` l
- }
. Q8 R9 N0 ] |% q- _/ {* {% e - //读取7 S. o0 H, @! M5 v& V
- int readEnv()
7 |5 }0 W o1 b* s4 T5 j" ` - {% d2 a' E6 @% C
- int i=0;
/ m4 {: a ~, `* u# K - uint32_t *p=(uint32_t *)(&Env);. \. E. J* x; p2 U J2 q# n' z
- for(i=0;i<sizeof(_env_base)/4;i++)6 S+ f0 @) _4 F* o
- {
1 Z* @% Y! y) p" L - *p++ = *(uint32_t *)(SAVE_ADDR+i*4);9 U2 z q S% O
- }
- z+ o/ n$ S# e3 I - if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))) [3 D5 v* W* w' N8 i0 `. z
- {
# q: y9 t: H [1 G* g- _* q - return -1;; ~, F7 x0 H; {9 e8 t, _8 q
- }
) l7 M5 S) N; c8 i) J - return 0;/ d0 c( f0 H3 |% o8 ]$ c: j
- }' n; F) Q, Z3 P2 w1 P
- //初始化7 `+ Z, ]; F3 h
- void initEnvironment()
5 S; s9 k' ^6 a+ W4 U - {
( j6 A& k: v; O' U - if(0!=readEnv()); X- J% k/ N1 I# _) I
- {
6 U2 p/ ?1 z' g% X# |) D, m5 I - tmc2208_set_default();//一个配置组默认值
, _" d2 I0 \5 L5 p& I+ s' M - spin220_set_default();//另一个默认组默认值- N1 g% R4 e2 j" T9 A# I
- saveEnv();; E( m; e4 |$ p0 o5 U/ u
- }0 n' v1 U }: Z
- else
! z, G; C# T2 j+ l3 T1 P# I - {
7 k: D% R s. Y; C+ s$ U2 Y) c - //tmc2208_set_init();//针对配置计算运行时参数
* G3 g& a- U9 K( y4 e - //spin220_set_init();
1 P/ t, ]' I4 `9 _1 g - }
/ Y( d, c' j" K3 W$ y1 y9 A0 n - }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。* w9 u) g$ {( W7 E* f4 F' G
Env.h
* f3 c2 X" V6 t. \( m- #ifndef __ENV_H, @% S7 J0 c4 o9 t! T) _( H
- #define __ENV_H
5 |! i8 W/ n( k' Q2 L - % |$ l' y: I) O- ]# T( J4 r
- #include "stm32f0xx.h"5 h$ U& q, j: `
- #include "tmc2208.h"3 K! p0 d' Y5 w& x6 ^* Y6 Y
- #include "spin220.h"
" N9 _2 }0 z- d: k# K/ M - / d6 ? x9 q* O# t
- #pragma pack(4)
5 t3 \* [: d2 j1 P# w- L - typedef struct{' W- a3 e0 |" b( |
- uint8_t micro;9 W: r0 U1 C' f4 p' T" ]: L' [0 H$ G
- uint8_t fullStep_angle;# l( j# [ v5 L! J3 U
- uint16_t start_speed;! w, C( u) ^% c* B0 u5 E( Q
- uint16_t max_speed;* B6 J. F& \" S- i, ~" ?
- uint16_t min_speed;9 `% |" |4 t% w8 a% P* u
- uint16_t inc_distence;
7 `8 O$ u% u; u) h7 }1 \0 M - uint16_t motor_max_current;$ w6 T% m4 K% Y+ G
- uint16_t motor_resistance;
$ d! g4 P: s" J! v0 [4 Z* ^ -
) y& W( T) k7 y* N! h3 n8 I9 T - 3 L2 @ @5 e$ h0 E% e0 v( N* ~' Y6 q
- uint32_t pos;
5 H7 Y; P( O& L4 n5 H9 b# Z! k - uint32_t speed;
' \( ~5 L8 p E - }_tmc2208_set;5 k9 n, _/ w) |& i$ ]
- 2 K& \" `/ Q" m
- typedef struct{7 l8 ~& h" \* p' X
- uint8_t micro;
$ k) A- h( b, \$ ]; p - uint8_t fullStep_angle;0 E1 Z0 A* c! c
- uint8_t grat;
7 K3 p( t6 C2 e3 h* ^" n% }& x# P - 6 x: Y0 f' H6 C* Y. f! l
- uint16_t start_speed;
. K' R Y z6 c& S - uint16_t max_speed;) ~; g6 |& s3 q/ N: `
- uint16_t min_speed;1 P: a# T( U2 ]- d9 P# F; Z
- uint16_t inc_distence;! L- M: `4 k. L' }; l4 }, p: D' _
- BitAction max_io_value;7 A, Q6 _$ y' e9 X
- * U6 ?8 B; P _! Y" j
- uint32_t pos;
, n- v$ P A' P& F: k - uint32_t speed;0 U- n7 {0 W; a' i' \& p4 |* W/ Z
-
3 z% X$ a+ P9 G - int run_F0;' B$ h# P6 S% }
- int run6_max;9 w( |) d1 k* E% T4 K" P
- int run6_min;
! N( T6 G p7 M0 F- Y9 S# K# m - }_spin220_set;
8 g9 l" g9 O7 Q" K0 ^ - # H$ [4 K9 A% a! H! A2 ] y
- 7 |, y1 J& A" g
- 0 g V( \) K+ J c
- $ i( B# C0 X5 }1 q$ a
- typedef struct{: N) x5 R! f% m9 c6 p
- _tmc2208_set tmc2208;4 F& t- D. h) `4 }4 G3 [7 T
- _spin220_set spin220;1 r# [. J2 ~: [6 Q e
- uint16_t crc;8 b/ c, W) y+ e$ U1 u1 ^( H. L
- }_env_base;6 m+ d2 `0 Y& a3 V% U3 V2 S
- #pragma pack()
7 b0 ]: O' l1 y
. u+ v6 o$ w8 q% r- b5 f* I/ ]- extern _env_base Env;
8 [) Z+ t5 w, d$ c, m) ]: X - void initEnvironment(void);
; [0 C+ z& g& z' Q7 z - int saveEnv(void);
- p' r- P; M1 R - #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可
" P; U8 _5 W! P' \
3 z L! i, ` N- e7 M# {3 h' U- void spin220_set_default()
1 d- z5 X9 Q( J( J0 ~% d" G& m - {' V$ v/ g0 X0 X- Q
- Env.spin220.micro = 16;2 l5 O8 o/ w' P& K
- Env.spin220.fullStep_angle = 18;6 ~7 O l8 ]! @: M/ \
- Env.spin220.inc_distence = 2;
& G. u# E/ L5 Z( |- W( _ - Env.spin220.start_speed = 60;//: C5 C# s5 X% U; O
- 4 H" q3 g o3 \# D/ V
- Env.spin220.max_speed = 4000;* ]6 x: W( H" l9 v# {6 D) V
- Env.spin220.min_speed = 60;
5 C7 _& \% S" X9 S# S -
' H" P+ A% I8 ~" c - Env.spin220.max_io_value = Bit_RESET;
, x5 q4 I& B. A! u3 ? -
# e3 X/ z3 u+ X" Z+ O5 Q2 d - Env.spin220.pos = 7200;
! A" \* C* k7 b) } - Env.spin220.speed = 4000;
5 O6 l% Z' j, V" { -
4 |5 B7 _! O/ D( N+ f2 _" g5 B - Env.spin220.grat = 0;
+ q: x2 u1 I7 d1 d# G - / Y; ~4 c% C" Y1 S# ]; S
- Env.spin220.run_F0 = 16;5 Y/ f2 T; H" ` u
- % d) R& ~8 I' R( ]& L+ d6 G( m
- Env.spin220.run6_max = 0;
7 A& |4 S6 W+ W9 r9 r+ Z. ^6 Z, } - Env.spin220.run6_min = 16;
* w! O6 _/ A8 X( [. a1 b -
( y/ B8 p3 S9 P3 ] - spin220_set_init();
+ |" j& K8 P; m8 Z8 ?( a! _- s( F - }
复制代码 至于xxx_set_init()根据实际需要了
$ y. q+ Z* K; ?6 Y
! ], G8 W. D: o+ i2 u6 w5 y$ h# g, G; h& p& k, K
; L: M w7 P4 h. [9 T6 j
( G9 J* o5 X' `- R- n- m
x1 x8 P9 e1 f' M/ D" ^4 Y0 E |