很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,/ Y }/ J2 ]: u1 O
env.c K' s: r% ? s. N+ u+ @5 |; P
/ P+ h# R- f6 B: |) l
- #include "env.h" J& }7 K6 ?7 C/ x! E( S
- #define SAVE_ADDR (0X08020000-0x400)
% y$ x* x! m9 l8 d! D4 k - _env_base Env;. N9 X( u4 @; j6 F
- uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen)& a. l+ a" I) \! w( r
- {
, G& H& h1 }* h3 W! x+ l- \, }( R - uint16_t i=0;) t* V8 W5 K7 ~& T2 G* m6 d! |0 g
- uint16_t j=0;
2 p7 n. S2 t2 X7 |4 k( o - uint16_t crc16=0xFFFF;
+ i4 ~" D3 V" F1 j; x) C9 ^% O - for (i = 0; i < usDataLen; i++), M# f! r0 B( I8 q3 o9 o
- {1 i6 k* R7 V1 l. ]& ~$ W# T! I- t
- crc16 ^= puchMsg[i];. y1 r1 L7 g/ I* C: c. F6 e
- for (j = 0; j < 8; j++)7 ]8 `+ H( g. E. y* Y; U
- {
$ x3 T5 F( r/ u( V - if ((crc16 & 0x01) == 1)
$ G' h6 o/ Q4 R0 h/ L% g - {
( z0 `6 X0 M* C A2 g - crc16 = (crc16 >> 1) ^ 0xA001;5 |0 m7 e, I$ |. N' W* ^
- }
) ?$ z1 h/ \2 e - else5 w3 g1 J( c1 b+ S
- {3 I* {( _0 g3 Y/ a; C
- crc16 = crc16 >> 1;% k' X" {$ `0 P* X1 j2 t0 u$ q
- }
% { O' [) {; ?4 ` - }
7 Y8 X% J! K$ X8 S! u - }8 Y7 I5 _$ E9 V
- return crc16; - A8 P0 X; t, z+ n
- }( o% Z1 p& [/ l2 t( ?' m3 k; G/ F/ z
- //保存值,env没有发生变化直接退出
" s, N% C- v5 K: I: C - int saveEnv()
+ R& ^$ k" S/ {8 g9 i) ? - {
1 @/ }$ M7 M( V6 B4 i0 k% {% A - int i=0;
! ?( ]( F! Y( f% n* W% V4 F5 J- V$ Q2 d - uint16_t crc;
9 |, p$ Q7 E% ^+ O1 P1 p2 h4 L - uint32_t da;
, P+ P; i+ Z. W/ A - crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);
, |+ D8 f$ _; ?5 ]7 _; o" J - if(crc==Env.crc)return 0;+ w3 w6 m) W/ `0 @: d
- Env.crc = crc;
' P; t s& \9 L, y1 @0 J - FLASH_Unlock();4 d5 O7 H3 m0 N% i
- FLASH_ErasePage(SAVE_ADDR);
/ w1 r4 G* g4 r0 \ - for(i=0;i<sizeof(_env_base)/4;i++)- [+ q3 \1 w k; l Y4 E
- {" P1 S: t1 l- n2 R# ], t2 b
- da = *((uint32_t*)&Env + 1*i);& X/ W$ Z1 M# |; T7 q
- FLASH_ProgramWord(SAVE_ADDR+i*4,da);3 O5 n! v2 ^ U& i
- }
( ]3 G* B2 n( s, p( d- g- P - FLASH_Lock();8 e! O- N& ~& K* ]/ ^
- return 1;* ?( H* w# D* w0 }; _% {
- }/ ]2 ~; j% c' o
- //读取- e4 y# X) |' G. Z' E, t
- int readEnv()# u1 P5 V, ^% T! g8 v
- {
. G* L* ]& c# o; x/ a$ O - int i=0;
9 E/ X1 |% Q& | - uint32_t *p=(uint32_t *)(&Env);7 l" |+ B5 T/ I$ G! \! a- }; X8 V
- for(i=0;i<sizeof(_env_base)/4;i++)
0 u6 w8 y; K, q/ L4 E, U5 a- c - {* J% a. }. ^( x. U/ t
- *p++ = *(uint32_t *)(SAVE_ADDR+i*4);! {) @) Z% ?9 Q; r/ i
- }
& m3 c! W G4 d! N4 M - if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))
2 D1 i) G6 p& G7 J - {
/ G7 g2 E3 l4 ]. E - return -1;
! D, N6 i2 y0 i9 o - }
# I# ]2 e- f2 e - return 0;
, C/ p8 v7 N5 `& z' T - }
4 { s$ a8 b. C5 G% W* ^$ {- V - //初始化
3 t% d: |! s- g S8 e - void initEnvironment()
* u. x V1 W' ?* O - {
. X: O& K) O* I5 i0 v) ^2 j& _ - if(0!=readEnv())" S5 ^4 y5 j, [ i/ O% p( x
- {& f7 J$ B t# o
- tmc2208_set_default();//一个配置组默认值# N8 i, }6 b1 G8 l, V( K, n0 I
- spin220_set_default();//另一个默认组默认值5 j! o5 N% Q& [+ f9 b: a
- saveEnv();
6 Y+ u* H6 W- L9 o" y - }
# t* F' \* H5 W( B7 A0 n4 }4 s+ v8 z - else- }$ ]5 w1 ]: e$ j
- {2 ]9 T0 g h8 f. {
- //tmc2208_set_init();//针对配置计算运行时参数+ b r# Z7 T) E0 M" ~! B' l
- //spin220_set_init();5 F3 X( U1 { D1 T/ n
- }
& M; @- o& y+ r8 f - }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。
1 W+ G- ^% k8 l+ u1 NEnv.h
6 h3 W8 A5 r- W$ @- #ifndef __ENV_H1 V" H& x, S4 R4 b q) L
- #define __ENV_H7 A0 a( m* ~5 ~
- 2 A" T( L! I9 f+ i7 R) R0 r
- #include "stm32f0xx.h"6 _" X3 T- E( ?1 Q8 p
- #include "tmc2208.h": o8 c# A& e+ t6 ~5 f
- #include "spin220.h"
, p" H* x s! X4 Z( d4 g - ; x: r6 V, v+ Y2 a/ Y
- #pragma pack(4) M& ~3 T% j3 T9 I( _
- typedef struct{
6 y! i8 c$ K: k4 M - uint8_t micro;& j0 ^. z' |/ {: F# e; {
- uint8_t fullStep_angle;" |4 ?/ x4 P. n0 l
- uint16_t start_speed;
- b; K$ J* a: G9 e# j, K - uint16_t max_speed;$ r6 k. o0 n: v4 M! B4 }
- uint16_t min_speed;9 e1 Z- Y$ u8 s5 ?3 e' H
- uint16_t inc_distence;
3 ]) F8 B# l9 ~) F) p/ y3 A I - uint16_t motor_max_current;
4 N! H! ]6 W1 B ` - uint16_t motor_resistance;8 l& L1 c3 ?7 e3 N3 M- k
-
% R* I \, D) | -
/ u: m/ V' ~/ `2 T' L4 d - uint32_t pos;; X( ?% N: t/ T0 D
- uint32_t speed;
% C( C5 F. m4 J3 t$ ]) q& T - }_tmc2208_set;
3 n' I+ m0 o1 \- H; V
q+ \) m a0 i1 x9 o& O- typedef struct{3 e3 G" W) f& |6 }; h
- uint8_t micro;
& \7 \8 @8 P$ M, ?/ u+ z: o - uint8_t fullStep_angle;
8 @. f4 I0 Z- }+ L: L2 j - uint8_t grat;# Q: E8 Q3 _# U) j' y1 B+ R7 ~- J
-
1 q3 \0 O3 ?" p7 K - uint16_t start_speed;- |% Z {; }, h8 c2 M% @
- uint16_t max_speed; k9 }2 `8 w( ^8 h
- uint16_t min_speed;7 q" o4 A6 a% C ?
- uint16_t inc_distence;) d$ c* m9 Y! }7 G
- BitAction max_io_value;
/ V5 Q( |& w# v. x" d - ! g. M; E7 q6 a/ e( V& E, F
- uint32_t pos;% Y) M, f+ L! y' S4 Y
- uint32_t speed;% p7 m# y/ Q1 L) E7 z. V
- . \& D6 A: I. y# F( t
- int run_F0;/ J4 d) D2 e. o( O0 k7 o r
- int run6_max;1 z) x; k$ W4 ?+ @6 c7 r
- int run6_min;2 x: A' y; t' D6 M t* Z
- }_spin220_set;
! f+ W$ P1 e7 ]5 Z6 s: P/ L
, V3 i( T% [- g0 s
3 l+ E' s B+ Q7 `
1 I' b- ?* e4 z7 E5 ^* k- 4 T% U3 m$ M2 B: h6 \# E
- typedef struct{
/ K/ S5 O3 Z! X2 j9 ? - _tmc2208_set tmc2208;8 S' T$ K9 ]; ~. t. X O1 K! N
- _spin220_set spin220;0 h" I2 G' v. J) }* c5 E
- uint16_t crc;2 i; N; Q5 r# }4 m# O; R0 k8 M
- }_env_base;1 z& p M- L; M2 y" q( x
- #pragma pack()5 |" M- N0 T0 }% B. l6 W8 _
- 9 y/ N/ a: V0 e7 k* Y U B
- extern _env_base Env;! x. G/ R! \9 n. w2 [
- void initEnvironment(void);
2 g3 H. S% [/ f# n - int saveEnv(void);( t8 i4 v9 I( l
- #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可/ T! R9 T& L! D4 W2 |: G
% R. L z$ _# b- R6 D0 J; \3 ^7 Q8 H- void spin220_set_default()4 a }* W' ?1 D, F
- {
- ?8 s u' D/ z! P& I4 \ - Env.spin220.micro = 16;* d8 J5 F+ x$ B+ g1 ~* y5 ?
- Env.spin220.fullStep_angle = 18;
7 k4 o1 l( U7 m2 H' ? - Env.spin220.inc_distence = 2;
6 e8 o4 F, ~% D4 n* V; ] - Env.spin220.start_speed = 60;//
0 e) B9 H2 e6 o( W$ l1 Q -
/ m$ e$ ^0 k: b( Z - Env.spin220.max_speed = 4000;) H" V9 }- z* {3 d$ v
- Env.spin220.min_speed = 60;; E4 ]: b; f) B8 u) i
- $ F z/ r# a k) ^) z3 p
- Env.spin220.max_io_value = Bit_RESET;- i E# V6 k9 n3 M$ O8 D+ f @3 ?
- 3 L3 k9 R" [" X0 k' b0 M
- Env.spin220.pos = 7200;
! y& @3 r. P+ h" A* E - Env.spin220.speed = 4000;7 M. d% s* s6 p8 Y/ c- i
-
, Z; l l8 @& M9 Q' U0 ~ - Env.spin220.grat = 0;
! J2 Y# |: K. j% x8 n& z% d: P - 4 D$ T8 M" \. n$ a4 y- E K
- Env.spin220.run_F0 = 16;
4 @9 R/ s K# ~7 M2 a - ) O% m) B% r4 ^+ M: E$ Q
- Env.spin220.run6_max = 0;" ~( q: }% H B/ X
- Env.spin220.run6_min = 16;2 n* S$ f$ W, }
- 6 T; _6 Y8 w1 z* C' W" g
- spin220_set_init();9 k1 J+ B' K; i H
- }
复制代码 至于xxx_set_init()根据实际需要了* P) Q, f! L9 {5 _
, ]! d: ?: s* F9 j& ~; b
$ }" R9 b: D7 ?( x. B5 P K: P: h7 v: \8 w3 X
; R7 @* y5 x7 V* o ?) c: A; x, _6 @/ |0 } t9 k
|