很多时候,我们需要在单片机中保存很多参数,这里提供一个给予STM32IC的例子,
8 \' L% Y/ i0 ]4 h env.c4 |$ p" M5 B4 X" G. t( ]
1 R* ]' r: W# ?- M' `' {
- #include "env.h": H+ `8 v, G! q/ C# \; N
- #define SAVE_ADDR (0X08020000-0x400)
; l0 e+ A. W9 @7 e! w - _env_base Env;: `& {7 v3 a- t* Y
- uint16_t Crc16_Modbus(uint8_t *puchMsg,uint16_t usDataLen); V ?" T1 z2 E" j1 U7 a2 n
- {. V2 ]9 _" h2 y& `4 o4 f
- uint16_t i=0;- W, u7 n- T0 R: z- E3 \
- uint16_t j=0;4 g% ]" S& I5 b5 W0 c$ @
- uint16_t crc16=0xFFFF;* l4 x: k6 I% h- I+ h7 U& P
- for (i = 0; i < usDataLen; i++)3 D: \( s! @+ a0 C- f4 d
- {
! |" {+ j( f1 H( ?: k - crc16 ^= puchMsg[i];1 P% |. ?6 ~/ x7 `+ m1 d
- for (j = 0; j < 8; j++)
( U/ `/ c3 \% H - { ! k8 U3 s9 Z+ t; C
- if ((crc16 & 0x01) == 1)8 Z# S* Z6 j# ]- |0 h% K
- {
; C/ {; w; q# t# Z - crc16 = (crc16 >> 1) ^ 0xA001;# b$ S6 B8 d- z. s% n
- }
2 D+ z- `" i0 ^* A5 I$ B - else
# J" o% k1 [: R5 {& y" t* E5 s8 w$ B; b - {- K. g5 E: T7 w3 J, F! R0 `1 c
- crc16 = crc16 >> 1;
: o% b6 }; x6 ~- I - }6 I4 f3 R" |. C7 [
- }. G% V- i' `5 k7 i, j
- }
+ s V- l8 f( Z& M# O9 x - return crc16; / ?, \4 m, l6 H- l" p& f
- }
0 Q( X# {% f' V1 Y1 b - //保存值,env没有发生变化直接退出- P$ O: R9 I% a$ I* O( d0 P6 x
- int saveEnv()0 |2 W7 o% h. X
- {
! O( F( h! w& k+ N0 {- c7 N. a5 J - int i=0;
7 O) x( I8 K; m( Q7 k- W' b2 Q - uint16_t crc;
6 w1 o$ \2 n: P, ? - uint32_t da;
+ h* o, h) v0 B- q X, {3 M9 U+ ^, K - crc = Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4);
) P$ ]7 R1 z. [; f. _) k! s% q! L - if(crc==Env.crc)return 0;
& g4 U# X" [' W7 _+ q- V& O* u - Env.crc = crc; ) }. X' U) c) e( S9 v$ b: I
- FLASH_Unlock();
7 o6 a4 Y! {! D' R- h - FLASH_ErasePage(SAVE_ADDR);
?* H, k! R s- X! l( r - for(i=0;i<sizeof(_env_base)/4;i++)0 X9 H: Y1 `; C# W% n+ F0 q
- {
' G9 a$ }2 k* ]3 P1 O: M3 c - da = *((uint32_t*)&Env + 1*i);' O3 Q5 }" K% l
- FLASH_ProgramWord(SAVE_ADDR+i*4,da);
5 w% y$ g' ?& M; n" o; B6 S- M - }
+ U/ {. j% k+ i - FLASH_Lock();
, L7 m( G+ i0 B" B: `% q - return 1;$ V9 [- Z7 e* }& P |
- }3 J7 P% \9 {1 u& u3 F, Q/ Q* R# `8 u* N
- //读取
0 q8 a( ]' p5 H. D - int readEnv()2 Z$ _) x! q0 S5 R
- {+ a. q& a/ l/ \6 r- D; ^. n# t
- int i=0;: N t- s! C, |+ U# p3 u
- uint32_t *p=(uint32_t *)(&Env);0 V5 y! K$ _4 n
- for(i=0;i<sizeof(_env_base)/4;i++)
# S# n, [1 m" z6 _ - {
1 O% A" ^9 P+ \6 f - *p++ = *(uint32_t *)(SAVE_ADDR+i*4);1 o6 R0 ^: n; t9 ~) z2 }: b
- }2 h$ V+ P5 X6 m7 d
- if(Env.crc != Crc16_Modbus((uint8_t *)(&Env),sizeof(_env_base)-4))* B9 `' g+ k) |
- {# L# ?$ Y; z* _' [4 E$ [
- return -1;
" y$ c7 J9 X2 K: {- Q - }# b6 |$ d% J" R0 G& G( ^" a
- return 0;6 V) D' P7 Q# K- y
- }
) G2 h# e! n: O; y - //初始化
7 C. ^% m1 ~" x- ^8 s( T9 e+ j - void initEnvironment()
* }( T# d, q) N. G1 B7 d" j - {3 E9 j1 K) s0 ]1 _# t, F
- if(0!=readEnv())
' T# n! F) c6 _3 ] - {
" k; i* A5 ^+ a9 z9 A7 | - tmc2208_set_default();//一个配置组默认值3 V" T) J# _, t0 S+ b+ g9 S) n
- spin220_set_default();//另一个默认组默认值6 O5 ?1 t5 l3 T- f3 l/ a/ v
- saveEnv();
* ^0 C7 P- `9 T I' `1 z - }
" h8 I% B' h5 A4 D& x6 b) W - else7 J# i, F6 h) e: F; }
- {' E N, e( Z1 z* v* u3 y
- //tmc2208_set_init();//针对配置计算运行时参数; _( B" F) X" k% G' g7 x8 ^
- //spin220_set_init();; t4 F0 V0 V2 Q3 U; y+ ]
- }" U: W* h- k% B# @
- }
复制代码 一共三个函数 saveEnv() readEnv() initEnvironment(),更多时候用户在Env发生变化后且需要保存是调用saceEnv即可,注意flash擦写次数。
+ A/ W* V& M+ t0 D, z/ J8 oEnv.h- M2 k5 Y4 Z: d+ o. O
- #ifndef __ENV_H
3 n, D6 F+ s$ L) B( T% J U q - #define __ENV_H( G' K3 z/ H# `. q6 [9 T
& ]8 y6 C/ U/ @2 ^, w7 M- #include "stm32f0xx.h"
# |, @! g `& @4 h+ b+ ^7 Y( \ - #include "tmc2208.h"
! L- N u* t8 ?: ]6 H- T7 u - #include "spin220.h" M7 i3 `+ l5 X) |( W& O8 ~
- ; \% v8 D# p- C/ u% ~; I. X; T
- #pragma pack(4)6 F) J8 e0 w& X% d5 ?. Z
- typedef struct{& b* D' [5 d5 m) a3 Z% v. S! o
- uint8_t micro;( R" l1 J& @0 z
- uint8_t fullStep_angle;
* @$ Q* A& o8 ^* a4 U - uint16_t start_speed;: E8 R2 D' R" @, H# V8 W
- uint16_t max_speed;* g8 ~1 ?1 D% @! a4 ]0 D' k+ |% V
- uint16_t min_speed;
3 z* _" a! e7 `3 e- [( O - uint16_t inc_distence;7 K, d; y4 p0 v2 D% h) Q2 e
- uint16_t motor_max_current;
# y7 R L3 `* G& l5 c - uint16_t motor_resistance;
/ w* R$ E2 s1 ` - 6 @' S& e# |# N, n+ i$ t o
- ( A* E7 G+ M, n0 X0 g% ]! N
- uint32_t pos;
# W1 x( X8 p3 J5 o2 ~ - uint32_t speed;
$ r. b( ?* H3 Y& Y4 t: r - }_tmc2208_set;. g1 z0 V8 o0 i0 o4 ]5 u
. q0 S4 q7 d* ?# C i- typedef struct{
. M4 a9 G+ X. g! ~, k' c - uint8_t micro;! Z# c: ?- R/ U+ v
- uint8_t fullStep_angle;
[6 S, g* }" Z - uint8_t grat;
! t2 P- G7 D4 I# C# e, q - - Q1 m' z' h' R1 Z) [8 c
- uint16_t start_speed;; |- O6 R- [, N* w
- uint16_t max_speed;! f' A7 O4 {; G
- uint16_t min_speed;; q, w% d i) n1 g- j4 j7 U
- uint16_t inc_distence;# E; R9 C4 @" m5 s. ^ k
- BitAction max_io_value;& G+ H3 g; M' X
-
9 t3 z' G# Y! y# Y0 v1 U, s - uint32_t pos;
3 n) q2 R9 n( \. k" I0 @! q) J* O8 _3 q - uint32_t speed;4 n0 Z' t9 f: z+ O: v
- 3 C" ~: Z3 c3 K! }) E
- int run_F0;
- e6 W' @( |. C: [7 U) V# Z' J {1 ^+ e - int run6_max;
7 z) `" D! T, @% ~ - int run6_min;
7 o9 A8 h$ D" A# y - }_spin220_set;
3 t0 n0 I! b9 a1 R' {' x - ) O- x1 Q! \0 i
- 0 X% |# v' e6 e( P
0 ^/ E, Q/ X: c$ P" r
/ A; A3 {8 U; L8 F- typedef struct{- a, M/ z1 p) G0 c
- _tmc2208_set tmc2208;4 }* A# s) q6 i. w4 q
- _spin220_set spin220;
3 B0 {9 |1 U, Q, k, I/ U - uint16_t crc;
- p; {: d& i: x( m; P - }_env_base;
% m4 h4 A K/ o+ U* r - #pragma pack()* P4 q7 ~" S0 M/ X' @7 ]
) v( f9 ]4 Y m, t$ C% T+ t- extern _env_base Env;
, c9 [; C: D. H* h: } - void initEnvironment(void);4 V- n) |9 k. Y! C! P+ Y6 p6 i+ l
- int saveEnv(void);" T$ E7 x1 | ~* r3 A3 d- z
- #endif
复制代码 这里只举了两个例子,有新的需要保存的参数直接添加修改 struct即可,同时在对应的xxx_set_default()添加默认值即可
! K3 M) r5 \5 N0 {8 A+ J, n
7 H7 X- i) u3 G5 e) i- void spin220_set_default()
( `9 H) X7 `2 g1 O b) ~/ h - {$ d: Z$ l' N. J+ x
- Env.spin220.micro = 16;* d0 }2 Y9 [( N. i
- Env.spin220.fullStep_angle = 18;
2 O& I' D5 j6 T' i( `4 X; I - Env.spin220.inc_distence = 2;3 r" W: K& b, C9 T$ ?
- Env.spin220.start_speed = 60;//: S# c- G" }$ [, A$ e1 y0 n
-
}2 G7 n0 _+ k8 [1 r0 K - Env.spin220.max_speed = 4000;
; I' p$ y7 j; t: P7 [! _ - Env.spin220.min_speed = 60;7 A# y; N( O2 O0 M2 C
- p( N2 T# I3 F6 `: O
- Env.spin220.max_io_value = Bit_RESET;" F D) \" l, ?& f# z# f( K5 R2 t
- 8 P$ z% L" ^4 {' Y; ^1 W
- Env.spin220.pos = 7200;
. P7 i: u$ f" H5 t" v4 O8 { - Env.spin220.speed = 4000;! ]5 N7 F# V, I/ W1 W
-
/ \" V* I0 c- t% f( R - Env.spin220.grat = 0;
4 @+ g1 s1 t' Z$ c, m h - - h ?: S3 L& M; v! Y. K$ D9 H7 N
- Env.spin220.run_F0 = 16;2 ^ e7 O+ D7 K4 J# ?
-
2 o3 G# N" Z6 w+ t - Env.spin220.run6_max = 0;
2 \6 w* B+ ~6 \( Y - Env.spin220.run6_min = 16;. H9 ^; a; B! G$ y" U
-
, N3 T: d7 P6 U/ w- y% e0 y. J6 |! | - spin220_set_init();, p$ W. @' B3 k' l; R$ N0 ~3 X
- }
复制代码 至于xxx_set_init()根据实际需要了
* }* \6 }! b5 p6 X* i/ S! i
) W5 p/ d6 P$ S8 U: i+ o5 c; L
* K& G k2 ]( h) i O; Y
; c- B. O/ h# h; J- F' z& g5 j% G, _$ d
5 @7 T6 c3 ]4 x; m; C3 q# k
|