很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,5 X0 d+ F$ E1 `# d. _$ F5 a. ^0 ^: c; M
env.c
( W/ t7 q" W# T/ m4 @
, V9 `& \$ ?1 e2 f- #include "env.h"
! K+ b$ S6 L9 l$ Y - #define SAVE_ADDR (0X08020000-0x400)
; M8 V, m' k2 J - _env_base Env;
& {2 B* b; b$ {, t - uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)
8 Y/ U9 S J8 M! P4 v s4 W - {
" |9 j4 l* c& W+ E - uint16_t i=0;$ I6 P! t: j0 Y9 P& |6 z& F' ~
- uint16_t j=0;
7 z f V+ u+ O, @& s0 w$ m- U - uint16_t crc16=0xFFFF;
5 ?4 y: A; T( A4 R+ O8 s - for (i = 0; i < usDataLen; i++)$ n# [" ]; t/ K X. p
- {
# W/ G% x6 k I* j! f+ P4 | - crc16 ^= puchMsg[i];
1 A* a% I/ Q+ G5 z5 b& `8 E0 Z) e5 U - for (j = 0; j < 8; j++)
3 b: z' s6 D r - {
2 f! ^6 T8 v' M2 t: @+ H8 Z# X - if ((crc16 & 0x01) == 1)
! M. P. E7 A8 N' C5 k% V - {6 J1 i$ k y+ F6 A) h! p1 ~; u6 F
- crc16 = (crc16 >> 1) ^ 0xA001;
1 P) v0 Z. I3 F: Y, n# Z3 b - }
6 }3 f. ?& N# F0 S - else
; W8 u. E2 t8 n! `( B - {
* Y- L" k+ b4 i2 p T8 r `( A* v - crc16 = crc16 >> 1;
) B3 O9 B& \; X# f: b2 H1 A8 _ - }9 c0 @; S- _% U: I8 n
- }0 ^+ o% X3 {4 W; n5 p7 m
- }
! U0 C( m( l! d0 s - return crc16;
# x0 l, e9 U$ T7 h - }
' X8 x, C/ d. J8 Q1 o. T, x - //保存值,env没有发生变化直接退出
5 [3 K; v; f2 F' v6 B - int saveEnv()
x: O, D' v$ ?3 U - {
5 q; K6 f( i o - int i=0;) W- r' @: p! j8 I# \% a& N- A1 o
- uint16_t crc;# v! k: N% Q% Y9 A1 y' X) e! X1 ~
- uint32_t da;5 @2 Z* R2 t" [) f
- crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);
3 X, W. P( ]/ m3 a, y: s# k - if(crc==Env.crc)return 0;1 d- \$ W2 G$ s+ S" J
- Env.crc = crc; ( Z F/ H! \: w' G
- FLASH_Unlock();4 @/ s# z3 R$ t c
- FLASH_ErasePage(SAVE_ADDR);
) c# h: K7 Z: J. ^2 w - for(i=0;i<sizeof(_env_base)/4;i++)
1 ^! i5 S" S. p; z& K6 o- a - {) U. p& a4 x1 P! ^* c
- da = *((uint32_t*)&Env + 1*i);
8 N: ~/ N( e2 l1 \ N8 Q! i" h2 V - FLASH_ProgramWord(SAVE_ADDR+i*4,da);
! K. n3 M; z w! A - }) h0 {# b3 _$ [9 }! f, k
- FLASH_Lock();
5 u4 q M# Q5 H4 Z- s2 A: l - return 1;' ?- A1 t8 B9 R/ N- I+ s
- }
$ Y& p I" c7 t - //读取
% G1 D$ c8 y8 i9 N% d) i - int readEnv()
4 N/ i* d5 X3 Y7 `8 L - {
) T# [% }. N2 s; w) m! S - int i=0;
! [& s4 U% U& r! [2 Q1 r - uint32_t *p=(uint32_t *)(&Env);
; @/ E; I7 b3 ~3 X8 O- H - for(i=0;i<sizeof(_env_base)/4;i++)
# z8 G( w2 ]' w; I5 C1 D# l - {
; y5 \/ W9 O# m4 h. z - *p++ = *(uint32_t *)(SAVE_ADDR+i*4);% K9 B l8 `8 p- Y- T3 q4 x
- }
$ V. q. _5 W$ H0 B# A7 o2 I- S - if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))
! B+ q0 @ k* v& {: M - {: F9 q @/ w8 }/ B* w. _
- return -1;
) V0 Z: o: f* Z, L+ c - } k3 }7 i+ {& p
- return 0;
- m) ]* J/ l) z5 m( t# `9 H - }* z2 O6 B `* _+ k7 P2 r7 L9 @
- //初始化2 q x( ~& A6 j5 B+ J8 z' e" W
- void initEnvironment()
/ Y; W# T7 D3 o, @$ L& c- l* j) u - {
' }" \9 j! t5 o5 n" E - if(0!=readEnv())
9 u" ^& K8 z# B {- h - {. x! G: J! F; n- b
- tmc2208_set_default();//一个配置组默认值! s9 z( s3 |* I8 g
- spin220_set_default();//另一个默认组默认值4 N( U7 C \8 I8 _6 ~4 U
- saveEnv();
4 p$ H \% B3 Y; H R - }
6 b2 A2 K. h T/ o - else5 |- o3 Y* E* C7 a7 b
- {# F E- b4 z3 X- D. V
- //tmc2208_set_init();//针对配置计算运行时参数
7 M P2 ?, `8 D, g9 B% U8 g L* J* ~ - //spin220_set_init();! s. u: P. S/ |2 c+ j& B
- }
/ @# v4 w) u& b, ?: w8 B - }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。, l' f/ F9 P+ q& e! t- z, r, [; |
Env.h
9 A6 E" M7 c! W/ ?# L- #ifndef __ENV_H7 W d, j6 ?! M! F0 d, T P. @
- #define __ENV_H! B3 }6 B" M8 z" g
- 4 F j' @7 |* c: S& V5 n h
- #include "stm32f0xx.h"
4 ~% V$ g( o, s5 S- A8 K - #include "tmc2208.h"1 K/ l! K, o9 t- L5 c, w1 f
- #include "spin220.h"0 M: j8 O4 y9 j1 T5 J" T, [
" w; a/ w4 ~9 T V! J- #pragma pack(4)
# i3 j3 y0 I6 L# U6 I- Y. M - typedef struct{! G1 F; x5 q; d
- uint8_t micro;
0 j# V% }1 @# l4 N3 q0 k - uint8_t fullStep_angle;
6 a+ E9 j' ]8 U6 I N8 O - uint16_t start_speed;
3 y" `! I- J/ Y$ ?$ i. H/ n - uint16_t max_speed;8 g1 I7 A, w# J2 c1 j
- uint16_t min_speed;
/ B( b; N1 q$ {+ I& V - uint16_t inc_distence;
" I3 v% p4 n& A* D# Z0 } - uint16_t motor_max_current;7 [2 M- {. k$ V: Q
- uint16_t motor_resistance;
( W5 d; U" U. f1 q -
) Z {0 V8 \1 r% g" w - 9 L1 ]1 P4 D4 u; o+ p
- uint32_t pos;
; O/ _5 X- F$ ]0 G+ h. J - uint32_t speed;, g0 Q. R2 G* T
- }_tmc2208_set;5 M) z3 a* x4 I1 C2 _* D
- ! N. l% r# A5 B( M" _3 o0 [0 H# {% W
- typedef struct{
4 x( O# W2 d9 ^9 C) ? - uint8_t micro;
" r V5 s0 T, Q$ i; r. X - uint8_t fullStep_angle;
0 r6 M7 U$ ^- M9 \) ^ - uint8_t grat;5 n: o) M" W8 D, h( p j
- $ y3 Q/ R {8 `# s/ g* }* p
- uint16_t start_speed;; {: f& Y( o0 j6 w$ s# s
- uint16_t max_speed;
$ \' a2 v& ? p K% y7 L9 \ - uint16_t min_speed;: C0 M' q) m+ | o
- uint16_t inc_distence;
& p+ @# q' q& r& L) ~0 X2 s# i - BitAction max_io_value;
8 Q% c/ [) A2 T9 B! s -
* g7 b2 M& m5 [1 R2 l' p - uint32_t pos;# Y* ?. P; s/ f4 k
- uint32_t speed;
+ v8 X6 r, D: [0 J& V -
. s2 ?, o) ?5 U' w* x/ h - int run_F0;
0 S& g. B* e: i6 ]9 t - int run6_max;
" K+ b! b8 ~6 e" u - int run6_min;
; l: K3 i j) W) v - }_spin220_set;( S% ?+ q* t" E9 z! k- s
- & O( {' ?# g9 E4 x
- & P. D) V0 l* L: ]- {2 s0 f
- " u6 e% b6 V) Y/ z/ P1 [! n: s
- ! e8 C1 p4 x; {
- typedef struct{" U' A7 P1 F9 s0 s
- _tmc2208_set tmc2208;- r: ]" N; l T# u: B
- _spin220_set spin220;
2 b" E1 k; Y& l' @4 ~- y" { - uint16_t crc;% {$ }( X: V8 G; ]7 o0 u" r) T
- }_env_base;; ^& h! ^) Q! Q: S9 B1 R/ P# ?! X/ i
- #pragma pack()
; E& V: O6 _1 d0 z+ ~
* g8 q' Q0 r7 l5 }! u: _- extern _env_base Env;# X" J/ m7 _2 I `* Q
- void initEnvironment(void);5 J& ]4 h; @' B2 ^1 q9 M
- int saveEnv(void);
# Y/ q" _2 i3 x6 ~4 s - #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可. Z4 a3 M+ m# W2 g& [' A; F
/ A3 b3 @" _. W: v$ R$ \- void spin220_set_default(); r b7 R/ l. m2 Z; W/ I
- {5 D9 A& F8 Y' N4 F
- Env.spin220.micro = 16;
+ S5 ~% T( Q2 C - Env.spin220.fullStep_angle = 18;4 _5 u/ I7 s; u) p) i# `$ `5 ], {
- Env.spin220.inc_distence = 2;
1 ?# }7 `8 i3 r& K6 s; X( _ - Env.spin220.start_speed = 60;//
. A7 T$ L3 `' Q: V, Q8 k; W -
. Z, E; I' q5 p4 O% @ - Env.spin220.max_speed = 4000;7 r ~5 j' g! {+ h1 ^% M
- Env.spin220.min_speed = 60;' w) c y9 }3 F6 d
-
, _3 ^/ p. d1 `2 y. B, T: S; O" u) ` - Env.spin220.max_io_value = Bit_RESET;" o1 y* q* Z& P+ B
- 3 s# _$ {' p; x4 p* S; q6 R
- Env.spin220.pos = 7200;
4 s" G X1 C+ n R8 P, ] - Env.spin220.speed = 4000;; s' w, J0 R4 r6 V( b7 u
- 8 D8 L" S+ y3 o/ z% e
- Env.spin220.grat = 0;
# f8 G5 j% T* a' Q -
+ y2 e4 |6 A: ?' y J/ {" t$ q - Env.spin220.run_F0 = 16;; G& W( |6 v& o) I; z6 C; @
- ; _3 J2 l4 i9 q; a
- Env.spin220.run6_max = 0;
: o- t1 O* ]+ D* ~ - Env.spin220.run6_min = 16;! s& w9 `% w6 o9 v% u% ]
- : B9 E4 G# b8 T6 b! d
- spin220_set_init();* Q- D0 I O, s+ ]/ y
- }
复制代码 至于xxx_set_init()根据实际需要了9 ^6 v! S. z# P, C4 K2 s
* x$ E! |6 J* w) ?* G3 y& B" [. K* g
1 Y+ h: n5 ]& A+ e# F$ J
& Y& K6 n0 y4 I) @* f& _; G5 }' O ~4 Q& f% C3 S4 H# w7 {! m
/ L, T5 @6 \* o
|