很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,
# b& o/ g0 ?2 B# U8 \8 U2 U env.c- s& x% @0 I! H' O( h$ [
, S y* z1 E; n) ]
- #include "env.h"0 R# w) C, J2 d; P* Y
- #define SAVE_ADDR (0X08020000-0x400)
8 U% B& g0 o$ }% D - _env_base Env;: j; I3 n5 l$ L: \ W5 b0 ^
- uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)
V9 e4 _9 Z: J0 ]1 { - {+ p0 V k. W5 f. g+ f
- uint16_t i=0;8 C! T& C; B4 i& h. L( d$ F2 N% K
- uint16_t j=0;
! l0 N: h' t! r' j - uint16_t crc16=0xFFFF;$ x" Q" ^+ n. d) |- E
- for (i = 0; i < usDataLen; i++)9 f7 A: g6 X( r5 N D2 _6 }
- {3 W1 l m; S3 y( n3 H* U* ]
- crc16 ^= puchMsg[i];
+ A' b% B7 g# U, y: i# W - for (j = 0; j < 8; j++)
! K! X+ X7 y( s - {
5 e8 H* O$ N! P. a - if ((crc16 & 0x01) == 1)
5 s7 C8 }- r+ o, Z; S& l' v: F - {
" B) G& Q/ v; O' K& w4 O - crc16 = (crc16 >> 1) ^ 0xA001;
5 i e$ e6 g" A4 o/ ]$ R6 r6 p - }1 d1 H2 Q% g4 w' Z" V
- else
7 b; X. K' F6 g3 d/ _3 O - {
; R' F) p. d- Q* N - crc16 = crc16 >> 1;
3 G9 ^! J5 H+ B S! k( @0 N - }4 d. ~5 i2 q5 ~- m4 g. X
- }
- m6 E, {" C9 t" d6 R - }
4 D7 c9 A* P7 z( B2 `1 L: t7 M/ W, m% g - return crc16;
4 P+ z/ K" h7 g* S4 }6 p% n - }: A1 l8 j. i8 i
- //保存值,env没有发生变化直接退出
& p+ n7 p+ ?# q; N3 j - int saveEnv()
& |* Z9 {$ ?3 R' u+ D - {
& M6 {. G2 j7 e" u9 a( p/ ] - int i=0;5 h# y9 J9 k3 ]0 I d) M
- uint16_t crc;; j$ z* O7 B- s# G% V; V6 H. a$ a
- uint32_t da;
' e: V% q/ x) r1 w/ r - crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);* t) {. G; u8 k( I0 D+ n, Q
- if(crc==Env.crc)return 0;0 h2 T1 X8 D! d4 H, T
- Env.crc = crc;
- |0 d8 _. K7 i, n4 r - FLASH_Unlock();' |. k0 K$ D0 t5 w( M
- FLASH_ErasePage(SAVE_ADDR);' K- `+ `) R. P
- for(i=0;i<sizeof(_env_base)/4;i++)
% z% }7 m$ z8 ]! e - {
- M' |. b/ U. B n - da = *((uint32_t*)&Env + 1*i);. j! L+ O. U! [, \0 i) n
- FLASH_ProgramWord(SAVE_ADDR+i*4,da);
' z2 A; G# U2 Z- c4 K- Q - }* Q$ y4 E6 u8 H# x% Q
- FLASH_Lock();
$ Z- [+ d! h" l1 } - return 1;
" y- d8 n8 m) j3 D4 J5 C) B9 y( U5 P) T - }8 F$ @6 J% n3 {5 l& |9 [, h
- //读取
! k) o: `! l# x: R T; m - int readEnv()1 p( ^3 v( W3 x0 z* n" T- o
- {
5 p% d6 @# d' C: E0 T# F) ? - int i=0;2 p- ?7 w! p* n- m! T" I$ H4 ?3 k
- uint32_t *p=(uint32_t *)(&Env);' i, l5 r+ l; i, R- g5 }
- for(i=0;i<sizeof(_env_base)/4;i++)0 K. T3 }# r/ F: n: B
- {
2 ^+ R( G5 {: m6 h8 N - *p++ = *(uint32_t *)(SAVE_ADDR+i*4);6 D* v( n, k% N6 W
- }$ o" l0 `* b+ G' ^$ L9 C& T
- if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))
0 [7 c% L6 W9 p; o - {- [+ r; |5 |, O: B7 e
- return -1;
" R- [; s% _* f, K i* @( j - }
% K" H- J& [6 b* v7 C( i* u - return 0;# T- S9 w. ], f' C \& ^0 X
- }
+ ` n7 `9 d$ h8 g- O - //初始化' K7 G* _# A: ?
- void initEnvironment()
: ~6 k/ K& O! @6 @ - {/ ~. r, J: K/ @) @) W% z
- if(0!=readEnv())4 d% F% d$ f/ \* K5 `) h0 @# U3 F* _
- {
& N+ @2 H4 \! k# O& J: A. F - tmc2208_set_default();//一个配置组默认值% t$ l# e) c: t0 T
- spin220_set_default();//另一个默认组默认值
8 l0 ]5 e' c% i; ^! U1 l9 i( P - saveEnv();
1 ^9 R* P7 Q" z! A. d( C- Y - }5 f6 M& N. H$ X* f( F$ Q S
- else
% a3 y7 t& X" M6 o0 v7 c( F - {( u4 N+ C3 p" {" w7 I
- //tmc2208_set_init();//针对配置计算运行时参数
, m: M5 f( u3 u- I7 f0 a0 n - //spin220_set_init();, a* N/ p! J. G; Y7 ?2 S
- }" k/ w$ B% {. e! `
- }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。* Q$ h* P) a/ X% C
Env.h
" J1 p$ u0 w7 O# q- #ifndef __ENV_H
1 P2 {3 i! {4 b2 N - #define __ENV_H
3 k1 i; H/ ]$ ^
6 c) e% [6 i5 G" ~* [- #include "stm32f0xx.h"
9 ?7 A( E6 b, s - #include "tmc2208.h"% x: k- q. X- D, w
- #include "spin220.h"+ m+ i3 L) ^. ]! z1 T
' D% o. s4 V1 ^5 q1 H- #pragma pack(4)
! O, H7 r$ L, N# O - typedef struct{# \% z* y [8 {- s
- uint8_t micro;
8 g, v4 Y5 ~5 A6 u) p8 K* d, ] - uint8_t fullStep_angle;6 J$ z* q% B7 R& x4 z
- uint16_t start_speed;
/ D9 ^8 U: k( N# @$ j - uint16_t max_speed;
B, s7 Q2 Z" P2 h) @ - uint16_t min_speed;$ c7 f% t7 Z- g" U; N4 U+ O f
- uint16_t inc_distence;
8 i% n3 }% w' b2 b3 e! J$ p: d - uint16_t motor_max_current;
. V+ ?6 v& g" U9 s: Y - uint16_t motor_resistance;
( G1 g5 ^' }# r! n' A5 @% M Z. y - ; y0 b. g' V' C, k: d
- C! t# w+ D; z& ~) `3 s
- uint32_t pos;' g" r& W1 N0 s& j
- uint32_t speed;
6 c( G# G3 X) w8 M) P7 [. g - }_tmc2208_set;
% c$ @$ y, \% D! f0 T V
* f% i/ Q0 V3 C/ y ? U( k3 K# V/ g- typedef struct{8 y) O V0 V% o
- uint8_t micro;2 s& P0 Z# ~% \
- uint8_t fullStep_angle;" S$ P! d5 Q! |9 ]1 n Y
- uint8_t grat;9 z$ S0 x3 T+ {
- " N# ]6 Q2 _5 D$ j& b: F
- uint16_t start_speed;
4 g4 J" Q' R z _7 \ - uint16_t max_speed;( h& V- h, J; t
- uint16_t min_speed;
% u: ?8 ]+ A& f) Y$ x - uint16_t inc_distence;6 A' E# v* |6 e8 _! `$ e1 |1 T
- BitAction max_io_value;+ r1 C% j9 s) Z! z7 O+ ]. I
- 3 X* ?; a+ P, `: Z; ?3 Y; W
- uint32_t pos;
6 A7 a9 W" c4 ]% ^$ `" b3 ? - uint32_t speed;
2 w. ~- ~4 @$ f) g7 z -
/ K' j, l% I# H8 ] - int run_F0;) o& T' V7 c4 A; d3 w& p# _, m
- int run6_max;. K, I- j @" n& h% _
- int run6_min;
) a' P1 G5 u" g - }_spin220_set;
# Y4 G5 y. v. a3 x$ h - 4 J! [6 H, k; `8 j
- b3 G$ r4 |: G6 u+ N9 p9 h
+ V) K# M, e0 F" K: S( f- + _: y2 h% a$ H( c1 i
- typedef struct{
& D! d1 Z, {* c# L6 P - _tmc2208_set tmc2208;
. f N+ H. m- w' s - _spin220_set spin220;" ]$ @( J" W# O/ ]3 M( k! m% o
- uint16_t crc;2 B! D" q8 o% y. Q: k
- }_env_base;& [; s+ N3 m, l. J" Z$ g! v" y# T
- #pragma pack()
6 I2 U3 ~6 l5 J, ]0 x/ v. D - 9 |* g4 l& B1 ~1 `( p
- extern _env_base Env;
# x7 d8 F8 s3 ~- w! n4 D - void initEnvironment(void);
& {: s4 Q$ \6 m, B0 A" K - int saveEnv(void);
' A; {* A; G. q9 q1 C - #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可& _1 E: \9 n/ Y( c* S$ J$ j7 b
- + j+ p. `$ X9 t& o6 m
- void spin220_set_default(): s2 _7 X/ H) H- Y# m" `6 P
- {
& K- Q( W0 V; [ - Env.spin220.micro = 16;% \% t8 Y1 I" J
- Env.spin220.fullStep_angle = 18;
/ L* P' f# H8 k9 c* V' S) c - Env.spin220.inc_distence = 2;
0 F) ?: i4 v3 m! Z6 \ - Env.spin220.start_speed = 60;//
3 N& J% n& ~5 f& F3 `+ u+ j6 U - 6 q L/ Z8 i. V. y% W
- Env.spin220.max_speed = 4000;
3 {, b, F! I( m( P! K' l - Env.spin220.min_speed = 60;
* l1 }. V0 \# c+ {- r7 h% P% G2 C -
3 V v4 h7 V) [4 r1 b; Y9 z$ C8 S# H - Env.spin220.max_io_value = Bit_RESET;
/ U" o; v* Y- y* ]/ V; j9 n% y -
* r( x2 y0 r# }# q - Env.spin220.pos = 7200;
+ N! _6 r! B( K% v2 l - Env.spin220.speed = 4000;( i2 G. t+ x2 j$ I( D
-
4 a$ M( U3 p" d: p, j9 R - Env.spin220.grat = 0;) W; E3 L1 c( Y# P l) z9 ^
- $ g+ x; N- s. T
- Env.spin220.run_F0 = 16;
& t1 i2 Q( \: o4 o- e - % |- H7 U( Z! ~6 u; ?9 U; w8 [
- Env.spin220.run6_max = 0;
: i: A# m- R) ?) |& \ - Env.spin220.run6_min = 16;9 m- ?* x3 k: {( P8 E; ^* o
-
- W6 g- w7 n2 w$ r: K1 Q- Q - spin220_set_init();
4 I4 K0 n* |: @/ a d' _. }4 Z& A - }
复制代码 至于xxx_set_init()根据实际需要了0 K$ [- S. n1 ^$ o" j9 |% I j
; [! W9 t+ A# E3 h$ h
/ }- U% K7 P2 b/ c [% E
# m0 ?' P+ ~2 s. h- G& J+ J2 C$ J9 z, X' C7 u0 ^8 X3 S8 g
5 ?' H0 ^) C& U: W) F, }9 j" ]
|