很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,7 y: B! z1 f, w
env.c: @- _* n; h& W+ J( n# I; T
6 N E3 V0 S" D' |$ m8 _( n- #include "env.h"; }8 J. K, F7 P
- #define SAVE_ADDR (0X08020000-0x400)- I) I- G0 c% L/ H4 b4 \1 f) W4 U9 e
- _env_base Env;
, W5 f" I$ K2 u3 S, c7 U3 } - uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)- r% y0 F- u# F- |* T2 g$ f7 p
- {2 s0 x( O0 _! W" _9 q8 U1 E
- uint16_t i=0;
# x/ {9 X; M# ^6 j - uint16_t j=0;
3 z1 b4 ^' t. T3 O; y - uint16_t crc16=0xFFFF;
" Y6 g3 W- ?$ D. O - for (i = 0; i < usDataLen; i++)3 p" j5 ~8 ~* r
- {) O0 G. H! X/ R; @
- crc16 ^= puchMsg[i];
$ W9 a9 W; w" i$ T q8 L6 ^ - for (j = 0; j < 8; j++)
: u/ j L+ P1 `1 W - {
8 S+ b [9 r& c$ i4 P - if ((crc16 & 0x01) == 1)
" P5 W& `9 q% K - {
" U* m3 B5 Z* x8 Q* a% } - crc16 = (crc16 >> 1) ^ 0xA001;
7 D D6 [: t3 O - }
% c8 o# ^& }: ~. E' _( J0 x+ b i; c - else
E3 N5 M9 r2 ^8 k; q4 H - {
2 R1 p8 o1 I/ E' C# x* _. m; y - crc16 = crc16 >> 1;
n5 w, j0 D( ^/ u- e7 s$ m - }1 ^4 ?! P! a. T0 U2 r
- }
1 y- O2 X$ a: v( K7 { - }
: }0 l2 s1 c0 E" n- ` - return crc16;
; x) S, G+ b7 h2 Y" T3 d - }
! P5 Y/ x: N, O$ p( m& j - //保存值,env没有发生变化直接退出# A: O3 f- |0 R6 a
- int saveEnv(), n5 |4 C4 B8 }
- {
( _$ m. U7 q& p7 a" I# {! O3 T - int i=0;
/ r. C N3 E2 C+ s) \! s - uint16_t crc; {0 u, y0 V4 P# Y% l+ i
- uint32_t da;
9 k* l! R8 W* o, j9 S - crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);
4 j# L, V5 d0 H - if(crc==Env.crc)return 0;" f7 ?' F4 N, f, a5 t
- Env.crc = crc; 3 ]3 L7 t$ |' ~; v) P, j" B
- FLASH_Unlock();
$ n+ t, x4 D% X* N" } - FLASH_ErasePage(SAVE_ADDR);
9 G- P/ v1 [: y; A - for(i=0;i<sizeof(_env_base)/4;i++)
) }8 s5 N( e$ H, ? - {" u. {. q6 m, W
- da = *((uint32_t*)&Env + 1*i);
' v: J+ \- p- q& x$ u - FLASH_ProgramWord(SAVE_ADDR+i*4,da); O; x" m# Y& i
- }
5 ]: z2 U- b) `7 y* {! q - FLASH_Lock();
" O; j/ u) B+ x1 V# [5 F - return 1; R4 I7 q2 _" r; m
- }
1 y+ X7 W8 ?2 H1 M5 P- f - //读取
2 o* Y, `7 R% p) L0 t2 u ~! P - int readEnv()
3 i3 N6 T0 o( l - { G1 v( p) N( Z/ _" f
- int i=0;
% ~/ S& n' ]) j. h8 x2 v* X+ t - uint32_t *p=(uint32_t *)(&Env);
3 ?+ y. d5 h$ s" J - for(i=0;i<sizeof(_env_base)/4;i++)
0 W- x% i; _0 r5 |+ d% h4 j, N5 o: u - {5 g8 p8 [- `% X) s0 z0 A
- *p++ = *(uint32_t *)(SAVE_ADDR+i*4);
; x* x" Z) h+ C2 L7 X; \ - }. D3 l: [- c3 I9 g
- if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))! N3 m' a0 f0 [8 ?' Q4 y2 S b
- {
( {! ?. E, R- _- t. {# m z - return -1;
- W0 Z, ~) t5 [. j$ `; O# ]& P; W# w - }. F4 i$ r6 Y" ]6 k! U2 D/ m) _7 A
- return 0;
" R- m% D" o: X' f3 M - }/ p% X; `* {) K; m' b, v5 I
- //初始化- x7 t5 `2 M8 V Y" n
- void initEnvironment()
& y4 _( [$ Y. w7 a - {& t: {+ j1 o8 T4 |- }6 m4 o' D
- if(0!=readEnv())
6 S4 r* L4 l0 \1 W - {# A6 ], W. G9 K; M2 w* s/ Y6 [$ }
- tmc2208_set_default();//一个配置组默认值
& X5 T1 a: r' E8 S" ~2 ? - spin220_set_default();//另一个默认组默认值
+ g5 H, a' u9 p! N! _8 v - saveEnv();7 Z8 K% l+ L& [0 g$ T# \
- }
. g2 U8 t8 J' l* j - else- h3 f+ ]) u0 T) |
- {% r# o; \$ @8 `. g& f
- //tmc2208_set_init();//针对配置计算运行时参数
+ l1 k1 K* c& `' q* X - //spin220_set_init();7 O+ ~5 @8 N; r- {7 d% ]
- }1 h+ u- u& n" o' J3 N
- }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。
8 a- z- p* K2 z U, rEnv.h$ H7 S$ x* O3 h1 G
- #ifndef __ENV_H
$ C, e0 N+ r8 d7 X7 a6 r - #define __ENV_H+ C5 t9 M& z9 j I6 K H
/ {- s& ^5 x* L* P3 \- #include "stm32f0xx.h"
4 j9 _7 u) ?* E5 R8 X - #include "tmc2208.h"9 C9 Y2 N2 G+ \7 }
- #include "spin220.h"5 i. W' Q) S f
- 9 d2 H& A$ N# P
- #pragma pack(4)
, S4 s' d" v, l5 ]5 x - typedef struct{
# o9 w, S8 g, o0 }7 e/ \) z - uint8_t micro;
3 R$ `1 X$ k- W/ ]6 ]/ b - uint8_t fullStep_angle;
# \# V- N7 ]8 j& b0 h - uint16_t start_speed;" V. h2 a) y1 M% w( F
- uint16_t max_speed;! R) s/ F! |+ [% A! X8 w6 O0 l8 Y
- uint16_t min_speed;
$ ~7 ~. m7 _0 m. w U - uint16_t inc_distence;
* V' v+ l. P7 { | - uint16_t motor_max_current;) K5 C& W L. G
- uint16_t motor_resistance;
* U. U' M6 C. N" _# d8 s1 j -
' S) z3 Y( P6 l) Z- T -
' b2 U3 @) |: A# `2 U1 ~& t, P - uint32_t pos;
# N1 ]+ i+ w& m8 @. B1 u2 o - uint32_t speed;" p T- Y7 ]( {* R, H+ {/ W
- }_tmc2208_set;
* y2 n% j0 n' a/ ~
1 p( |! r4 L% Z; p7 f1 i6 {- typedef struct{
5 O# |9 g8 |1 r9 Z - uint8_t micro;* h6 E# s9 f, v. l, d- B0 N
- uint8_t fullStep_angle;
I3 q1 _3 k9 }5 Z - uint8_t grat; A# i% D$ b! A: b' {7 ?! m
-
& |1 T* x0 V! H' o: F' [' Z - uint16_t start_speed;
0 V. f* R- Z% _+ }4 f - uint16_t max_speed;
' f' B4 ]/ _& ]6 C - uint16_t min_speed;
; [" }9 j" M# `# Y- c - uint16_t inc_distence;1 T! y- g+ r; ?4 M/ |- F
- BitAction max_io_value;; M/ p# B3 j. u! X+ b$ X: u
- 9 G% d( |/ J/ A8 c; y1 ~
- uint32_t pos; p5 @* X; @/ B* ^
- uint32_t speed;/ Q! _! B- k+ v& X$ H: b
- . T, d) H, V, w- r( d) B
- int run_F0;
( l" W4 ^. ^/ J1 r; ?0 A& R - int run6_max;6 w, g7 h& E( y2 a: ]! a
- int run6_min;
" W9 A# [* X2 F _3 u2 X, T" _) y - }_spin220_set;
8 ]" K5 \, L8 N5 R# s6 _7 n l2 x( B - % h+ ]1 B6 F: j( m- C
, M( W" L4 ?; N& a- 5 ~/ T% B: G8 A# Q7 ]6 z
- 3 z- _/ S0 _$ n0 @
- typedef struct{) g9 J* k# `2 M4 I! C
- _tmc2208_set tmc2208;2 m" L- N% C9 O1 Q: l
- _spin220_set spin220;& Q; ^- H+ G' O0 X
- uint16_t crc;
% c. i' [% F* S. V# V2 B _ - }_env_base;
`' p8 p/ g/ n$ W" C - #pragma pack()! L. }/ }5 y7 x7 C9 B: E
- . V" h2 C5 i1 V6 C5 j4 U1 @
- extern _env_base Env;: [5 W9 S# C! o* C, q' F0 Z. P4 q
- void initEnvironment(void);
6 r- Y ^4 r: N, n# h1 [ - int saveEnv(void);
5 ]) M* T# D6 n9 j1 G t D" o1 Z - #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可3 u) y# Q3 F) a/ d
- - y O- d/ s5 c. U2 J* E; P& r6 w+ P
- void spin220_set_default()
. C* [) ]! N; Z( l& V( k; k4 u& f# ~) D - {
$ J# c$ q2 Z, z( v+ m - Env.spin220.micro = 16;
, H; [$ y! Y6 V5 k/ G& }: {5 _& _ - Env.spin220.fullStep_angle = 18;
; W) l! W7 w" O. P" A* z - Env.spin220.inc_distence = 2;, g# W' l5 Z& H# b# |
- Env.spin220.start_speed = 60;//
n0 M2 w4 `6 m7 {+ o -
, V+ v6 S* y6 Z, x6 a' t - Env.spin220.max_speed = 4000;9 M! }7 l- \! c7 z
- Env.spin220.min_speed = 60;* P; G+ R7 ]) b9 r+ w) d4 v
- : }$ n+ p) }. \/ i* d
- Env.spin220.max_io_value = Bit_RESET;# E: F* T1 T8 R! }* c
-
) f# q! \' N* ?" A4 c - Env.spin220.pos = 7200;
9 i6 N6 [( |, } M - Env.spin220.speed = 4000;: Z) f3 a! h t9 r+ }
- . q% d9 v: x2 C/ p5 h' F3 t
- Env.spin220.grat = 0;& e) x- F/ ]* x( h" ^8 F% Q
- 1 D. R: P8 f% ^# [3 R1 _& J8 _
- Env.spin220.run_F0 = 16;
+ f: \, U. q/ ]" C7 N" M- H -
- I/ }+ ]5 m2 f5 M l - Env.spin220.run6_max = 0;5 Q$ _3 Y* I4 l6 w+ u2 r
- Env.spin220.run6_min = 16;
O: I1 k5 J# q% X- G - % t* d/ P$ f; B
- spin220_set_init();
7 r2 \+ y7 w$ R+ i - }
复制代码 至于xxx_set_init()根据实际需要了) B" L# }1 A3 g$ S; @* Z
/ U U' o/ u& V/ f$ i
7 B5 Q- O$ Y; c- [4 d
- u( a6 b8 y5 t0 K- v
( H* R2 ^1 X, M6 v. Y& L
, E" o/ K, E# Q1 `" X
|