很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,
: t$ J- I8 _1 _5 j7 V/ _# C env.c0 @ Q" x2 j' e& |4 f
/ u: N. l; I. q% t0 X- #include "env.h"
- G0 Q6 A* c& V' x' i - #define SAVE_ADDR (0X08020000-0x400)6 _6 O8 F8 ?& }% z& B6 ^
- _env_base Env;- }. N3 F8 Z7 G
- uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)
% i, y' [5 y V1 J - {
1 z% a! g6 {6 m. }+ E, X! u - uint16_t i=0;
5 v- Q5 J; @" X2 ~( s5 A# S - uint16_t j=0;
' m( M! ]3 T) ` - uint16_t crc16=0xFFFF;
+ R9 ]5 [, ~; }8 l - for (i = 0; i < usDataLen; i++)9 m: q5 U2 h" \! _9 `& F
- {
3 N9 b( {6 }: `7 S - crc16 ^= puchMsg[i]; x: ?* P7 M! Z
- for (j = 0; j < 8; j++)
1 h: |9 D) U9 p. `- s - { 1 N2 C+ K& p4 L4 N
- if ((crc16 & 0x01) == 1)/ x! c1 n1 m( I V. J, Y
- {5 q% b6 w1 D0 W; l
- crc16 = (crc16 >> 1) ^ 0xA001;8 A5 m; H4 r/ ~9 B9 S
- }) |3 n. a( Y* @+ t& o) i0 I9 L/ o
- else
6 w4 ^' F* V0 q- b - {
0 d$ F6 V; w8 C! _9 P - crc16 = crc16 >> 1;
6 w3 {' h* ^4 w6 h* J, Y - }
1 t6 m# l2 |" P6 C - }8 j/ _6 X: o: L# i9 W& A5 f
- }
4 h v. W, F. I, Y( P - return crc16;
# @0 Q! g1 ^$ ~" B - }1 S$ K1 W1 f% G' h* D' c
- //保存值,env没有发生变化直接退出8 M/ U( k- c0 s3 E1 I$ `
- int saveEnv()+ v( d1 Y5 o. P4 Y. P$ M
- {! w6 ?) B& E8 r
- int i=0;: z% i0 ]% L& b- G! [6 k, k
- uint16_t crc;
4 c5 x- W7 J" ~8 D3 l. p V* z - uint32_t da;. N) R- A1 s6 }3 m: u& t/ A" I
- crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);* W' x1 x# v& u5 W$ H8 W
- if(crc==Env.crc)return 0;
/ l5 S3 c* R8 \5 _: R6 p* B - Env.crc = crc; . G7 y+ K3 X0 b9 f
- FLASH_Unlock();) K7 p+ E1 j9 u0 x) }
- FLASH_ErasePage(SAVE_ADDR);
4 L% K# |$ e/ V c; h - for(i=0;i<sizeof(_env_base)/4;i++)
7 H6 ^ a. k/ z2 q: u3 r2 K - {$ a4 i0 d7 ^5 l3 v8 N6 J5 e% E! q
- da = *((uint32_t*)&Env + 1*i);, L1 u8 j6 y" w7 j" L6 Z/ P7 k
- FLASH_ProgramWord(SAVE_ADDR+i*4,da);
5 s2 l* g) \/ U# ^# U: n: J - }
% H& p( J _: o! d9 c9 G! U3 N - FLASH_Lock();
) R8 O- I, ^* E( [! \2 I% F - return 1;
3 X9 ~6 H1 q9 O5 P% t+ ~6 i - }
5 W( `5 n7 |" h1 [4 D - //读取
: R \" N: |# j. [) F6 a, k; y - int readEnv()$ I Z6 Y8 K- C9 a) |0 Y) d/ h5 U
- {/ l8 B3 g6 v9 }( n( P" |8 u I
- int i=0;) W* W5 d6 ?4 Q- |
- uint32_t *p=(uint32_t *)(&Env); K( _# e# C+ z* q8 K- I
- for(i=0;i<sizeof(_env_base)/4;i++)
, R$ T [4 I2 H, i* {" r( ~ - {! R! k3 S, c3 d% _, A1 u b
- *p++ = *(uint32_t *)(SAVE_ADDR+i*4);
3 {4 g8 g* n& l5 D% I: b - }# P4 w3 k) \3 h; H
- if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4)) p( |0 O8 B* {+ f
- {
+ y1 f$ T8 c2 g( e# r2 R- m! G6 F - return -1;
6 L3 V7 S$ t6 P - }
0 W0 Z `% u* s$ W - return 0;+ | o( }" j# U/ W6 ]. k5 X
- }
6 |9 a" {- O, J - //初始化
1 m7 R' X2 \/ o, f - void initEnvironment()0 r4 I H1 k& Y) X8 s7 Z5 |
- {
. G2 y; y# F1 ~. P" ?2 L - if(0!=readEnv())$ L; h3 i8 V+ I8 y/ U% k+ Y
- {6 t6 L3 m0 |- c1 J
- tmc2208_set_default();//一个配置组默认值4 B) \5 l& E- ?) t6 T$ M
- spin220_set_default();//另一个默认组默认值/ B8 l* F' P. U
- saveEnv();
# v. m9 `4 U M' W+ O9 f - }
% y4 R& @ p' u2 w - else& o" B' I1 N# i6 G, y" e+ D( F
- {
1 ?% G! L q. n4 |! @! N0 t - //tmc2208_set_init();//针对配置计算运行时参数0 w( D8 S1 T; o2 e- ?. _
- //spin220_set_init();8 }2 J% e$ E3 I: c, o% P
- }
3 C* A* v9 w; U" S$ X5 j+ ?" z - }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。2 I% I" y0 l7 |9 k, H
Env.h
' ^9 z+ U5 _' B8 C- #ifndef __ENV_H
4 a9 b- Z$ j3 i2 c* p! Y - #define __ENV_H
$ D! z/ {: w9 v3 L. u3 h - ' ~, Y3 o+ g3 \- _
- #include "stm32f0xx.h"
& f1 G8 y& U6 Q( E6 T7 N: A; a* O - #include "tmc2208.h" U) @2 V: h. e
- #include "spin220.h". o8 Q# R9 i( t6 R$ W+ }
- ' Q; f$ @, ^& X0 q+ R e3 Q
- #pragma pack(4)
3 i+ ^5 U) b! G0 B3 m; D - typedef struct{6 a( }: P' O# H# E! U# j
- uint8_t micro;' h9 i6 A$ o4 i# b6 o
- uint8_t fullStep_angle;8 a* S9 g# `( ~, A3 N
- uint16_t start_speed;
. F+ [" z. A0 } - uint16_t max_speed;, P( T n, _6 ~$ r% V& I
- uint16_t min_speed;5 i0 V0 z, O' ]7 P
- uint16_t inc_distence;9 ~. F0 b" u8 \
- uint16_t motor_max_current;$ `( E0 ~$ F' w" J9 H3 c9 a
- uint16_t motor_resistance;% A. h' Y# K( u* l' Q$ A8 B
- $ v7 {* ^. y5 u/ s# X
-
3 W0 f2 Q3 T0 J2 Y# L" v/ J - uint32_t pos;9 ?& K+ T0 Z. D) @
- uint32_t speed;- L+ {" }$ ]" J# T- H; K v
- }_tmc2208_set;+ n0 p+ b2 T: i
% _1 c; K. q6 `' W0 @. d# I$ G- typedef struct{7 F6 l8 E* t+ }) M, C1 ^# \
- uint8_t micro;0 q( @: v O+ |1 h
- uint8_t fullStep_angle;
2 V* f* y W" R# h$ N - uint8_t grat;+ y7 I0 @9 v( B
- ) m8 T4 r- O9 o8 ?3 j# q* @
- uint16_t start_speed;
% D8 X+ ^ m" J9 U& ?( v - uint16_t max_speed;
5 F' d) B2 j, v0 O: F: H4 i7 V - uint16_t min_speed;! E: W& Z; b) l
- uint16_t inc_distence;: ~2 d8 C5 Q. h: z$ p( }
- BitAction max_io_value;. v- R# ?! f8 i* c
- 8 \9 h# K+ h3 t4 ^7 t0 p
- uint32_t pos;
! o# o3 f, X/ ^$ d9 r4 m9 | - uint32_t speed;
5 I1 m$ Y4 Y8 ]/ @ - 6 M, {$ q9 S& t
- int run_F0;$ V! W6 \) J' Q
- int run6_max;; _2 R/ }8 P; b5 s& ~3 y1 ^
- int run6_min;8 U( ~( C- R1 F( t# u4 E
- }_spin220_set;
. N; Y4 C& [) X0 q. B8 c6 U5 G$ o - / a4 [0 l9 v3 n; ^
- : K e2 L5 s$ Q9 c. n
# s& m' t2 i/ |
$ \* K/ _: {% [5 s" x- typedef struct{
" i/ W# |4 S U - _tmc2208_set tmc2208;
: X5 `! s5 [6 d: H" h! c7 K - _spin220_set spin220;& x v- {! B+ Y& l8 u' R
- uint16_t crc;; T/ i+ q! r1 q. P
- }_env_base;+ v5 R+ ~0 h7 s5 t6 W2 F& l, {
- #pragma pack()
* T8 X8 h f1 h2 ^, M$ b - ' s, Q! l3 l* V) H9 w
- extern _env_base Env;
' f/ ]+ l5 ~# k* v - void initEnvironment(void);
3 l2 q# ^# R8 h* S" n* O - int saveEnv(void);6 ~. ~( q4 Z* c# |) L- J
- #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可, T8 f( D* P- a% }3 _% [1 J4 F
. B# c' t; \6 D. E1 w. W. z% D$ h- void spin220_set_default()7 A5 A/ V7 [8 G0 e7 D
- {
" N" y8 N8 Q3 |0 a% u) ^# M - Env.spin220.micro = 16;- i, x% v) f T- G
- Env.spin220.fullStep_angle = 18;
3 p9 [" E& ?, d) k4 t - Env.spin220.inc_distence = 2; [- ]1 h; v3 G1 O) |" Z) @. g
- Env.spin220.start_speed = 60;//
) t" p( n/ [3 B5 m -
: @. s! r P6 S* H; v' ~ - Env.spin220.max_speed = 4000;' y% r" L/ R) [
- Env.spin220.min_speed = 60;8 d/ `, w" ?: A5 j
-
& c; B# [) P0 X0 P5 H- F - Env.spin220.max_io_value = Bit_RESET;6 i" I, ~2 T G1 V. B
- $ ^# A% v5 u, ^* k9 x: H- N G
- Env.spin220.pos = 7200;
2 b& Z' h$ W# O- f1 N- i0 M$ f - Env.spin220.speed = 4000;
" h) B4 W2 k8 g: q2 @6 T9 A - 1 x6 V' ?, I# X- ^6 h0 X9 j8 Q
- Env.spin220.grat = 0;
* I2 l. h2 I$ N) u) l1 L* S$ x @ -
; [6 i" K: K/ v8 d# t' s - Env.spin220.run_F0 = 16;
6 F2 {. W& E- y8 @ _ - ; ? y9 r8 s5 b
- Env.spin220.run6_max = 0;2 n: ]! j8 p5 I. y1 z
- Env.spin220.run6_min = 16;
- X7 |" K& H- R' A4 ~1 o -
; U( `0 J4 Q8 C& v* N9 W2 v6 H - spin220_set_init();
7 y+ D8 _% `0 J! V- K E - }
复制代码 至于xxx_set_init()根据实际需要了
2 ^. s3 r* o2 O0 Z0 X# `
5 O. M- r+ M1 s+ D! C
+ J; x w2 x% v$ K) Y
4 |( A+ G1 w+ n' k4 x$ J9 {# I& T% ]& y+ h7 ^; k0 d2 b
2 d3 H# m( L/ E4 S' Q |