一、cube.AI实际项目应用
- [' r/ ^7 q% ]* ` 接篇二,前文都是采用FP-AI-SENSING1案例和配套的B-L475E-IOT01A开发板来阐述的,而实际项目中,我们都是基于自身项目硬件平台来训练模型及部署模型的,我们仅仅需要cube.AI软件包(作为可调用库)来支持我们项目,不会强行采用FP-AI-SENSING1案例去收集数据及配套的B-L475E-IOT01A等硬件平台部署。
6 x* E3 ^# B( v" m: V0 P
: m' h9 U i/ {( p/ \; ~( h 回顾篇一,ST公司支持到如下图芯片型号,
3 S+ X- j3 W8 O4 ?
4 h" c9 U" q) D& H
& u! d; a8 j" b1 g" w
0 h: T9 v q. k K* m2 O. E9 u8 L
在本文中,将采用STM32L496VGT6-ali开发板来部署cube.AI实现人工智能。STM32L496VGT6开发板已经集成了LSM6DSL传感器(三轴加速度计及三轴陀螺仪传感器),项目设想如下:
/ I5 N. U# U, } e5 r8 u: y& l+ V0 o" I5 p# E- N- B
1)通过LSM6DSL采集加速度数值(x/y/z三轴加速度)$ z+ x8 E9 g7 q$ ?! U: t
' W$ Y: y& n1 o2 T; H 2)本文只采集三种姿态(开发板正面朝上,静止不动、左右移动、上下移动三种姿态)时的加速度数值,用来实现分类神经网络,三种姿态作为神经网络模型输出值(分类)
* W3 \2 d# M6 a3 j0 v* R
+ ~! K' i* H, C4 [! N 3)每次输入读取三组加速度值(每组数据是读取x/y/z三轴的三个加速度值),共9个数值作为神经网络模型输入数据
, r7 @/ ^* q+ l2 Y s6 R; Y1 m* c1 ?' g
4)利用STM32L496VGT6开发板上的三个按钮,KEY0为静止不动姿态采集按键,KEY1为左右移动姿态采集按键,KEY2为上下移动姿态采集按键。
1 |0 R. c; |- B) Y2 t7 A* M% }, X( i1 A& x! z6 _1 ~
5)通过串口打印输出采集数据信息,并通过串联助手连接获得采集日志并保存成TXT文件
' ^+ O. } a/ w6 Y# N0 T: G
2 H+ }/ a* Z% X z- I; i2 k1 | 6)将记录数据文件转换为csv文件,通过keras框架,编写神经网络训练模型python项目,进行神经网络模型训练,并输出.h5训练模型文件
! ]* ?1 C0 u8 H) `3 d/ N) o
. Q2 P+ x! ~9 Y8 P 7)通过cubeMX和cube.AI将h5神经网络模型转换为c语言神经网络模型. I/ K1 R B9 v' G
* T. T- d5 {' c% s2 X1 I8 M 8)将LSM6DSL实时采集数据推送给c语言神经网络模型API,进行神经网络计算,查看输出结果是否符合预期。
6 d. f/ x% J+ _# Y
% @) C9 k6 U" b$ H9 X
7 D* @# c0 c2 |* D# ]0 V9 l8 Y0 Y二、创建工程8 m& |- N, S! R% E: K% r
在CubeIDE上,基于STM32L496VGT6芯片,创建新工程STM32工程,并实现了串口lpuart1调试日志输出,三个按键KEY0~2和三个LED灯LED0~2的功能实现,并实现LSM6DSL传感器采集数据功能(I2C4)$ G; G* {' l( P- h
. V1 h6 I& h0 g/ F! {& h! `
现给出简要的配置及源码信息:- q b- B; ?# M7 t; q2 I
6 r% _) T: X/ f% w
2.1 工程配置9 E5 r" V* D( e9 S9 G+ g
1)内核功能配置及RCC开启外部时钟支持1 d. Y k! y3 ]' ~+ ?5 a
3 u+ I) O: ], v3 }: @
+ P: b A" N# t: ^" P# i$ t2 I) x
$ e- D; }" C* }2 l% r, F; h% {
& ]' C$ C. O$ z0 c% v+ g: k9 U5 w$ p: Y; Y
2)开启LPUART1,并开启其中断支持
/ V' L+ @! b* |9 b* K# J2 F' n- D. F" r6 p3 y
1 e0 U# y) r; K: [# L0 H3 n
) U' H6 ?* l, a
" L) Z8 \7 ]* Q& ]
/ ~. ~5 a+ _. C3 Z$ n
3)开启I2C4,并开启其中断功能及DMA功能" }" _& Y* I! ?
$ t( \. G1 h9 h8 D1 ~: E+ m) w% [/ b" j. _7 X2 l6 e7 h
# Y1 `7 h. l+ @8 \4 I
4 \$ j! M" b* Z
0 m! U: ^% f- [- L! J
' `$ @& D- v; X; r1 w* G, a
! q: T/ b: t6 p6 K) P+ s% {+ x& N& h 4)配置GPIO引脚(三个按键及三个LED灯)
# n7 ~ q/ \; c4 P7 X' o* {! R% M, O9 T4 i8 r! Q4 ~+ z
+ u/ C6 m: }; C' Y' Z5 q
: s9 ^, z2 C* |5 e6 X* e, h 5)配置时钟树5 p; Q: A9 w+ P: ?, [5 g" o
5 S9 z2 e6 @9 E. i6 A
; |- a9 t% N3 R$ W
6 }4 O6 n' ?) } 6)引脚视图, o$ X; Y, e) d' ?" A
2 g: \1 i6 z9 j
( O$ ~0 _1 ~- D. M3 i; E Y
1 \: {2 @* W; Z
7)工程配置,选择为每个外设生成独立的.h/.c文件7 }+ X1 X/ f- _9 D/ U( q: ?
. Y4 s9 e; \: b0 i8 x- T4 w
* G V$ }, T' j4 E6 s8 W* @" Y' P% i* K0 l: j# F
生成输出代码8 i, k: Q( Y, Y
8 j! v4 m2 |. _& V9 O+ A
2.2 外设代码设计
/ [6 r+ ?, d9 C' J- V 禁用syscalls.c文件(右键进入文件属性设置页面)
3 [+ N3 C6 ]- h3 S; a7 z2 D
8 B$ l, X( w, o; b5 w0 ?( f- }
% e6 ^: ^+ O+ K: I9 @
" o8 Z3 e, p0 N. n2 x8 Y/ c! }2 F
在工程下,创建源目录ICore,在该目录下,如下图所示,创建子目录及外设驱动源文件
( w* K3 ~. ` h/ r& E" n" ` D/ x) u3 \" X* n6 L# k
n9 o ^% `1 r- Z# g* M) n
2 B, j: K( U2 _ c8 T) S 源码文件内容如下:
* K( H3 \3 t4 {, r' ]4 y 1)key.h- #ifndef KEY_H_; T& [; n0 A) M- z4 U: h% A
- #define KEY_H_
2 h! a) W$ J& I$ ^7 m) u# m - 7 p1 i! t i: N
- #include "main.h"& G C: k* P# z
- #include "gpio.h"
, q& ~* @0 ]4 C -
4 i+ I! T# k, @1 R) U - GPIO_PinState get_key0_val();
. }4 o0 b1 c" G# | - GPIO_PinState get_key1_val();" i4 m' i) ~- |. N( M$ _
- GPIO_PinState get_key2_val();6 P( x. r$ v( S- w! J, N8 P+ l
- % D; |; ^& j, D/ N, k. ~
- uint8_t KEY_0(void);
* z. @9 @3 q' ] - uint8_t KEY_1(void);! c( {' U r5 ]) S [, Z( f
- uint8_t KEY_2(void);: K& {5 Q$ N% T& k: |% q3 N( t
- & T% R# X( k, y: @) S
- #endif /* KEY_H_ */
复制代码 5 {+ V* P2 C/ W5 b( N1 c
key.c" }8 _, Z$ w; Y6 ~- F4 W" Z& j1 _- r
- #include "key.h"
7 x; u% I) W4 d/ }' A2 Y( u -
! r1 P* E4 f# [+ \4 Y - GPIO_PinState get_key0_val()
& k: l7 p% n$ C! T9 ?8 N - {' R3 ]; ~9 ~( ]1 B
- return HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin);
3 K! W8 a& F; ?- q - };! t9 M' y% k" d- Z0 r8 ~
- 5 H8 L: c$ n' Y; P$ }/ ?
- GPIO_PinState get_key1_val()9 U* g" M2 ?4 e) H! H
- {$ l8 F: V2 \" z% M, l0 U
- return HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin);- N# K) K# F) V/ Y3 J
- };2 Y* ]" D% |( V9 r
-
% C3 F" @# d& u5 p- r - GPIO_PinState get_key2_val()
& U/ P! |" \5 o! q! g - {
# i0 `" p: V1 l7 b0 |$ q! s7 i - return HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin);
G0 d5 W! u7 \/ Z! C2 { - };: o2 p' B4 I/ i, G( G* }+ |, v! i
- $ |: F. M o! l
- uint8_t KEY_0(void)
+ o5 z; T, `8 j5 q1 ?$ N - {
2 ]- n7 `! G' V- s5 R* r - uint8_t a;
C( z; ?+ k6 n7 Y - a=0;//如果未进入按键处理,则返回0
( J8 L$ Q# c' m B' W( K( C- p - if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==GPIO_PIN_RESET){//读按键接口的电平( Y7 P# Y3 D4 M: U L8 M
- HAL_Delay(20);//延时去抖动* D C& [. ]/ V3 [6 O
- if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==GPIO_PIN_RESET){ //读按键接口的电平: c0 t1 l: R/ S) Y) r
- a=1;//进入按键处理,返回1$ F7 d! K+ S- D. w
- }5 K4 l4 h6 u+ {1 t, M: q
- }! }- w( t2 u% X( f- R- I8 S
- while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==GPIO_PIN_RESET); //等待按键松开
) o- c. @. S+ W& w - return a;
( ^- |( P3 i( t" n f; O - }
x0 C9 k# ~+ ^+ s5 y% f -
8 ^; E6 O( z# t( x; [1 M - uint8_t KEY_1(void)( S+ C* ]! ~7 Y+ |6 E
- {
6 H9 m/ l; O9 ]! U( ?' K - uint8_t a;
1 X5 z( ]/ z- L( p! S2 L; K - a=0;//如果未进入按键处理,则返回0
# j! K) @0 `) o6 P9 G* u6 y - if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET){//读按键接口的电平) F" F/ g4 O% F3 a9 W. k) m" e
- HAL_Delay(20);//延时去抖动6 \- P( b$ H2 i, {
- if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET){ //读按键接口的电平
+ v, R( m2 H$ c0 k) \- j: {' B# w - a=1;//进入按键处理,返回15 D3 j* a5 G; n) [, [" B
- }- x) ^& p1 w# }! N. M9 U- I
- }! |; H* z% M9 [: v
- while(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET); //等待按键松开
/ q4 s4 e `& ? I# x2 a' u - return a;- @8 g! j/ Q& F, d, w( g
- }
/ q4 _9 V5 E" Z -
$ z% H& e' ]) b" H/ I, O' u, K - uint8_t KEY_2(void)) T8 }1 r. G* J* | W0 n
- {6 r( U# s0 d% Q5 N {
- uint8_t a;
( T/ H: b: o7 g - a=0;//如果未进入按键处理,则返回0
' e$ w8 ^2 E3 e5 `. u: a - if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET){//读按键接口的电平
9 t# I3 ]! a+ \9 H" T - HAL_Delay(20);//延时去抖动
3 ^ h. u2 h& U# M3 C - if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET){ //读按键接口的电平: @3 M& {% J3 z4 ^2 x
- a=1;//进入按键处理,返回1
. u' `4 G3 L- |% J - }
$ u8 z$ \* A5 c/ T; j& Y - }
, L0 @& G3 }5 X* {6 E$ s2 P1 `: Z5 G - while(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET); //等待按键松开
0 T/ J7 ~% l9 ~' i; w9 a% m6 x$ v d - return a;% G" a# i* |) D0 A
- }
复制代码 . \$ r) N$ n/ z
2) led.h1 Z% d1 b3 h) R) v" G: ^
- #ifndef LED_H_
0 ?9 A. r9 I1 W$ ?+ {3 s, } - #define LED_H_
3 ~/ F9 P& g6 }9 c; u! \ - #include "main.h"
4 G0 ^" v) Q: S7 l/ D - #include "gpio.h"' C8 e+ O) V+ [6 d$ @) D
- 7 _ z1 u! S4 B2 i# n; m8 q
- void Toggle_led0();
$ w& Y0 x# N1 R. z" Z5 u' ~ - void Toggle_led1();5 q: O* u5 c# u( N9 q
- void Toggle_led2();
& J, V R* G; ^" f O - 9 F0 i; i( ~+ Q8 r5 V
- void set_led0_val(GPIO_PinState PinState);& O2 Y' q5 B- C
- void set_led1_val(GPIO_PinState PinState); M$ C9 G: n% x; R- S w
- void set_led2_val(GPIO_PinState PinState);. @& E( f4 |& Z% u4 f! o! O
- " t* E; @+ p" e
- #endif /* LED_H_ */
复制代码 ( T+ S3 Y+ J4 \3 n( c( A b; v
led.c
1 S! ]1 _8 w$ O9 Z) l5 `% f( \: {- #include "led.h"
, V4 {% c7 n0 V - 9 U2 @. I/ a" W" [2 m" l; \
- void Toggle_led0()
9 [: Q1 x2 P+ ?8 L$ D - {
q! w5 a2 c7 o' ]# s2 r# F8 F - HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);/ i$ Y% z) c/ y8 X
- }
7 H0 p# f) U j2 S+ N - ( a* T7 v! F$ q; r& z& d6 _) R
- void Toggle_led1()
- T! F& ^/ t+ l) g - {
. R3 Q: z' Q8 z3 u4 A3 e - HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
# f( r/ g$ a+ D4 }) c& A - }
0 z V7 J$ W" e% } - r; s- ?/ e8 [0 U
- void Toggle_led2()7 h5 Y% q; t0 ~ W
- {. ]# [; W0 m- a3 D* [7 S
- HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
; W5 G2 h; ^% I9 P5 Y0 G, p - }
6 ?5 Z# F( y |( V. ] m - 4 r: \0 j% P: k% o" e
- void set_led0_val(GPIO_PinState PinState)
% X% L! b6 `0 E5 r( l6 S1 K - {
6 n$ n) M3 X% L( M* R+ m - HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,PinState); x2 {6 _! D5 o! Y5 a- u2 {0 q. k- ]
- };1 I/ M8 ]7 P/ Z( M. p
-
" [. r7 O8 _6 e6 [& a - void set_led1_val(GPIO_PinState PinState)( m' C/ X \6 j: x! E
- {( V, U+ p' j/ s0 C1 Y% V
- HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,PinState);
* D* R, }4 a6 O7 _" o4 p - };8 R. x5 H: O4 Z6 l7 m" N
- , n' Q( u( s1 j, c
- void set_led2_val(GPIO_PinState PinState). D m! Q _) [% @# K9 n
- {
- n* l* d1 N3 w1 [ - HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,PinState);; u7 W/ m; t c7 N5 o
- };
复制代码 . ~* o% R+ w. ^
3)print.h
" S+ g& E6 n4 Y4 K4 V6 B9 E- #ifndef INC_RETARGET_H_/ ^+ g; G$ e$ K, ~. |5 G$ b6 V
- #define INC_RETARGET_H_0 ^7 F0 o( w8 k& o% w
- 0 H+ _3 A. T5 F6 e& P1 |( @1 V
- #include "stm32l4xx_hal.h"& P/ \" S/ G# t
- #include "stdio.h"//用于printf函数串口重映射
( A4 ~3 T& s. g - #include <sys/stat.h>+ O2 e2 `& a7 B2 a, n, V
- - c% o& J' u. M2 Y
- void ResetPrintInit(UART_HandleTypeDef *huart);
% {' c% X/ d( T* ?3 S! J. t9 M5 c -
* d; |* `* ^! d0 u1 K/ Y - int _isatty(int fd);
: N; L8 c K! I$ e" a, Q - int _write(int fd, char* ptr, int len);- ~: p; k! Q e! y2 c- \/ c
- int _close(int fd);) a; F3 }: @9 X) R
- int _lseek(int fd, int ptr, int dir);1 {5 Q4 k' w3 v, u
- int _read(int fd, char* ptr, int len);# A8 l$ [8 V" r; K
- int _fstat(int fd, struct stat* st);
! X; C! r# q8 x) ] -
+ J7 \5 ~ T. J0 p - #endif /* INC_RETARGET_H_ */
复制代码 6 c! {' |. `9 P9 w7 i
print.c
8 ~( G) j* G# e$ Z& t" b5 T- #include <_ansi.h>
[4 R. v5 ~/ u0 z: z' k; V - #include <_syslist.h>
9 ]# }, j: p6 Q - #include <errno.h>0 W, o3 N# p0 a, |7 x6 |9 H* q* L
- #include <sys/time.h>
( s' c( l1 q$ z( L4 \; ~ - #include <sys/times.h>
: O: }* G; s7 t4 G- t; k: p% q - #include <limits.h>& \) d# q- E0 c2 v; g/ V9 G8 @' [
- #include <signal.h>, C, p1 u7 ?- s) a$ x' X5 `
- #include <stdint.h>7 N- R' U3 x' U+ @, ~1 @
- #include <stdio.h>* D5 Q" w0 S* z. ]+ J
-
/ ^7 i+ Z3 \4 L! K6 i - #include "print.h"; O; `2 l, p! V' o
- . ]7 i- ^; l0 F2 m
- #if !defined(OS_USE_SEMIHOSTING). V+ r1 i$ o4 P5 i' Z8 L
- #define STDIN_FILENO 0
% Q, N/ N' }' f# [ - #define STDOUT_FILENO 1
, [3 J5 ]- A6 R - #define STDERR_FILENO 2
! v: j( P, J: X- a - 5 i$ x& Z7 H2 A( T4 @( ~
- UART_HandleTypeDef *gHuart;
9 C# e' O8 c6 M# ]# W. y - " `" R+ V1 i4 j1 Q( \+ d/ r
- void ResetPrintInit(UART_HandleTypeDef *huart) {0 Y: g) U/ E4 {5 ]- v
- gHuart = huart;
2 \( }+ _4 [/ H2 \' Z - /* Disable I/O buffering for STDOUT stream, so that
$ Q0 n! d" ]* v - * chars are sent out as soon as they are printed. */
1 p# ]; v6 b8 D I - setvbuf(stdout, NULL, _IONBF, 0);
o2 Q* A1 k) w - }$ i0 t' c. Z) b; x# s0 d/ i: d
- int _isatty(int fd) {
" D) h c/ y \" }" F1 ` - if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
# Z5 c3 o7 Q2 n3 ~0 ]$ ] - return 1;# r* j- o2 g5 h
- errno = EBADF;
' @6 I% F( j. Z - return 0;
. I# r! d- r9 Q1 A5 I/ G6 S - }0 e) m$ ~! v$ Y! @1 B$ `" W
- int _write(int fd, char* ptr, int len) {& [- C0 H6 r" X8 l( T7 q" \
- HAL_StatusTypeDef hstatus;
2 W7 v0 H3 e0 b- C - if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
& e- v/ x0 n* w3 U! G Z- r( q - hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);: y: w# i* B b/ a! a
- if (hstatus == HAL_OK)" ^& ^5 X# l" `# S8 S. H
- return len; P: a4 A# e& X& ]
- else
4 h& S3 ?2 A8 _ - return EIO;
" k. ]. }: }; t - }
9 \9 E! j+ f6 r5 F% S - errno = EBADF;$ `$ ^% ~; u9 ?% a$ Q
- return -1;2 m+ b1 {. `& M
- }
# Y2 Y& Y0 n$ X - int _close(int fd) {+ O! ?" C& [) J8 K6 n* b& j
- if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)6 M5 m1 p. e# v/ O
- return 0;
! e5 u- P, F$ q \ - errno = EBADF;
# s( l1 E/ B" T; G# B# P7 J - return -1;- s5 _ r) R. }6 O. R
- }- Y5 i! P* c w Z
- int _lseek(int fd, int ptr, int dir) {7 C1 M) V3 D3 w
- (void) fd;% E. a' `2 \6 D; S
- (void) ptr;$ G7 X# B4 ?+ I3 M1 P
- (void) dir;
0 P- Z/ l5 k& x+ t6 z3 i - errno = EBADF;
1 b' S9 R9 i, W0 i0 \* O: z/ u+ p* T - return -1;% w% d8 a% h; `
- }
. l$ U9 Q" O- L# @ - int _read(int fd, char* ptr, int len) {
" L. \& T( Q8 R- x0 A" m - HAL_StatusTypeDef hstatus;
& u3 J8 m. J$ j$ T& \# K: s" A - if (fd == STDIN_FILENO) {$ q2 V" \1 A$ |$ s6 ~
- hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
! Q# k' H( u+ T7 _8 A4 G - if (hstatus == HAL_OK)
4 l* a' E/ v e) Z+ y - return 1;
4 p0 C; T3 F ~; H - else
; A+ D( i0 h4 R! ^5 _2 E - return EIO;
% P- s2 {6 P$ X c - }
& m9 V0 e0 v& _8 Y% R9 [2 p - errno = EBADF;
& V! M' e" Y, I7 V% b9 I - return -1;6 A, P( {' G" v# q- u
- }
. M/ ]0 P3 P# u+ o7 G# c& c - int _fstat(int fd, struct stat* st) {3 h) e" Y9 Y6 h
- if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) {
/ C6 B7 f; z( e2 V( V - st->st_mode = S_IFCHR;$ G; q3 p( Z F' x9 Z. f) _
- return 0;3 W; k# s, A4 K: X
- }8 x# P" S; d- v8 C) |- ?
- errno = EBADF;4 Y Y( Z) J x
- return 0;
: r( a5 f+ [# n2 @ - }2 t8 a6 R/ q3 E" U7 J& ~
- 9 \8 D" x1 s" g7 B% r9 e7 Z
- #endif //#if !defined(OS_USE_SEMIHOSTING)
复制代码 4 o0 \5 m8 o/ x5 F
4) usart.h9 Q8 z4 e4 D3 X$ K; K0 s1 q+ R
- #ifndef INC_USART_H_
& P. h# Q& u7 k) n$ x( [ - #define INC_USART_H_
' S+ T; B: T, D5 e9 A! r -
8 J# K' @4 I4 U4 P& Z$ E* `" M - #include "stm32l4xx_hal.h" //HAL库文件声明
0 {" _) [" J. x/ E' M6 I5 W - #include <string.h>//用于字符串处理的库2 T4 Y8 L' I6 l9 `
- #include "../print/print.h"//用于printf函数串口重映射6 `" U- ~4 h8 |: |9 c
- 3 [, J6 u m- Z
- extern UART_HandleTypeDef hlpuart1;//声明LPUSART的HAL库结构体
: y. n2 k! a0 Q" Q& l - & R6 y0 b. e+ m
- #define HLPUSART_REC_LEN 256//定义LPUSART最大接收字节数7 z/ T! e2 Q: m
- 3 v9 F: M! C4 L4 h* j [6 k4 |. ^. N
- extern uint8_t HLPUSART_RX_BUF[HLPUSART_REC_LEN];//接收缓冲,最大HLPUSART_REC_LEN个字节.末字节为换行符4 ?% K% Y. k" M- L0 t
- extern uint16_t HLPUSART_RX_STA;//接收状态标记) U0 i1 ?' g9 e- C
- extern uint8_t HLPUSART_NewData;//当前串口中断接收的1个字节数据的缓存: H: B1 K) B# J( T0 a
- 5 ]- X$ J$ W e% p
- j0 h' r/ x2 t
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//串口中断回调函数声明
6 X4 O/ {6 J- i - 3 c% [2 N1 ^' U# {/ a
- #endif /* INC_USART_H_ */
复制代码 ) D+ j% ~& G3 m/ [
usart.c9 W( \6 N/ ^# g( w7 M+ |# |; E
- #include "usart.h"1 V3 h' ? k4 q/ `0 w7 c
- - P4 n) Y' U/ q3 g
- uint8_t HLPUSART_RX_BUF[HLPUSART_REC_LEN];//接收缓冲,最大HLPUSART_REC_LEN个字节.末字节为换行符( C- ?% y1 q9 R$ r1 @1 L
- /*
% p" E H( I6 o. Z8 o - * bit15:接收到回车(0x0d)时设置HLPUSART_RX_STA|=0x8000;" ]( e) X4 k" C. i
- * bit14:接收溢出标志,数据超出缓存长度时,设置HLPUSART_RX_STA|=0x4000;1 [' H/ b1 x3 h; F9 P
- * bit13:预留3 @' m) Z) n; t( x' @& _9 G8 p
- * bit12:预留, F% i' y; m, C4 ]4 n$ g5 k4 G/ ? F
- * bit11~0:接收到的有效字节数目(0~4095)
( W. U5 R8 D- ?8 U2 _0 h1 ~0 m - */
' L0 Q$ z/ B; W( Y* m - uint16_t HLPUSART_RX_STA=0;接收状态标记//bit15:接收完成标志,bit14:接收到回车(0x0d),bit13~0:接收到的有效字节数目( F% h# e3 O Y: H7 ^( G8 z1 }
- uint8_t HLPUSART_NewData;//当前串口中断接收的1个字节数据的缓存
% w# s" x6 a% z) Y- K7 [8 k* v( I* A# l -
+ _- @0 ?1 _+ x: | - void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数
2 w# q) `0 V( H/ J1 B5 x - {
+ M* n- C0 v0 ~ - if(huart ==&hlpuart1)//判断中断来源(串口1:USB转串口)4 l! e* Y* K7 w) \
- {1 L# ^) P" n D3 p
- if(HLPUSART_NewData==0x0d){//回车标记
/ Z* ^2 x( H* B2 M8 ?/ C) Q# N - HLPUSART_RX_STA|=0x8000;//标记接到回车
. a6 ?/ B+ [* U; @ - }else{
" `/ J! C* S, T% T" Y; t4 q* U - if((HLPUSART_RX_STA&0X0FFF)<HLPUSART_REC_LEN){9 t3 t- S2 E, K( u D9 O) V" e: T! S
- HLPUSART_RX_BUF[HLPUSART_RX_STA&0X0FFF]=HLPUSART_NewData; //将收到的数据放入数组& q' V) D3 {& A9 G% K( k
- HLPUSART_RX_STA++; //数据长度计数加1
: Q! o+ I$ ~: }8 t6 _ - }else{. Z- E ^( V, ]) x. ~- g; N
- HLPUSART_RX_STA|=0x4000;//数据超出缓存长度,标记溢出
& d1 [4 v# R- V; N% R7 n) U - }( o* t4 {" l( l# o& j4 V( ^7 J
- }
/ @8 v0 Y, d6 M2 y - HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData,1); //再开启接收中断
3 W- ~' W/ M+ [* E% a - } y+ \0 p, ?/ M* F
- }
复制代码
& q- L- i9 i, H( x2 R3 \ 5) LSM6DSL.h' [/ G ~9 B& d8 Y
- #ifndef _LSM6DSL_H_" R( @8 j' n3 j8 B/ f
- #define _LSM6DSL_H_% V" T4 t, b3 U2 u' m$ D. L
-
* [) o6 O! |4 k! X+ h - #include "main.h"
7 e/ ^8 V) A/ _/ \3 a: j9 r$ G2 v -
& m; g0 s% [: E. ^5 F* `/ _ - void LSM6DSL_init();
" p) i5 G2 `" |" s - //3 W8 {4 b2 M# s& Z, \) D3 D
- uint8_t LSM6DSL_acc_st_open(void);
4 k( C; f6 W, A+ {, {! z - uint8_t LSM6DSL_acc_st_close(void);
; T5 {+ `2 n' G6 n4 u- f/ k9 @ - , r$ c+ P p3 Z
- uint8_t LSM6DSL_gyro_st_open(void);4 U7 V+ Y9 |, G6 z7 K( b7 u. ^. w$ J
- uint8_t LSM6DSL_gyro_st_close(void);
9 m3 x# B% i# y; k -
. a3 `7 h9 F% e- e6 q' u+ C - uint8_t LSM6DSL_acc_read(int32_t *x_data,int32_t *y_data,int32_t *z_data);* |( X& m8 |, {3 c7 t
- uint8_t LSM6DSL_gyro_read(int32_t *x_data,int32_t *y_data,int32_t *z_data);0 u' W) X u9 g$ C! b9 ?1 P: b
- ; j$ t9 |" |' W2 {" e. _9 }
- #endif /* LSM6DSL_LSM6DSL_H_ */
复制代码 8 A b% |# `; G, m( h
LSM6DSL.c,实现传感器的ID检验、软重置、模式设置、数据读取及转换功能。* H( z+ u+ _9 [# h% z1 Z8 ?5 j
- #include <stdio.h>' G1 ^; n* J0 ?& s/ J( a
- #include "LSM6DSL.h"
+ Z2 G, z! A. z2 t# l! L - $ a4 h1 Q' B! V s) Y& f" s
- extern I2C_HandleTypeDef hi2c4;
! q* ^9 U& o' \: c% T& K* T7 w V: V - 7 |( X( h2 V- a9 A
- #define LSM6DSL_I2C_ADDR1 (0x6A)
4 a3 {; i7 B" L, @& d$ I( h - #define LSM6DSL_I2C_ADDR2 (0x6B)
1 Z' e" n& g/ b! B0 Q - #define LSM6DSL_I2C_ADDR_TRANS(n) ((n) << 1)
+ u0 C2 a: {1 V' _. k - #define LSM6DSL_I2C_ADDR LSM6DSL_I2C_ADDR_TRANS(LSM6DSL_I2C_ADDR2)8 z5 e, s' a8 N! N7 l# I* f
- + ?& s+ p/ ]' z$ r
- #define LSM6DSL_ACC_GYRO_FUNC_CFG_ACCESS 0x01' ~5 P6 W5 |: _( c* P
- #define LSM6DSL_ACC_GYRO_SENSOR_SYNC_TIME 0x04 g6 z# \, U+ g. B2 D% l: j
- #define LSM6DSL_ACC_GYRO_SENSOR_RES_RATIO 0x05& T7 |7 ?- f$ ^* p
- #define LSM6DSL_ACC_GYRO_FIFO_CTRL1 0x06
0 V1 }! O4 G, I3 v) t+ t8 n - #define LSM6DSL_ACC_GYRO_FIFO_CTRL2 0x07
3 E. N3 ^5 v# ]" N& s, u* w/ ~4 z - #define LSM6DSL_ACC_GYRO_FIFO_CTRL3 0x08
( `# X$ O' |0 i3 f+ S# A- F - #define LSM6DSL_ACC_GYRO_FIFO_CTRL4 0x09
$ ?& ?$ o! D& Q) Q - #define LSM6DSL_ACC_GYRO_FIFO_CTRL5 0x0A
& h* a4 u3 G9 ?5 ^7 F. a; ] - #define LSM6DSL_ACC_GYRO_DRDY_PULSE_CFG_G 0x0B' n z% a3 U+ t: W
- #define LSM6DSL_ACC_GYRO_INT1_CTRL 0x0D* G; e/ b' ?# r" j8 ~# u
- #define LSM6DSL_ACC_GYRO_INT2_CTRL 0x0E
& Z5 h' _$ A& D4 W - #define LSM6DSL_ACC_GYRO_WHO_AM_I_REG 0x0F
: d5 X& G4 ^: P$ Q, e# P7 H' ^ - #define LSM6DSL_ACC_GYRO_CTRL1_XL 0x10: Q* C( f* T! j$ r0 \ N" z1 F: A
- #define LSM6DSL_ACC_GYRO_CTRL2_G 0x11: f, p$ N1 T. o8 p8 r9 u
- #define LSM6DSL_ACC_GYRO_CTRL3_C 0x12: p- E$ t7 y" \& Y% P1 U5 C% _2 M
- #define LSM6DSL_ACC_GYRO_CTRL4_C 0x13
; ^2 `- i+ [, x- W$ m - #define LSM6DSL_ACC_GYRO_CTRL5_C 0x14
3 O4 e: e9 i( H - #define LSM6DSL_ACC_GYRO_CTRL6_C 0x15
- |: C Q/ j, k$ C) u, B - #define LSM6DSL_ACC_GYRO_CTRL7_G 0x16
' K+ Y* u$ W8 E) T$ B - #define LSM6DSL_ACC_GYRO_CTRL8_XL 0x17, p% R' e' O/ G5 @* G
- #define LSM6DSL_ACC_GYRO_CTRL9_XL 0x18
* q/ \' Q( d' A, _4 k5 \0 k: e& F - #define LSM6DSL_ACC_GYRO_CTRL10_C 0x190 M$ b- ~+ _1 _7 x
-
7 u- \1 ~* x( J$ P# F( B9 H c -
`& v+ z9 X/ W; |5 A: y' e - #define LSM6DSL_ACC_GYRO_MASTER_CONFIG 0x1A
& {2 R/ M/ W/ S" M9 @4 p - #define LSM6DSL_ACC_GYRO_WAKE_UP_SRC 0x1B
3 ]: z( T/ y% b/ W" B - #define LSM6DSL_ACC_GYRO_TAP_SRC 0x1C! m' s8 i/ Y; ^0 w
- #define LSM6DSL_ACC_GYRO_D6D_SRC 0x1D
. K/ R& ?- y2 E# f7 y! T - #define LSM6DSL_ACC_GYRO_STATUS_REG 0x1E
7 y" b7 ~8 M% K! w7 y -
+ T) x9 ?3 W n+ T( P/ n- f$ @ - #define LSM6DSL_ACC_GYRO_OUT_TEMP_L 0x20+ I& S+ h; A% R' x( [
- #define LSM6DSL_ACC_GYRO_OUT_TEMP_H 0x210 s5 F) T' ^& I# r# B- a4 Q
- #define LSM6DSL_ACC_GYRO_OUTX_L_G 0x22
8 k) o) h" j. ^9 n' q, B - #define LSM6DSL_ACC_GYRO_OUTX_H_G 0x23& x' a- N( x; L, E) H
- #define LSM6DSL_ACC_GYRO_OUTY_L_G 0x24 h$ q$ \. u& g) f8 u! y
- #define LSM6DSL_ACC_GYRO_OUTY_H_G 0x25# D _% _- R' L5 D
- #define LSM6DSL_ACC_GYRO_OUTZ_L_G 0x26
' O, @* O0 o* y. v/ V* Z, r* ~4 D - #define LSM6DSL_ACC_GYRO_OUTZ_H_G 0x27
: M) L* z6 J- h - #define LSM6DSL_ACC_GYRO_OUTX_L_XL 0x28, ^, u1 U8 ~3 b, a k9 _/ V% n5 y
- #define LSM6DSL_ACC_GYRO_OUTX_H_XL 0x29" Z. H5 c! `0 \ |- b' Q
- #define LSM6DSL_ACC_GYRO_OUTY_L_XL 0x2A9 e C( e0 L0 T/ J) t) r2 ]
- #define LSM6DSL_ACC_GYRO_OUTY_H_XL 0x2B
: c$ D$ Z+ B$ q1 U6 D$ N$ o- X - #define LSM6DSL_ACC_GYRO_OUTZ_L_XL 0x2C
, c# G/ P$ N+ D& D" ~ - #define LSM6DSL_ACC_GYRO_OUTZ_H_XL 0x2D
& F Z$ H3 _$ @ - #define LSM6DSL_ACC_GYRO_SENSORHUB1_REG 0x2E1 |1 Y3 Q) }' y. W! `
- #define LSM6DSL_ACC_GYRO_SENSORHUB2_REG 0x2F, r7 M9 N, I5 Y* Z
- #define LSM6DSL_ACC_GYRO_SENSORHUB3_REG 0x308 D* C b o: N0 {7 H
- #define LSM6DSL_ACC_GYRO_SENSORHUB4_REG 0x31& K6 e" k. S6 M2 d. I1 H
- #define LSM6DSL_ACC_GYRO_SENSORHUB5_REG 0x32
) k; C2 G2 R' [/ L# y - #define LSM6DSL_ACC_GYRO_SENSORHUB6_REG 0x33! u3 O5 f1 y1 A) J8 o
- #define LSM6DSL_ACC_GYRO_SENSORHUB7_REG 0x34
# S1 L! ~$ q5 x6 L! m! h/ q' _ - #define LSM6DSL_ACC_GYRO_SENSORHUB8_REG 0x355 X5 v. w/ h9 e Y1 r
- #define LSM6DSL_ACC_GYRO_SENSORHUB9_REG 0x36% d1 R N3 |$ ^, |- t
- #define LSM6DSL_ACC_GYRO_SENSORHUB10_REG 0x37 W. x# q) J; P$ T: ^
- #define LSM6DSL_ACC_GYRO_SENSORHUB11_REG 0x389 Z9 `5 W$ G: b( k8 V @
- #define LSM6DSL_ACC_GYRO_SENSORHUB12_REG 0x39 }+ { [: p+ Y' k6 V; ]
- #define LSM6DSL_ACC_GYRO_FIFO_STATUS1 0x3A
2 L: F3 j7 |# D& x% U' k! S% W& X - #define LSM6DSL_ACC_GYRO_FIFO_STATUS2 0x3B
/ t# I: E K$ j! g( ]0 p1 ?$ N" q - #define LSM6DSL_ACC_GYRO_FIFO_STATUS3 0x3C& E9 e$ F7 I- L7 I) ~
- #define LSM6DSL_ACC_GYRO_FIFO_STATUS4 0x3D
! F6 l9 ~3 O7 R C0 @2 _ - #define LSM6DSL_ACC_GYRO_FIFO_DATA_OUT_L 0x3E% {/ f6 R- y% V
- #define LSM6DSL_ACC_GYRO_FIFO_DATA_OUT_H 0x3F
. H- l6 D4 Z. A# c4 k3 N( ^ - #define LSM6DSL_ACC_GYRO_TIMESTAMP0_REG 0x40
! y. h* |0 r5 s" a3 f# \! V - #define LSM6DSL_ACC_GYRO_TIMESTAMP1_REG 0x416 V# x$ a$ T; I) A4 }( D3 G' ~
- #define LSM6DSL_ACC_GYRO_TIMESTAMP2_REG 0x42, V! o1 A& W3 r
-
* p8 i3 F% f6 t: W - #define LSM6DSL_ACC_GYRO_TIMESTAMP_L 0x497 B$ \/ S( a, @
- #define LSM6DSL_ACC_GYRO_TIMESTAMP_H 0x4A5 [( f. P6 a+ A( F. I+ ]3 ?, ]1 s
- : S, L& q0 m$ ]1 ~: E1 i8 n
- #define LSM6DSL_ACC_GYRO_STEP_COUNTER_L 0x4B1 `3 ~9 c c# m( ?
- #define LSM6DSL_ACC_GYRO_STEP_COUNTER_H 0x4C
/ N/ }( _! a" l R; T; G - # w; T2 n1 D* A o! u: `& l
- #define LSM6DSL_ACC_GYRO_SENSORHUB13_REG 0x4D# I4 }* N$ @& K" m
- #define LSM6DSL_ACC_GYRO_SENSORHUB14_REG 0x4E
7 S8 g3 Y* ?* `0 g& R - #define LSM6DSL_ACC_GYRO_SENSORHUB15_REG 0x4F
) E- @- R/ J5 ^7 p% K, u - #define LSM6DSL_ACC_GYRO_SENSORHUB16_REG 0x50
7 B! ^/ {* }+ j$ b9 C - #define LSM6DSL_ACC_GYRO_SENSORHUB17_REG 0x51/ C# s9 b" }' P3 f
- #define LSM6DSL_ACC_GYRO_SENSORHUB18_REG 0x52
2 z0 m D4 A7 o( x -
) V. Y2 f, b* ~! F0 U - #define LSM6DSL_ACC_GYRO_FUNC_SRC 0x53
2 B, |& b* i, R8 V/ F& y - #define LSM6DSL_ACC_GYRO_TAP_CFG1 0x58
; c# M" k J+ `& m - #define LSM6DSL_ACC_GYRO_TAP_THS_6D 0x59" c$ {2 x: o5 C6 ]1 h$ c
- #define LSM6DSL_ACC_GYRO_INT_DUR2 0x5A
8 i% J' q( n; ^( b, p - #define LSM6DSL_ACC_GYRO_WAKE_UP_THS 0x5B
/ | ~2 R9 y6 s% z4 |( S - #define LSM6DSL_ACC_GYRO_WAKE_UP_DUR 0x5C
, u9 f# ]! z# w0 r5 s1 Y4 u - #define LSM6DSL_ACC_GYRO_FREE_FALL 0x5D }! H2 u3 D$ h" _; b" ^! }/ i. Z; G
- #define LSM6DSL_ACC_GYRO_MD1_CFG 0x5E
% |; e5 T0 C2 r - #define LSM6DSL_ACC_GYRO_MD2_CFG 0x5F
: V% [2 y, ? v H/ ?/ p3 m d - * T4 Y3 ]- c1 [) i( K! o! d9 t
- #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_X_L 0x660 X- j$ j- {: O" B" I. Y; _
- #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_X_H 0x67+ Z$ y. W' A2 H9 A6 ?9 U$ z2 h0 ?
- #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Y_L 0x686 ]& W, Z; N; \: K" U$ Z/ S
- #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Y_H 0x69, I1 Z- \0 f7 O9 ~& ?! V0 j+ U s+ M* s8 @
- #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Z_L 0x6A
% n: ]7 U% d3 B+ ^ - #define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Z_H 0x6B
; z+ H0 |9 z/ n' q$ X - 7 G% b! |6 P+ K* l$ h% L2 I
- #define LSM6DSL_ACC_GYRO_X_OFS_USR 0x73
5 O n- l4 i: @: C - #define LSM6DSL_ACC_GYRO_Y_OFS_USR 0x74. v( X$ a$ j$ |( N- D
- #define LSM6DSL_ACC_GYRO_Z_OFS_USR 0x75
6 R- Y- H, l% Y& y W# h+ q - 1 X, k9 C; ]! {6 J
- #define LSM6DSL_CHIP_ID_VALUE (0x6A)
" [, o) _5 f' _" J1 M/ j6 | -
, z- K+ Q, f A" T" d# J2 U2 A - #define LSM6DSL_RESET_VALUE (0x1)
9 T8 m: L* p" f' W+ u" w. s - #define LSM6DSL_RESET_MSK (0X1)0 Y# S! k) Z5 [/ j* c% i, b
- #define LSM6DSL_RESET_POS (0)
0 x0 O: O7 h0 V3 F& p - 3 o6 T" T0 u# ` C
- #define LSM6DSL_ACC_ODR_POWER_DOWN (0X00)4 P5 S( X/ k! `9 y7 i
- #define LSM6DSL_ACC_ODR_1_6_HZ (0X0B)7 X; \+ y& B+ t3 n
- #define LSM6DSL_ACC_ODR_12_5_HZ (0x01)* S: D" }2 p* O" T) w( F
- #define LSM6DSL_ACC_ODR_26_HZ (0x02)9 n. `9 @: y& [/ h1 i
- #define LSM6DSL_ACC_ODR_52_HZ (0x03)! O: p* D) E. R& f
- #define LSM6DSL_ACC_ODR_104_HZ (0x04)# \- z/ H$ l6 E+ q2 h- V2 B! ~
- #define LSM6DSL_ACC_ODR_208_HZ (0x05)* G! H; V7 H+ s& m
- #define LSM6DSL_ACC_ODR_416_HZ (0x06)
' C d& a& ]: f - #define LSM6DSL_ACC_ODR_833_HZ (0x07)
: ?7 V8 P0 c2 ?- G5 E - #define LSM6DSL_ACC_ODR_1_66_KHZ (0x08)
5 y2 z4 Q+ e" E" a4 Y. S4 ^" y - #define LSM6DSL_ACC_ODR_3_33_KHZ (0x09)
- l6 l8 y- z6 N" q0 E; s. S. K - #define LSM6DSL_ACC_ODR_6_66_KHZ (0x0A). ^+ Q7 D- |; M8 k+ F
- #define LSM6DSL_ACC_ODR_MSK (0XF0)1 F. T ]0 [3 p. R: S* m+ A
- #define LSM6DSL_ACC_ODR_POS (4)
& C' @ ], v* u' [/ C; O' U -
6 k* K$ e" v7 G; D) p - #define LSM6DSL_GYRO_ODR_POWER_DOWN (0X00)
; \8 I/ M& f" r5 O7 r" F - #define LSM6DSL_GYRO_ODR_12_5_HZ (0x01)
q6 c8 k# i# k - #define LSM6DSL_GYRO_ODR_26_HZ (0x02)" h8 L+ }4 Q5 }/ [" t
- #define LSM6DSL_GYRO_ODR_52_HZ (0x03)
3 P' V8 S$ [" K# a/ q - #define LSM6DSL_GYRO_ODR_104_HZ (0x04)
_; b3 M* ^. ?: J3 }4 l5 p, c - #define LSM6DSL_GYRO_ODR_208_HZ (0x05)8 T9 R. j6 K8 B1 f
- #define LSM6DSL_GYRO_ODR_416_HZ (0x06)9 t, T* P$ E: }3 _7 }0 A+ _
- #define LSM6DSL_GYRO_ODR_833_HZ (0x07), x, U# Z. l# g2 n* e
- #define LSM6DSL_GYRO_ODR_1_66_KHZ (0x08); ]: {- Z Y) ?4 Z! L4 x2 @
- #define LSM6DSL_GYRO_ODR_3_33_KHZ (0x09)9 H& x- Z' {. W0 v& f. b
- #define LSM6DSL_GYRO_ODR_6_66_KHZ (0x0A)
# M0 u4 o5 w: X2 x3 o( ~ M - #define LSM6DSL_GYRO_ODR_MSK (0XF0)
" O* H- p% o' c& y# i - #define LSM6DSL_GYRO_ODR_POS (4)
1 P, S( l% i6 x8 e4 n* a8 m9 n -
9 d. b+ D* Y& C! v$ V - #define LSM6DSL_ACC_RANGE_2G (0x0)' d3 ]* @% ^, j+ k3 S$ y6 d9 e
- #define LSM6DSL_ACC_RANGE_4G (0x2). S: n4 O- m5 N4 x5 e
- #define LSM6DSL_ACC_RANGE_8G (0x3)- b0 z8 d+ g3 E. n2 W; h
- #define LSM6DSL_ACC_RANGE_16G (0x1)* Z' ~6 n5 n3 N! F2 }
- #define LSM6DSL_ACC_RANGE_MSK (0X0C)
' g9 u- y$ y7 [9 A- t - #define LSM6DSL_ACC_RANGE_POS (2)
% T/ A9 D. M2 k+ i8 j9 ^ - 1 h8 L: _4 v! O! |& t* ~
- #define LSM6DSL_ACC_SENSITIVITY_2G (61)+ l& y' C( j9 f& A" W$ B
- #define LSM6DSL_ACC_SENSITIVITY_4G (122)6 {* l, a* x+ G- j9 Y% L
- #define LSM6DSL_ACC_SENSITIVITY_8G (244)
# I& h1 g4 ]9 G, x - #define LSM6DSL_ACC_SENSITIVITY_16G (488)2 A7 A1 [* q5 w/ v. b* \7 G) ^ L
-
9 G4 Z8 _3 U7 ] - #define LSM6DSL_GYRO_RANGE_245 (0x0)
4 N4 u$ x; B$ S% X9 c! E5 q - #define LSM6DSL_GYRO_RANGE_500 (0x1)
* e" A' G" T( h$ O8 ? - #define LSM6DSL_GYRO_RANGE_1000 (0x2)& q5 e% H2 c; M; P, x% y
- #define LSM6DSL_GYRO_RANGE_2000 (0x3)
; ~( k2 K* M0 G. n, d - #define LSM6DSL_GYRO_RANGE_MSK (0X0C)
' T. F3 O- f+ _+ J* U& j3 E' { - #define LSM6DSL_GYRO_RANGE_POS (2)$ b- y! e2 _5 k9 Q
- 8 x5 ]! d( N! p6 j6 ~( k- ?
- #define LSM6DSL_GYRO_SENSITIVITY_245DPS (8750)6 Q3 y, a0 L+ _( g7 l% ?" y. A
- #define LSM6DSL_GYRO_SENSITIVITY_500DPS (17500) y! { \ a* \- y, V& |" s3 q
- #define LSM6DSL_GYRO_SENSITIVITY_1000DPS (35000)0 ]& P; k( [. G7 {, i! V3 N4 H
- #define LSM6DSL_GYRO_SENSITIVITY_2000DPS (70000)0 L; e& X8 y" Z! p
-
2 N% h, @# a( s - #define LSM6DSL_SHIFT_EIGHT_BITS (8)
+ b) |) Y N5 P' s0 G! B - #define LSM6DSL_16_BIT_SHIFT (0xFF)
3 W1 o( |- h( C$ B! x/ r0 |3 s6 Y - #define LSM6DSL_ACC_MUL (1000)
! u8 D! o4 Y! L2 J" b - #define LSM6DSL_GYRO_MUL (1)! L8 f/ ?3 H: y$ [, N8 B- ]
- & T3 i! ~8 n9 Q3 G
- #define LSM6DSL_ACC_DEFAULT_ODR_100HZ (100)0 |, N: j9 l4 W) _; O* J
- #define LSM6DSL_GYRO_DEFAULT_ODR_100HZ (100)' J' ]8 [! c+ m! ^! y9 N0 X: b4 h4 a2 H
-
: |0 ?; `! A% j! o$ |' h; h; c% E - #define LSM6DSL_GET_BITSLICE(regvar, bitname) \
. A& s4 |$ U$ {+ w. J - ((regvar & bitname##_MSK) >> bitname##_POS)
, R0 R7 W6 d) z( k* ~. y - s# _* S0 G2 ~8 s* H& z9 e
- #define LSM6DSL_SET_BITSLICE(regvar, bitname, val) \7 |# g9 P/ L* z# R, G/ B
- ((regvar & ~bitname##_MSK) | ((val << bitname##_POS) & bitname##_MSK))4 i R. g% g5 n- X2 D- C: X, l# f3 B
- 5 C/ a' [5 F$ c, R- {6 @9 f
- typedef enum {) u- m8 _1 q4 A+ s9 w; N2 `0 _
- ACC_RANGE_2G,6 F+ |- K& {( `
- ACC_RANGE_4G, E7 n9 `/ J9 F* P3 U5 l* L
- ACC_RANGE_8G,# p! H. h4 b+ _2 F' m
- ACC_RANGE_16G,
' s8 b/ i- W1 m6 m2 S$ y6 h - ACC_RANGE_6G,
2 \; a3 x. R w8 ]: x( i* D; d- U! @ - ACC_RANGE_12G,/ w& C- \1 k H) N# x
- ACC_RANGE_24G,% L6 }) Q/ G1 H7 ^8 m: H' b/ ]
- ACC_RANGE_100G,
) q5 }$ Y4 V# p' L0 R* {' Q - ACC_RANGE_200G,1 n9 ^' [0 `- L3 `$ [
- ACC_RANGE_400G,
4 d2 ]" t0 [: V T- Z# Z: j$ ]/ s) k - ACC_RANGE_MAX
! S1 f0 m1 x L! A, J6 ` - } acc_range_e;4 F# c. k6 j8 T' [( p4 @
-
% A! H8 T" M3 T2 r+ u; F - typedef enum {- |- {2 }% D1 b% \/ t+ o5 x+ V
- GYRO_RANGE_125DPS,' r1 K! k% r6 m f2 d0 p( H6 q3 O
- GYRO_RANGE_250DPS,7 B7 S: F V8 L' g' j. Y
- GYRO_RANGE_500DPS,7 Y" X4 v% a p
- GYRO_RANGE_1000DPS,9 }7 u- Z" ]) `( K$ `4 K4 Z2 |' V1 k
- GYRO_RANGE_2000DPS,
3 V: m$ d: J, s! m/ S - GYRO_RANGE_MAX
C+ j) `/ e1 i6 y/ [/ u - } gyro_range_e;
+ w1 i& l9 z+ m' ~ -
# b. ^( G1 D$ V8 e# r+ N3 w - static int32_t lsm6dsl_acc_factor[ACC_RANGE_MAX] = {
8 N0 h+ z7 i1 w% p( c9 v - LSM6DSL_ACC_SENSITIVITY_2G, LSM6DSL_ACC_SENSITIVITY_4G,) @9 v4 s. j; @9 C8 Z
- LSM6DSL_ACC_SENSITIVITY_8G, LSM6DSL_ACC_SENSITIVITY_16G
1 b6 P, U! t4 G( S! I3 X - };. ]# k' g' L& g
- static int32_t lsm6dsl_gyro_factor[GYRO_RANGE_MAX] = {3 `8 L! K& J5 k+ U9 k5 a, q
- 0, LSM6DSL_GYRO_SENSITIVITY_245DPS, LSM6DSL_GYRO_SENSITIVITY_500DPS,; j5 B8 Y6 t! m$ v$ V0 Z
- LSM6DSL_GYRO_SENSITIVITY_1000DPS, LSM6DSL_GYRO_SENSITIVITY_2000DPS
B8 S/ t7 P/ u6 V3 V& m - };
% t: ?4 k1 |2 U6 a) }" ]3 W3 w -
6 q& ~. D' z! S* b8 y- i - typedef enum { N; I% i7 x; q5 @& a, d7 Q
- DEV_POWER_OFF = 0,
7 A( A3 z+ P% a6 p - DEV_POWER_ON," b) z) ]9 a7 i3 O
- DEV_SLEEP,
W9 Z |6 _. Y - DEV_SUSPEND,; P C9 @8 v8 ]( f8 w+ S( L; E% E
- DEV_DEEP_SUSPEND,
3 B9 o4 |! \3 w - } LSM6DSL_power_mode;
" s5 s3 K' O+ R4 K! z9 A @: C1 T: [ - - V8 a" R6 X4 t1 O, b
- static int32_t cur_acc_factor = 0;- U2 a) m+ }8 K2 _) `
- static int32_t cur_gyro_factor = 0;
# K8 X% [: N. N# q/ E1 E -
( L3 a2 U1 M( |# T4 Q- z - uint8_t LSM6DSL_ID_check() o2 v) `2 e; i) d6 m0 V' o% j$ X
- {, ]! Z$ ]0 k. O+ H7 [5 R, I( P
- HAL_StatusTypeDef hi2c2_status = 0x00;
5 y: O+ I7 X2 D1 `1 O u - uint8_t addr_val[3] = {LSM6DSL_ACC_GYRO_WHO_AM_I_REG,0x00,LSM6DSL_CHIP_ID_VALUE};9 N$ B% N( i" G0 t9 U2 z
- hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
: {5 I7 q6 |6 ?/ v& I' s - if(HAL_OK!=hi2c2_status){
$ O- H' Z5 S$ t% h - printf("get LSM6DSL ID error\r\n");, @" n2 J0 O: D/ D
- return 1;
( i+ k+ @$ l% e" r" l - }
/ P; ~# c# o- K! {, n - if(addr_val[1]!=addr_val[2]){
6 E; t5 L0 {) m" ? - printf("LSM6DSL validate_id is error\r\n");
& w! M4 X/ o) `' t - return 1;
) ^9 t3 g8 B! y1 d( H7 s! Z - }
: i8 v' p# S* O# N$ ?( t - printf("LSM6DSL_id:%02X\r\n",addr_val[1]);
c: `$ `5 D/ m# E# D% j0 z# k! | - return 0;
* o7 u# B% W6 X0 _, L9 Z& Y - }! F' I+ L5 H7 l* \! I0 h" B8 U
- , s I! X/ D8 S. D) S9 G
- uint8_t LSM6DSL_soft_reset()
/ ~+ t3 d2 H9 N5 s - {
. R+ f. ], `3 L3 o6 ` - HAL_StatusTypeDef hi2c2_status = 0x00;1 I8 R ~( e9 ?( Z6 x) c7 y
- /*first read*/* U8 e& X* C( O( t" h
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL3_C,0x00};
+ k) r1 Y5 [! \ O - hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);* ~. P p' A9 \9 a% _% Q
- if(HAL_OK!=hi2c2_status){
3 {, E" m/ U2 F/ z3 f* T - printf("get LSM6DSL ACC_GYRO_CTRL3_C error\r\n");3 y i2 [4 n# ~# Z6 z6 \' h; Y0 p
- return 1;
1 z/ i5 \4 [# L; F" m& x0 R5 l6 g - }
; s& M( x4 F+ t% N7 Q* ]9 X& K3 A, s - printf("LSM6DSL ACC_GYRO_CTRL3_C old:%02X\r\n",addr_val[1]);
, X) {* `9 @7 B8 @7 N# G - addr_val[1] |= LSM6DSL_RESET_VALUE;
; x8 C1 W$ g/ [' A9 X - printf("LSM6DSL ACC_GYRO_CTRL3_C new:%02X\r\n",addr_val[1]);, O* Y' k4 T4 t+ A6 M$ t
- hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
' ]/ |8 l' H5 w9 j2 C: u) i: u; w - if(HAL_OK!=hi2c2_status){
6 j* E: A2 A6 L1 f" M1 m+ [/ _ - printf("set LSM6DSL ACC_GYRO_CTRL3_C error\r\n");
' p: x# r5 @( \: a. `, ] - return 1;; U$ v! y2 Q: C" _2 j
- }* p' S1 y0 e; M$ C
- printf("successfully LSM6DSL soft reset\r\n");. L# ^' q) w3 W& M* {+ v$ r; X
- return 0;6 J r1 @( `- X2 ]' |- g
- }, v6 \- O( q2 x
- /*
) v1 r6 W9 g2 _" J1 X! b - * 以正数为例,最大可到32767,如果是Accelerometer数据,量程为2g的情况下,' G7 g& L7 l$ q/ t$ [% s, S; ?0 ]% p: k
- * 32768个刻度,一个刻度代表:2g/32768 = 2000mg/32767 = 0.061035mg6 G* B& ]# P( S9 _
- * 例如:如果读出数据为16384,则加速度:16384x0.061035mg = 1000mg = 1g ]. |' y8 T! \
- */
$ G8 | Q4 A% D' K: X) _ - uint8_t LSM6DSL_acc_set_range(uint32_t range)& M/ d+ m! D1 s
- {+ Q- y7 ]$ `4 {* {+ M6 w7 C; P1 ~
- HAL_StatusTypeDef hi2c2_status = 0x00;
, H0 u& g7 ~, P - /*first read*/
9 X* c' B' v9 E9 N L6 g - uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL1_XL,0x00};
2 X5 a; @; k& e9 G; \& l1 ?7 r - hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
2 J' D; g* {8 v1 `7 w$ O4 E - if(HAL_OK!=hi2c2_status){
+ _# d Q% A% \5 |1 m - printf("get LSM6DSL acc range error\r\n");! G% P0 m( }5 {/ {( n+ x9 W
- return 1;
5 C( m" \3 B0 G1 c7 g - }
$ z1 r7 {* _4 A1 k/ D - uint8_t tmp = 0;5 I' W- R. L8 @6 z8 s3 K3 t6 A# a
- switch (range) {1 h/ c7 R* x7 V y& ?7 h9 ]; i" `
- case ACC_RANGE_2G: {
2 z6 |7 c+ o$ \- s7 |( P - tmp = LSM6DSL_ACC_RANGE_2G;
9 L. F% W5 c H: h - } break;7 h' Y4 [% ?) W' \% H
- ; l7 Z0 j' b/ f* N/ V# u
- case ACC_RANGE_4G: {
4 [) k$ y$ W: t2 o9 l - tmp = LSM6DSL_ACC_RANGE_4G;! N* z4 }% U/ P' R+ ?% A7 ]
- } break;+ v7 x- h2 p4 j6 h7 s& D
- : ]4 q8 U% }7 t5 }, o, }
- case ACC_RANGE_8G: {
i; |3 H7 n& q& M# F2 t: ? - tmp = LSM6DSL_ACC_RANGE_8G;
5 ]) R; |0 |3 d - } break;/ L$ A' g% a. E3 U7 p8 c
- ( I6 |0 i4 a! A' ~8 K
- case ACC_RANGE_16G: {
) m' \: P) E& m8 q& P9 ~! G - tmp = LSM6DSL_ACC_RANGE_16G;* z/ K4 t4 p q o7 y
- } break;
6 |2 J' m% U# Z - 4 O" P* z$ \4 K3 ?) h1 E) s+ h4 _1 A
- default:- R1 c; }& U. s* w
- break;7 H- R/ p* n P1 E; e$ P, Q
- }3 h7 k& [/ z8 l/ _. K+ W
- addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_ACC_RANGE, tmp);% z: j: C' e- C+ q
- hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);) N I1 S8 r8 X0 \# m
- if(HAL_OK!=hi2c2_status){% ^ m6 U6 ^: F+ e' I3 o
- printf("set LSM6DSL acc range error\r\n");
. E9 l) L1 i" |( P6 z Q% z - return 1;
8 M+ T; T" S, s2 F; W. _ - }, I8 W$ T1 y- }9 x( B
- if (range <= ACC_RANGE_16G) {, h6 Y* A3 i& o% W( p9 p1 V
- cur_acc_factor = lsm6dsl_acc_factor[range];
+ T+ q% g9 f Q% ?: V$ [% I* r/ Y - }
: x* ~/ ?3 a' y& h' J - printf("successfully LSM6DSL set acc range\r\n");
: r) V/ N- Q* l5 y( [ - return 0;
9 _$ A; [% I0 ^0 ?* d - }8 n8 | y6 x5 f- u `6 i! l5 c
- ; W( J5 H$ f4 c; _3 l* W3 y9 w
- static uint8_t acc_st_lsm6dsl_hz2odr(uint32_t hz)3 \* z3 P# i+ K( y5 _
- {
3 g" ]. Z0 {% m% F - if (hz > 3330)7 r5 k* p: @3 }0 p. }' @
- return LSM6DSL_ACC_ODR_6_66_KHZ;' ?# i/ r% v2 F. r/ `
- else if (hz > 1660)
1 ^9 l2 y v! x - return LSM6DSL_ACC_ODR_3_33_KHZ;
2 n) x% p8 M+ S! L! \. y+ W) f" g - else if (hz > 833)6 ~2 w" R: U' o* q' w
- return LSM6DSL_ACC_ODR_1_66_KHZ;
1 J2 x% P& w3 n6 c3 w; ~ - else if (hz > 416)2 H. ~/ C6 F8 n7 ?$ ^# }
- return LSM6DSL_ACC_ODR_833_HZ;
6 i9 u/ Z" {% @" K& @* r' d - else if (hz > 208)
8 \* j; u1 B/ \! i$ P - return LSM6DSL_ACC_ODR_416_HZ;
# T0 {) U: W2 n2 n - else if (hz > 104)" p3 ]9 P/ P/ K" r8 z8 H, _7 v2 ^5 o
- return LSM6DSL_ACC_ODR_208_HZ;% Y' J3 _& Y% H4 \2 `
- else if (hz > 52); ~6 g& W( D% U* E
- return LSM6DSL_ACC_ODR_104_HZ;
6 k. K7 |% B4 G' | - else if (hz > 26)$ G' n; j& l' R
- return LSM6DSL_ACC_ODR_52_HZ;' }4 G! T2 O, R( ^, {% T! ]% h
- else if (hz > 13) l7 D% G# d" w6 k! K9 D
- return LSM6DSL_ACC_ODR_26_HZ;
; |/ d( o+ c3 s5 ?5 h1 m - else if (hz >= 2)
. H. J0 r3 A6 n# L( {/ D/ w - return LSM6DSL_ACC_ODR_12_5_HZ;
7 n9 z2 l' b6 }# `9 p' m - else
3 B+ I4 t& o) i7 R - return LSM6DSL_ACC_ODR_1_6_HZ;
+ O1 }5 R- p) m& o$ }" m. u - }
8 `( u2 _# k/ u, d6 K6 T - 1 B: Q" h9 l# g
- uint8_t LSM6DSL_acc_set_odr(uint32_t hz)
v" M7 O% [( I; u7 t - {$ Z, L3 f- l. n! B/ F* i. {
- HAL_StatusTypeDef hi2c2_status = 0x00;! F. |, W7 Q9 q# q8 Z
- /*first read*/$ e% v5 \1 e: S6 r; K' U
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL1_XL,0x00};
, v+ l U6 V% H - hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);' q7 I9 I8 x) T0 v# C4 r
- if(HAL_OK!=hi2c2_status){
5 X5 H9 }% n# B, r0 r3 s- D' ~0 D - printf("get LSM6DSL acc odr error\r\n");
. m1 K" e; w" \5 Z - return 1;
$ {. o% E6 H" s3 W: A' H - }: ]9 J* ` Z. L5 r+ i' t# \
- uint8_t odr = acc_st_lsm6dsl_hz2odr(hz); Y: m* p2 H3 B7 q
- addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_ACC_ODR, odr);
& r. J4 t* _: t6 }2 ~" R( G- } - hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
6 I( z# s5 S9 U9 { - if(HAL_OK!=hi2c2_status){8 ?; `( |$ l, ^: u9 t0 E: T& v
- printf("set LSM6DSL acc odr error\r\n");
" y. n! M$ L! k; w - return 1;5 N. m: l- M9 S. T9 K2 b" E9 p8 ?3 h; X& P
- }
$ S& z) w5 c; I' p1 @' v: j - printf("successfully LSM6DSL set acc odr\r\n");! B% d& C4 q/ X$ ?$ {/ b( R" ]
- return 0;# q, ?/ ]; X9 u' Y! g( f
- }, ]5 ]: {: x5 f5 S( r3 G0 s
- , z J: w1 [' i" z. k
- uint8_t LSM6DSL_acc_power_mode(LSM6DSL_power_mode mode)5 f8 `3 l3 @+ U: T& v# i
- {
; J% G' v$ |: p- { - HAL_StatusTypeDef hi2c2_status = 0x00;' l3 ]5 N% r' r3 {2 W2 _
- /*first read*/6 |* E% c, m2 L# G3 v( F
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL1_XL,0x00};! X& r- i- y+ J- n
- hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
! |; t/ k8 _9 M; P M7 b - if(HAL_OK!=hi2c2_status){
1 t% v' [$ l' P8 e! G - printf("get LSM6DSL acc power_mode error\r\n"); q9 h/ G) x1 h( M5 [
- return 1;
+ v5 M6 W, Q0 g$ E. S5 T - }0 d- I! [9 z1 Z, j: }2 V) X
- switch (mode) {* D0 U/ y9 r- K$ ~+ f) {
- case DEV_POWER_ON: {
) L& c/ }* f6 K: @& X) a - addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_ACC_ODR,LSM6DSL_ACC_ODR_12_5_HZ);) y5 |, B9 I; O: Z7 ~. T4 w
- }, d, t3 w5 [- Q
- break;5 l( H! K, o- g1 k7 m2 a
- case DEV_POWER_OFF: {
. m. `/ |3 c1 B! x - addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_ACC_ODR,LSM6DSL_ACC_ODR_POWER_DOWN);# X; H! ^$ e& D; w; [8 Y! h1 E4 U
- }
: s" t7 C, j9 L" E: y' Y' a2 S - break;
7 b0 t) B+ j# q1 ?: p4 p. k6 ]9 | - case DEV_SLEEP: {9 J/ r" |, L9 y9 ], T3 o; Z3 ^
- addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_ACC_ODR,LSM6DSL_ACC_ODR_12_5_HZ);
3 A! N- X/ \% T K3 {2 r - }
1 d* d& ^7 J& r2 p# z - break;
' a& @7 ~, |/ M, u# ? - default:
1 D s8 [& N! ~/ w4 x8 g! Q1 D - break;
) |# r- b. }2 E - }# H3 z( d4 i/ g/ T# i3 T) o
- hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);. e( s' \( p! d7 V, }
- if(HAL_OK!=hi2c2_status){( j- j+ f! B1 [! H$ g
- printf("set LSM6DSL acc power_mode error\r\n");+ [( Y, t$ I" k
- return 1;
3 _! ^" F4 S6 r, ~' ~ Z - }) ]( O. L# `) b# `: J
- printf("successfully LSM6DSL acc power_mode\r\n");1 ^1 p7 U8 {4 C" t* M- v7 C5 A. N
- return 0;
4 [& r2 y- c3 i - }
% g' t1 E" H+ O - . P. E+ `7 i$ y
- uint8_t LSM6DSL_acc_st_open(void)
: L t! O2 V& ~& x0 [ - {) j$ |" U9 u& D) S! a& ~5 Z& |
- uint8_t ret = 0;
) X: p# y8 m% T - 6 {+ u. ~( M2 k( f; ^3 o8 d/ u
- ret = LSM6DSL_acc_power_mode( DEV_POWER_ON);$ z5 w1 G2 R# L5 b9 P* H
- if (ret>0) {' W4 I4 \" W, O+ e" }$ R2 z) f
- return ret;, f* D! m/ }( |: ] m9 k* v9 b
- }
/ k0 J8 Y& D0 P$ F - 9 p+ q% g$ \2 b3 }) r
- ret = LSM6DSL_acc_set_range(ACC_RANGE_8G);
) I6 o4 O' r/ X0 J - if (ret>0) {, l0 r8 m* p. [: d. V7 H
- return ret;( @( L0 K' p5 k7 Q# P1 i) G) D' E
- }# ^4 X, d' S5 Y7 \8 `* h
-
6 q" k9 F- y- @: y - ret = LSM6DSL_acc_set_odr(LSM6DSL_ACC_DEFAULT_ODR_100HZ);
8 z- W8 C& ?2 i/ F - if (ret>0) {
) k: J+ I! q0 v$ r - return ret;0 V+ b1 R8 x- q9 A" n" j# ^/ N4 z1 z
- }$ W: V: |/ x) z( ~9 E% N, Y9 n
- printf("successfully LSM6DSL acc open\r\n");
/ c* |- ]' V" S0 f' L3 c- H - return 0;* u9 \" x1 M# D
- }& l$ c3 V8 c- y& T/ D
-
8 q, Q) V! O8 `0 q5 E# k - uint8_t LSM6DSL_acc_st_close(void)
* }& A% r" k! s - { ^- ~3 ~* b0 m5 a9 w- j" S- V v
- uint8_t ret = 0;
3 b- M& m6 }* `8 J! t7 G - ret = LSM6DSL_acc_power_mode(DEV_POWER_OFF);
9 g6 Y5 z0 s' z - if (ret>0) {3 \/ W& E$ y7 v- ?* E
- return ret;
* a# w" Q B4 {8 t( d3 U - }
' t& n$ K* n, P/ q# _( A - printf("successfully LSM6DSL acc close\r\n");5 R, o9 C( X* v6 I' H. y
- return 0;# p+ s5 W0 i+ h$ ]. F7 j+ K6 R
- }6 H9 F! K- K; f7 K& g! Y3 Z8 {
- ( B! {* Z/ Y4 k) w# B
- //LSM6DSL的满刻度加速度范围为±2/±4/±8/±16 g,角速度范围为±125/±250/±500/±1000/±2000 dps。( R0 E' _- Q7 @
- uint8_t LSM6DSL_gyro_set_range(uint32_t range)
; E7 [" ^ q9 K3 _: s5 } - {
0 I$ b6 [. `$ g! B. S - HAL_StatusTypeDef hi2c2_status = 0x00;6 F0 G4 X8 H2 o' p6 E2 \$ u- b5 \
- /*first read*/- p7 v# G, b" ` z7 c- a( b
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL2_G,0x00};) k8 J1 ~" c* L3 J
- hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
. D: Q& D7 y, H1 A - if(HAL_OK!=hi2c2_status){
3 s) `/ j' F5 g! y5 Y - printf("get LSM6DSL gyro range error\r\n");3 ^) O q9 }; k) P9 z
- return 1;3 [- t3 B l# O- P: G
- }( }/ I Q; C6 ~# I8 a8 a
- uint8_t tmp = 0;% ?) j/ G' o3 A! W- s7 t
- switch (range) {
8 g; t" f* ?; b' {. h - case GYRO_RANGE_250DPS: {
- J, o" S( X, k5 k. M - tmp = LSM6DSL_GYRO_RANGE_245;
8 a# J) d E1 E5 {4 g - } break;
6 |- u4 J+ ]6 b; Z -
Q' z# }! B' h2 V6 ?6 C - case GYRO_RANGE_500DPS: {2 j; ^/ s; t& }. F9 X% }
- tmp = LSM6DSL_GYRO_RANGE_500;4 L/ M1 M0 E$ V4 i
- } break;
. b) s# {! e- ]/ p) ~1 q; U -
; N( K$ I7 d% Y3 O5 n9 R- b - case GYRO_RANGE_1000DPS: {
6 @) e6 x3 z' R; {# e7 |4 l) t - tmp = LSM6DSL_GYRO_RANGE_1000;
$ r7 I0 f$ u5 R7 ]" \ - } break;) b: W, y+ V5 O3 h
- ) q3 Q) `& |3 ]8 y$ R
- case GYRO_RANGE_2000DPS: {
6 E) U$ B. ?) r5 u6 Z1 L. Y2 M. X - tmp = LSM6DSL_GYRO_RANGE_2000;& Y$ X9 ?2 Q( v, X7 T% g
- } break;9 }2 C2 M5 s4 ?! x1 a+ u9 ^
- - V1 |8 O8 a% w& @! L
- default:
- W$ K$ U/ o+ O# n) M& {: | - break;6 U" W9 m* U$ L1 A" q( F7 D# ^, @" X
- }7 z9 t% A& B% A, ]0 }! ~
- addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_GYRO_RANGE, tmp);
3 ~1 q$ @8 _" O4 P - hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);0 m$ ]7 _) ?/ S7 K8 h+ P
- if(HAL_OK!=hi2c2_status){7 @3 z: C) ]) N' g) n
- printf("set LSM6DSL gyro range error\r\n");
i" H6 g6 F: N& j5 `1 w; Z - return 1;3 B y/ P* A8 Q3 c
- }+ d. F, ^' n* p1 E& P
- if ((range >= GYRO_RANGE_250DPS) && (range <= GYRO_RANGE_2000DPS)) {7 Q+ y, W2 F3 Z6 t
- cur_gyro_factor = lsm6dsl_gyro_factor[range];
+ u% t6 k e3 \. N) E - }2 g+ y1 s3 P4 X
- printf("successfully LSM6DSL set gyro range\r\n");# X8 n( V( ^) o) S ?6 _
- return 0;
' S+ X0 ^( w$ [ - }, i/ t0 F1 a+ ]% A1 w4 _
-
5 c0 P% k$ J- _. _# }+ g4 G - static uint8_t gyro_st_lsm6dsl_hz2odr(uint32_t hz)- n9 n* {7 m" t
- {/ y% z# t3 O$ v" b9 N6 A6 I
- if (hz > 3330)
- x& ]) U2 ?$ K3 m - return LSM6DSL_GYRO_ODR_6_66_KHZ;
. K' N' z! Z+ ~# E$ S3 V8 t) @ - else if (hz > 1660)
! ~2 x! T1 Y' r- ^% t2 |- w - return LSM6DSL_GYRO_ODR_3_33_KHZ;
( ?* x6 g, Z3 b/ s @ - else if (hz > 833)7 h0 v* w1 q5 ?5 H% }) ^
- return LSM6DSL_GYRO_ODR_1_66_KHZ;
& K7 D) P& X; J3 }: t) u - else if (hz > 416)
& m& B5 S& `" x- y& O" `* E - return LSM6DSL_GYRO_ODR_833_HZ;
0 J0 _+ ~) [4 p9 v2 R3 _* E - else if (hz > 208)! n7 m+ |8 _3 A9 ~4 ~
- return LSM6DSL_GYRO_ODR_416_HZ;% r2 B# a) o: g2 E+ _, n& X6 Z
- else if (hz > 104)0 [ f. ^. b9 G, d
- return LSM6DSL_GYRO_ODR_208_HZ;; a9 |" \' ~) ?3 K
- else if (hz > 52)
2 P5 L' \6 ?3 l - return LSM6DSL_GYRO_ODR_104_HZ;2 }5 v6 h; u* [
- else if (hz > 26)
6 Y" [( a2 u5 B - return LSM6DSL_GYRO_ODR_52_HZ;
* I1 A# G- X- O+ ?# ^. C: b - else if (hz > 13)& z" Q/ S+ m4 q& m- x0 {7 ?/ T9 N
- return LSM6DSL_GYRO_ODR_26_HZ;) w$ O& @2 b! q# X( V0 G
- else
3 G6 l5 C5 v3 Y1 J - return LSM6DSL_GYRO_ODR_12_5_HZ;
1 [4 E- L0 n; T E( J# [- {+ _ - }! h1 X- L: W* T0 s& b# ]+ N
-
( J% }: C) H* ?6 u! f% X( `0 ` H - uint8_t LSM6DSL_gyro_set_odr(uint32_t hz), C F( x1 @& L# l8 A
- {, F" n' l# Y4 p" d
- HAL_StatusTypeDef hi2c2_status = 0x00; r. j: M2 X/ ]7 T" |& w5 t
- /*first read*/1 F6 `) @( R7 d8 z. A3 x! H
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL2_G,0x00};
" c" V0 J' r _; A q - hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
/ T4 }/ Z) A# P% }* h4 w - if(HAL_OK!=hi2c2_status){5 f" Q+ ~, ~( @1 u7 H$ g7 \; K! S
- printf("get LSM6DSL gyro odr error\r\n");- }& u( Z1 c, D% J2 ~( r+ k3 B. R
- return 1;
5 O) ^# J3 ^- a/ T - }9 a! [7 _/ {. l6 @+ ~4 X7 H
- uint8_t odr = gyro_st_lsm6dsl_hz2odr(hz);
9 }9 j0 T9 Q8 z+ A3 u$ P# M) l - addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_GYRO_ODR, odr);
+ A8 t" D+ {4 W - hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);% }( ^1 x1 @$ }2 t6 \
- if(HAL_OK!=hi2c2_status){+ c/ G9 E/ S' K+ b* O
- printf("set LSM6DSL gyro odr error\r\n");5 {' h( J4 o' q9 `( k9 l
- return 1;
/ h0 D) T) `1 i# }: G4 E8 H8 _ - }
7 Z, d( k" z5 ]) P3 {5 F9 ` - printf("successfully LSM6DSL set gyro odr\r\n");- R( y+ k- S1 g" l4 j% \
- return 0;
3 ^, P9 i3 n1 g5 m' t - }* D+ w4 q' p) s& d0 ~3 U6 z
- 6 t" v$ u1 U5 E/ [( l
- uint8_t LSM6DSL_gyro_power_mode(LSM6DSL_power_mode mode)! P$ y2 p( l5 ^( J- ^* k
- {
! p4 V/ F2 ^5 S$ ` - HAL_StatusTypeDef hi2c2_status = 0x00;
5 L; O: r5 y: I# l* K/ f0 T - /*first read*/9 ]/ S2 M8 u. b( t0 K
- uint8_t addr_val[2] = {LSM6DSL_ACC_GYRO_CTRL2_G,0x00};! i N5 r2 [ w# ^8 y) l
- hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);3 o( u1 a4 r+ ^
- if(HAL_OK!=hi2c2_status){9 z+ P/ W$ Z# \6 J
- printf("get LSM6DSL gyro power_mode error\r\n");
3 G% j% g6 [- f3 C( v5 X* C6 N - return 1;+ n; R: b" S" ^
- }. }/ |4 {' U: P* a+ j
- switch (mode) {1 q3 o: x/ h8 d5 G) P" J7 J
- case DEV_POWER_ON: {$ Q/ S# T0 c4 ?; Y9 D
- addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_GYRO_ODR,LSM6DSL_GYRO_ODR_12_5_HZ);2 Z w+ l4 b4 M9 w; G5 o1 ?: f, n
- break;$ Z" z6 f/ B6 F; n/ J
- }, @+ K P' l- m0 E5 V. f/ f
- case DEV_POWER_OFF: {
2 ^8 a. y9 p( k1 H) O: u - addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_GYRO_ODR,LSM6DSL_GYRO_ODR_POWER_DOWN);
8 W" p% @5 F7 Q6 w. U - break;
5 [2 `0 E, {) V; v4 ^( ]1 D E - }! l6 a9 P& r$ u2 l" y4 E
- case DEV_SLEEP: {
) G0 s! M6 y3 R$ }2 S - addr_val[1] = LSM6DSL_SET_BITSLICE(addr_val[1], LSM6DSL_GYRO_ODR,LSM6DSL_GYRO_ODR_12_5_HZ); o$ Z( s2 N2 M. y7 `0 a# O1 v
- break;
9 [% L: I* s* N' E5 H - }
& C/ Z0 M6 z& }6 x/ c. R5 \& t - default:
6 A: U- p2 d' R( K1 I - break;) X% g8 ~9 Y8 m4 h
- }
8 @$ T# R/ W/ \' Z" r. P- L - hi2c2_status = HAL_I2C_Mem_Write(&hi2c4,LSM6DSL_I2C_ADDR,addr_val[0],1,&addr_val[1],1,1000);
) @1 r) X* L' l8 X - if(HAL_OK!=hi2c2_status){' W- b5 C! j! r* C5 o
- printf("set LSM6DSL gyro power_mode error\r\n");7 i: Q2 d& j/ G" p& O
- return 1;& L6 q# `( Y j$ X
- }( v* ^6 v8 S* W- H+ u8 [, f$ S
- printf("successfully LSM6DSL gyro power_mode\r\n");: L( I# R) x! m) S& Y6 r0 L
- return 0;: V3 \; R1 z0 O; A# H# {, H; h
- }* w* M$ E5 b! [1 k) |
-
5 Q m% v# w# `' Q# a# u - uint8_t LSM6DSL_gyro_st_open(void)
9 a( \) e4 z$ e4 Z0 I - {
5 [+ ~0 R7 Q1 Q( r+ ^ - uint8_t ret = 0;
1 c# R: I. t1 R, Q9 J - ret = LSM6DSL_gyro_power_mode(DEV_POWER_ON);% ~3 t4 v) [! c9 H: I
- if (ret>0) {
: l+ W, [; h$ q3 N' _( D7 ] - return 1; J; n) R, L. A$ e" e ]
- }
' F- u0 {! o4 z8 S2 H - ( d t8 B R7 z2 s
- ret = LSM6DSL_gyro_set_range(GYRO_RANGE_1000DPS);
9 k- |! W p0 s, R - if (ret>0) {6 k7 o8 n2 t- ~+ @9 C) b0 y1 c. [1 e
- return 1;. K+ V X! B) f4 e6 o7 r
- }. G! ?1 ]8 m5 }/ s- J4 o8 T
- # Z9 ~) p I" n1 N
- ret = LSM6DSL_gyro_set_odr(LSM6DSL_GYRO_DEFAULT_ODR_100HZ);
+ d7 F6 [9 L1 h& ~: w% A: c - if (ret>0) {" g+ y2 ]0 R2 ~) k
- return 1;3 k2 N/ p* {9 \' `& j! ^# d8 f/ {6 y
- }
3 B( k& }1 j. i, g* ] - printf("successfully LSM6DSL gyro open\r\n");) o# |- C! {4 R9 i! I/ r7 A1 k
- return 0;7 o5 C& I6 M+ t
- }0 s s- G9 v6 x9 v
- # l1 |! n6 h7 Q T ^. J: C
- uint8_t LSM6DSL_gyro_st_close(void)
/ `9 R7 r. `4 l - {
3 f( v' c2 U; j, V8 B4 [# T - uint8_t ret = 0; C1 t6 C. v% s
- ret = LSM6DSL_gyro_power_mode(DEV_POWER_OFF); j p" x) b0 K2 _5 B" o
- if (ret>0) {, Y4 o6 l3 ]& J, S1 y
- return 1;% P0 }5 t# q" G$ a7 B
- }) @) G. f' m1 g$ k) h# n
- printf("successfully LSM6DSL gyro close\r\n");; B/ P4 E i) _& u" v# n7 m
- return 0;. e- _: n& v g* I3 v2 v) }
- }9 G5 \4 N% [! F. U( N3 r# i
-
" H6 m F9 c' \ J - void LSM6DSL_init()
8 ]( h& q* r E- w1 ^1 X - {6 s/ S% T" z1 ^/ T
- if(LSM6DSL_ID_check()>0)
) \/ c7 l, @5 ~ - return;0 Z8 J/ S! o" O* x, [
- if(LSM6DSL_soft_reset()>0)
! I- D: a R% n! a - return;( m0 Y, a J9 n: p' d1 t. h* G
- if(LSM6DSL_acc_power_mode(DEV_POWER_OFF)>0)
4 f/ t. u7 P' p* c0 m - return;
[; G3 R3 w) G- F: J- \2 C- g - if(LSM6DSL_gyro_power_mode(DEV_POWER_OFF)>0)0 @0 W( `& B" g# Y. t
- return;& P* y$ d/ r* m$ A! T! R
- printf("successfully LSM6DSL init\r\n");
/ B" S* F- A% H- W1 C/ n - }* x/ F" R0 N6 o: S
-
% w5 R- C0 i! P7 r( ]: } - #define DATA_AXIS_X 0
1 n$ {) T5 v5 ?4 X. G+ ? - #define DATA_AXIS_Y 1
3 A+ T, Y& Q7 L2 U' P; s% i7 k0 n - #define DATA_AXIS_Z 2% ~6 w. Z3 M8 t j8 E" l ]0 f9 Q
- . f/ b% G3 m0 o% ^1 _: Y4 X, T
- uint8_t LSM6DSL_acc_read(int32_t *x_data,int32_t *y_data,int32_t *z_data)
) g# f: j8 r5 z) K - {
& A* ^3 C" ^, I/ d% x - HAL_StatusTypeDef hi2c2_status = 0x00;
6 I5 ?4 B$ R+ R" t; ^ - /*read 0X28,0X29,0X2A,0X2B,0X2C,0X2D*/
% c7 C% c' d, g& Y8 |7 D - uint8_t addr[6] = {LSM6DSL_ACC_GYRO_OUTX_L_XL,LSM6DSL_ACC_GYRO_OUTX_H_XL,
g: C/ h1 |8 ? - LSM6DSL_ACC_GYRO_OUTY_L_XL,LSM6DSL_ACC_GYRO_OUTY_H_XL,
6 f% x Z& j% n8 A% D! h! | - LSM6DSL_ACC_GYRO_OUTZ_L_XL,LSM6DSL_ACC_GYRO_OUTZ_H_XL};# Q) e- E$ ?1 { ?6 t2 D
- uint8_t val[6] = {0};
$ b. Y: S; e6 }/ H( @ - for(uint8_t i=0; i<6; i++){' n9 {# B2 O/ ~2 e& W5 E! g8 o% t: g3 ~
- hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr[i],1,&val[i],1,1000);8 ^. I0 {' Y! _5 t& y1 k( `
- if(HAL_OK!=hi2c2_status){
$ H4 ^6 w" G: \5 ~ - printf("get LSM6DSL acc_read[0X%02X] error\r\n",addr[i]);
% O4 [6 ^# C& ?. G- t4 l - return 1;
& L3 v. s5 r: o" x0 T" C# j/ W - }
9 D- D; w: m5 J4 |5 Z5 z v - }
4 k8 ~2 T6 L$ W - // printf("read acc reg_data 1:%02X, 2:%02X, 3:%02X, 4:%02X, 5:%02X ,6:%02X\r\n"- |. `3 g( ^" N" d9 u# d; k, a* n$ v
- // ,val[0],val[1],val[2],val[3],val[4],val[5]);
5 R1 w& ] J5 w - int32_t data[3] = {0};! f8 v( h+ Q1 G' n6 `2 o5 V1 \
- data[DATA_AXIS_X] = (int16_t)((((int16_t)((int8_t)val[1])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[0]));- C* U& V, t5 V! K/ C4 j% _2 `! f
- data[DATA_AXIS_Y] = (int16_t)((((int16_t)((int8_t)val[3])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[2]));
+ r8 c5 _& G; a( f4 Z - data[DATA_AXIS_Z] = (int16_t)((((int16_t)((int8_t)val[5])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[4]));
2 K4 g3 x: Y7 I9 y @0 c - if (cur_acc_factor != 0)1 a) ~1 P0 f3 p0 W
- {& Y- y" n0 A* H$ P( D4 M2 W( \" H6 e% q
- data[DATA_AXIS_X] = (data[DATA_AXIS_X] * cur_acc_factor) / LSM6DSL_ACC_MUL;
; e# l2 o; j8 i( k- ]" y7 I1 G - data[DATA_AXIS_Y] = (data[DATA_AXIS_Y] * cur_acc_factor) / LSM6DSL_ACC_MUL;
$ C0 h1 X+ ^" H/ G$ J - data[DATA_AXIS_Z] = (data[DATA_AXIS_Z] * cur_acc_factor) / LSM6DSL_ACC_MUL;0 D' j3 v6 P4 l, A
- }
4 n7 K+ D7 Y8 j' @2 ^ - // printf("read acc cur_acc_factor:%ld, X:%ld,Y:%ld,Z:%ld\r\n"
6 U9 R: u/ J, k8 y - // ,cur_acc_factor,data[0],data[1],data[2]);
5 A5 {$ {/ E6 |3 b1 J O& E7 E - *x_data = data[DATA_AXIS_X];' \8 L" i" t- v' R7 G2 e/ J- p
- *y_data = data[DATA_AXIS_Y];
6 m, T- o4 \6 {6 o* K" ]( Y) Y' k - *z_data = data[DATA_AXIS_Z];
, U1 i3 H+ d% e - return 0;
. K) O* ?5 a0 d( b7 B9 ? - }: r- c( L$ t0 R9 v
-
' Y" `1 G" _. u) g# z - uint8_t LSM6DSL_gyro_read(int32_t *x_data,int32_t *y_data,int32_t *z_data)
6 e7 U; f- r1 D8 q- f5 K; R - {
+ Z+ R) d. i, _) L - HAL_StatusTypeDef hi2c2_status = 0x00;2 A! `3 Z3 h1 f, C, T
- /*read 0X22,0X23,0X24,0X25,0X26,0X27*/$ B. `* [( @: V8 ?+ p2 w
- uint8_t addr[6] = {LSM6DSL_ACC_GYRO_OUTX_L_G,LSM6DSL_ACC_GYRO_OUTX_H_G,! w( n% `/ k% ?' o7 t$ n/ H; s
- LSM6DSL_ACC_GYRO_OUTY_L_G,LSM6DSL_ACC_GYRO_OUTY_H_G,
. e" O( x3 p9 T2 B - LSM6DSL_ACC_GYRO_OUTZ_L_G,LSM6DSL_ACC_GYRO_OUTZ_H_G};
3 |; l8 v) p. `2 u - uint8_t val[6] = {0};
9 ^7 i- ]4 X& H& f2 g - for(uint8_t i=0; i<6; i++){
+ ?$ P; t) K+ O! h( s; d3 M. J( s - hi2c2_status = HAL_I2C_Mem_Read(&hi2c4,LSM6DSL_I2C_ADDR,addr[i],1,&val[i],1,1000);7 W3 c6 ^8 m+ V, c5 o+ A
- if(HAL_OK!=hi2c2_status){
0 }2 m1 ^' S- L - printf("get LSM6DSL gyro_read[0X%02X] error\r\n",addr[i]);
! ~ V! r7 n2 J - return 1;
5 F- T: B2 Z4 ^4 Z - }
J i) G4 w( r- e" q1 { - }
3 T; k3 U- N. a - // printf("read gyro reg_data 1:%02X, 2:%02X, 3:%02X, 4:%02X, 5:%02X ,6:%02X\r\n"' I( s/ L% K/ w$ I+ _- a
- // ,val[0],val[1],val[2],val[3],val[4],val[5]);: T7 W% O- I1 ]( u6 ]
- int32_t data[3] = {0};
: g" Q/ z7 X( k0 b' P, n - data[DATA_AXIS_X] = (int16_t)((((int32_t)((int8_t)val[1])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[0]));
_/ e( G* D; J- g" C* G - data[DATA_AXIS_Y] = (int16_t)((((int32_t)((int8_t)val[3])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[2]));% a3 b& d, L+ Z& [
- data[DATA_AXIS_Z] = (int16_t)((((int32_t)((int8_t)val[5])) << LSM6DSL_SHIFT_EIGHT_BITS) | (val[4]));5 U% J& ?2 _# d g% X0 o
-
" v# r3 W! t2 {% q - if (cur_gyro_factor != 0) {; `# p z& a" ]0 j, G' o
- data[DATA_AXIS_X] = (data[DATA_AXIS_X] * cur_gyro_factor) / LSM6DSL_GYRO_MUL;9 r% C9 N2 n7 @
- data[DATA_AXIS_Y] = (data[DATA_AXIS_Y] * cur_gyro_factor) / LSM6DSL_GYRO_MUL;1 O$ S r% Q }1 y4 v- H* F, ^+ X
- data[DATA_AXIS_Z] = (data[DATA_AXIS_Z] * cur_gyro_factor) / LSM6DSL_GYRO_MUL;
5 a x+ L) W f0 i L( d - }& D0 p/ x+ o5 O: T& P2 _6 B0 N& N
- // printf("read gyro cur_gyro_factor:%ld, X:%ld,Y:%ld,Z:%ld\r\n") _. r+ |& L6 v7 }- A2 H w* G
- // ,cur_gyro_factor,data[0],data[1],data[2]);+ r0 J' e1 A$ n7 Q; }+ `. n9 t
- *x_data = data[DATA_AXIS_X];
# J2 P$ M$ q) M - *y_data = data[DATA_AXIS_Y];0 Q H4 ~8 N. U) m& i& |4 C! p1 s6 O
- *z_data = data[DATA_AXIS_Z];- s2 o* A5 C E# {/ K! f( X) D
- return 0;
/ a* F* Z1 [5 K0 [9 ?# r. V - }
复制代码
; H4 c2 G/ c7 f4 t9 v2.3 传感器数据采集与输出源码设计2 \0 c5 s9 S6 S5 @5 h6 [% N
在main.c文件中,添加各个外设驱动头文件支持
$ ?9 J+ i T: F. |- /* Private includes ----------------------------------------------------------*/
& C, ~% p+ f. W4 g, _ - /* USER CODE BEGIN Includes */% h3 B2 H9 V. j( y7 n: ?* F6 q
- #include "../../ICore/key/key.h"
8 t1 m9 J+ v4 x7 D ], s3 @/ [6 o - #include "../../ICore/led/led.h"
5 |; P5 R# W% Z2 E5 M - #include "../../ICore/print/print.h"
! m- F; I1 t( S2 Q/ {# m, O, I* V - #include "../../ICore/usart/usart.h". A) G% n- I9 T7 H
- #include "../../ICore/LSM6DSL/LSM6DSL.h"7 r/ j* H* Q4 c# Q# n. a! M3 d
- /* USER CODE END Includes */
复制代码 7 T( b' x. V& Y
打印实时采集的三轴加速度信息2 d) R% i$ R: M( d/ k+ I+ H5 c5 a
- /* Private user code ---------------------------------------------------------*/( k- f0 w5 o" l+ n& \: ^
- /* USER CODE BEGIN 0 *// g# l! T9 ^7 I/ p" D M
- void out_print(int32_t acc_x, int32_t acc_y, int32_t acc_z)
8 `* U; V# f( I) v$ z2 d( r3 m0 g - {
# w! J; s" v6 y# }6 ~+ d/ [ - if(acc_x>0)+ C2 ?! K6 w5 e- L L, A7 d4 \! N
- printf("%d.%d, ",(acc_x*98)/10000,((acc_x*98)%10000)/100);6 e2 w( M0 N( ~ q9 I, T
- else
& k0 n L: b7 v+ `! [: x { - printf("%d.%d, ",(acc_x*98)/10000,((-acc_x*98)%10000)/100);" q% K1 V8 b+ G& n* K
- if(acc_y>0)
, T- j& L2 v% Y+ L* d7 Z( v - printf("%d.%d, ",(acc_y*98)/10000,((acc_y*98)%10000)/100);
) h: D$ K7 P$ _* Q- r6 O: _ - else; z8 H, b" y! {2 b
- printf("%d.%d, ",(acc_y*98)/10000,((-acc_y*98)%10000)/100);: `, ?6 X7 V. ]
- if(acc_z>0)! b; M8 m& N y" ?
- printf("%d.%d, ",(acc_z*98)/10000,((acc_z*98)%10000)/100);* ~4 r& F; ]- p' }# Z0 O2 k" _- X
- else4 T$ _( e+ U! {6 d+ ?
- printf("%d.%d, ",(acc_z*98)/10000,((-acc_z*98)%10000)/100);& h" o5 d1 n7 U7 V% \; N. M- Z( \
- }$ e" d" Q1 y Y1 ~% p
- /* USER CODE END 0 */
复制代码
- @' C7 G7 o7 l& }% @, G: H 在main函数中,初始化各个外设
+ g+ R" J b: r- int main(void); W' K4 c/ h, V% r ?
- {
* }- H$ J! l# N( K, N7 Q& g - /* USER CODE BEGIN 1 */
" ?- f, z9 G: F% n3 r6 b - int32_t acc_x,acc_y,acc_z;
+ u; \2 K% X8 }) r/ l$ S - /* USER CODE END 1 */+ M( F# x9 X- l; j% j& I) }
-
) @" ?6 k/ X! U( z* e. u - /* MCU Configuration--------------------------------------------------------*/
5 m* c3 Y A1 D - ) J( Z! c' Z. N8 b, D$ A
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
( K& N1 p' r$ c - HAL_Init();
; M8 U% o, _; p- K) f6 } - 9 A4 l( U" G% B& l; r' q
- /* USER CODE BEGIN Init */
: }( e8 ] i( F0 U6 K5 g e -
/ }# v+ @! D7 f$ m7 C$ m( w - /* USER CODE END Init */
7 o" }. ]' L6 S; \ - 6 [- m I: o8 U6 d* b% `, C, `3 f* ?
- /* Configure the system clock */0 H. h" h# q; C) y1 ]% v
- SystemClock_Config();
7 `+ H7 B+ ~0 s+ @ - R( U" ^; B" X" \& Y
- /* USER CODE BEGIN SysInit */
5 ^8 h; Z& G0 }2 r$ K0 X! `8 t( ] - . @1 |/ v: ]5 D+ i9 r1 n
- /* USER CODE END SysInit */" }* U3 T/ E. A& b( n
-
' A$ D+ X9 L: y/ T6 v - /* Initialize all configured peripherals */( d5 Y* L( b. Q; E) [# M
- MX_GPIO_Init();3 i! z9 P+ A: G3 f7 {
- MX_DMA_Init();
" C: p4 k8 `- j2 V, e) j9 T - MX_I2C4_Init();4 `4 ]9 E8 R# W( ]) O) _$ |& c, }% O
- MX_LPUART1_UART_Init();5 Y8 s3 U# w" V# E6 P% K0 ]4 W
- /* USER CODE BEGIN 2 */
" ]4 p8 k$ q" @( A5 B6 r - ResetPrintInit(&hlpuart1);. b$ d: |5 t7 }2 x% K, ]
- HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断8 w0 N9 N% d( ^+ a; A8 g: Y
- HLPUSART_RX_STA = 0;6 X0 |' U, C& A+ `. t
- //LSM6DSL+ y$ @0 O* ]. J! U) w- G
- LSM6DSL_init();
" I3 I# [' _- w& D& Q5 \ - LSM6DSL_acc_st_open();4 G) {+ F+ g! E- L. ?; W% r
- acc_x = acc_y = acc_z = 0;
2 Z k, v4 b: _3 T! C3 V0 P7 W. ? - uint8_t menu = 0;3 i5 a, p- e* U) h
- uint8_t step_size = 3;
. S* j, L) I4 o" Z/ [: s- ] - /* USER CODE END 2 */
复制代码
( }& p# s+ E$ V* K! d$ ?% M 在main函数循环体内,实现根据按键采集传感器数据(开发板正面朝上):3 Z0 a' m/ `! ^7 Y/ G
1)保持开发板在桌面不动,按键KEY0按下时,采集静止不动姿态时的三轴加速度,并每采集三次,输出一次姿态结果[1,0,0],再次按下KEY0时停止采集
1 e( `, `2 }" M9 k: q; r! e 2)保持开发板在桌面左右移动,按键KEY1按下时,采集左右移动姿态时的三轴加速度,并每采集三次,输出一次姿态结果[0,1,0],再次按下KEY1时停止采集
7 j" A; S) E& L4 c1 }5 o* z3 ? 3)保持开发板在桌面上上下移动(垂直方向),按键KEY2按下时,采集左右移动姿态时的三轴加速度,并每采集三次,输出一次姿态结果[0,0,1],再次按下KEY2时停止采集
) T& t8 k- y# j! T3 u! `) X+ H) J- `8 L- A# B3 o$ n; T
- /* USER CODE BEGIN WHILE */
6 Q- y. x8 S1 E k ~, R - while (1)
. W4 I' o! j O* P - {
. U. X# f8 U( k# I4 j8 g - if(HLPUSART_RX_STA&0xC000){//溢出或换行,重新开始. ?, y( x7 Z8 `2 ~, u5 `( d
- printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);5 p: ~7 ^8 }% q7 O( i/ v# s3 F
- HLPUSART_RX_STA=0;//接收错误,重新开始
" Y( j b. Z% o* Q - HAL_Delay(100);//等待" Z# G% j; N( i7 u+ [
- }0 u* ^) u$ e( O- r1 r/ J
- if(KEY_0())! W8 b1 b: j! {* ^
- {) F1 w8 m2 r# D$ M
- if(menu&0x01)
: |' T( c6 ^9 ]" N: p) S5 k8 o - menu &= 0XFE; //取消静止不动数据刷新
- y5 r5 j/ _6 t! Z* T& ~. r& I - else{
) t, E% i% G0 L5 h - menu |= 0X01; //开启静止不动数据刷新
0 J9 Z& G# M! V! i7 [; ]4 w - }
' z! U* i, A' r7 K; c2 O8 s" z. z - menu &= 0XF9; //取消其他数据刷新5 A7 y7 F3 ?" T1 S7 p( F, _" w8 m
- }
! ]5 O# F7 ]% B - if(KEY_1())
7 o u# S* a7 q( p9 B - {
- A6 B, L7 S' ~" ^) o/ p, H - if(menu&0x02)
% o2 q; s- {0 i - menu &= 0XFD; //取消左右移动数据刷新
* o$ h' w; o# _: R9 C5 @ A - else{% b# @( V q* l- d- M. P
- menu |= 0X02; //开启左右移动数据刷新* X2 p/ S$ B0 M S, L9 o+ m
- }5 W# }/ q: @, h2 t2 g E
- menu &= 0XFA; //取消其他数据刷新7 q$ N- T# _7 m `2 m$ C4 P& r
-
0 s& @' W. ~4 g/ f - }
- m, R- M# [, t& Y4 ` - if(KEY_2())
1 v' [! e( j' B! g" v& R - {
- U" a0 u+ p3 p. e3 C - if(menu&0x04)
, [& v& m. y+ r# M/ a* Z1 x - menu &= 0XFB; //取消上下移动数据刷新
! R0 \ o# r1 E+ v! u7 j6 z5 ^ - else{
4 z0 b5 R3 U' w3 \ - menu |= 0X04; //开启上下移动数据刷新
6 B( J# D2 Z N9 E - }
( V* L( G8 W* E. V5 j1 O3 T- u% j - menu &= 0XFC; //取消其他数据刷新
/ k* w6 i6 z$ p4 }, i -
' }- Q3 P6 T3 G% h7 n$ i7 {5 ` - }
2 o+ R1 G7 V3 y) { - if(menu&0x01)//静止不动( X8 Y6 g# z$ W0 Y8 e
- {
( F3 }3 x( c! D: J) J, G3 x# z - for(uint8_t i =0; i<step_size;i++){1 g$ G( o' R" p5 E
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);
, a8 d0 y, A) M1 j3 W- ~ - out_print(acc_x,acc_y,acc_z);5 t# ~: C- b0 l( `3 m
- HAL_Delay(100);//等待0 j" }1 W) ?0 B7 F% E
- }% H$ k9 a6 O; @, P4 T- w9 s
- printf("1, 0, 0\r\n");, J7 M2 e# A( i9 \( n- l5 I
- Toggle_led0();
0 m/ p1 J! y, b- r - }
; ? e; n3 C( X+ j2 p& }1 Z - if(menu&0x02)//左右移动; W/ i- h/ W9 ?* i8 {
- {2 s- Z4 s2 N) S% f, F- H2 T
- for(uint8_t i =0; i<step_size;i++){6 V) W6 q% I" r1 C/ V4 C2 |
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);& ~+ g0 C- E1 l1 ]
- out_print(acc_x,acc_y,acc_z);' G2 N! z; G& b- s! T- a
- HAL_Delay(100);//等待- ]6 Y4 e4 L% d% ?4 d0 u
- }
5 E7 j! [# }% e - printf("0, 1, 0\r\n");9 W, ^. s4 o+ T3 [
- Toggle_led1();
% X) w# X5 n. H! E) b/ b( `2 u - }/ F+ M* V7 y% N; }8 a, ~
- if(menu&0x04)//上下移动
# z6 E. J. ]8 p' Z+ O, y - {- g- i. M- Z. L& A! w2 o( `1 j
- for(uint8_t i =0; i<step_size;i++){7 _/ Q2 Y' F6 o1 l. @6 | }
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);, C/ L( B8 D+ e: B
- out_print(acc_x,acc_y,acc_z);
+ ?3 X' U+ e6 M* ^+ Q. h0 \7 ? - HAL_Delay(100);//等待
3 J/ l3 ~* Z4 |1 W3 E% N7 C* z - }
- U4 G+ K- U1 v! B4 Q" V, [; v7 R: k - printf("0, 0, 1\r\n");6 r) q: [2 t+ P$ Z
- Toggle_led2();" S+ r3 s& E3 S0 o! l
- }
7 G6 ]% M) a2 p; P5 Z" s - /* USER CODE END WHILE */
复制代码 2 l6 Y, J a' ]. m' l5 B2 q
2.4 编辑下载程序,采集数据
! ~1 o [, e* y' q/ m3 j# l. O 编译程序及加载到开发板
- d0 a1 ]0 H x# _* Z. n1 F5 t) n7 O }2 j
. m# V* n* L; z% f
8 u) f2 G J H! C" h( {) z+ A
打开串口助手,连接开发板,先清空屏幕,然后按上述功能操作进行数据采集,每种姿态采集大概一分钟的数据,完成后保存数据。
$ N: d4 |" P3 R+ M
3 ?8 q# ]# w9 d7 G% [6 N1 G
+ {0 D! z& x4 p; J+ h/ x
6 u, m/ {# e1 R3 t* k0 @' L t
创建目录My_HAR_Study,将保存的txt文件拷贝到该目录,并将该文件修改为.csv后缀
: ` E7 P( i4 E& P$ Y3 W6 m
% v, W# w& @9 J8 x* I, n6 W
5 n2 ~0 g, l& e
8 i+ @0 A( F+ b8 s x, y2 }1 [ 三、模型训练
% B% h) q1 @4 Z2 D+ Z. b, v4 f! E" _, F$ Y 在该目录下,创建myrun.py文件,内容如下: q5 N* U( D+ b: E
- #模型训练文件 myrun.py 训练 epochs 1000次3 |7 q: e3 ?4 L
- # myrun.py6 V {: q- K6 l% |7 S
- '''
, R7 V7 m( z) J: d, e - 开发板(正面朝上)姿态检测5 [/ B8 l* e/ P* T* i0 j- a: s
- 静止不动、左右移动、上下移动
- T: @' m3 j. O) Z, @" `/ ] - # h) r' m1 d$ @8 ?6 [ d# ?
- 输入层 -> 隐藏层 -> 输出层
( e$ ~+ D6 ?: } - '''
6 x* r# Q. u7 Z' [5 s' n; b - , a. j: ?, L' H0 r& F6 L; o8 o) A
- # 导入工具包8 g' s$ @/ L( A2 o
- import pandas as pd
0 }# [6 F! X- q5 P+ @. B0 N# Y6 Q - import numpy as np
" F% t/ ?% t! B9 { - from keras.models import Sequential
9 E# k, J: @8 L% V1 H, |8 ~3 G! N - from keras.layers import Dense, Dropout& a- p; }7 R1 S
- from keras.optimizers import SGD+ I5 u. {; b- V" Q
- 5 x/ m& Q" a) y1 [
- # %% 读取数据; `; [, S n* v3 m9 }" x
- data = pd.read_csv('SaveWindows2023_1_28_16-31-14.csv', sep=',', header=None)" x& g4 H2 e: T" I! ~0 z7 F# h
- data_x = data.loc[:, 0:8] # 取1~9列所有数据
2 [/ H' b$ a ]6 p+ W1 ?( ? - data_y = data.loc[:, 9:11]
}: P/ \) H! u' o0 [/ j - data_y.astype(int) X0 v, {* Y* c" ^ e7 T
- #
/ A' R/ h, r. i" X2 d; N9 E' | - print("-x-")
9 r8 x( w3 `' Y) Y - print(data_x[0:2])
( j+ P& f4 ?4 [! C - print("-y-")( N( x) Q- ~" L2 C
- print(data_y[0:2])
. b# v& O: G, c8 M: H8 s3 y; Z7 o - ) b: Y8 ~7 t2 n3 ^
- # %% 建立模型; A) C/ v3 L5 H7 X7 o
- model = Sequential()
$ L; r2 x; Y' X/ `! L) g( a - # Dense(64) 是一个具有 64 个隐藏神经元的全连接层。
7 p4 E) s( C z - # 在第一层必须指定所期望的输入数据尺寸:$ O& I' X" G) Q) P z, B9 T
- # 在这里,是一个 9 维的向量。7 p& Z& R- |. B( ~
- model.add(Dense(64, activation='relu', input_dim=9)) p* w8 M) Y* A7 \/ W _9 g% a* f
- model.add(Dense(32, activation='relu'))
- |: W9 p% ?3 r J2 N - model.add(Dense(3, activation='softmax'))
S6 \8 `6 p0 V/ Z( y -
' o7 y3 ?$ s. Z2 z4 Z4 i' j" d - sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
- F( _' u8 F( z, x6 ?- z - model.compile(loss='categorical_crossentropy',$ W) h; ^7 T7 M' `
- optimizer=sgd,, D8 V3 ?4 ~% `% w6 M: g6 [
- metrics=['accuracy'])
' t' _1 n0 L* P - # q( g% R m F
- model.fit(data_x, data_y,6 z" U8 ]2 h; p0 U
- epochs=1000,- ]/ ?+ A3 ^' G% o4 Y
- batch_size=72)
% c# f' t! R- m: @" ?/ j( w - score = model.evaluate(data_x, data_y, batch_size=72)
# f! _7 W. B/ ?- k; \ -
, H/ f( }% U; M0 l - # 保存模型8 Z* L# E1 e2 I! K
- model.save('myhar.h5')
复制代码
0 U; @& G5 A# T' Z' T 当前目录启动命令行工具,运行python3 .\myrun.py命令,1 c9 E8 v4 N+ g0 Q8 L9 h
w" F0 v- Y% M$ f" p) L
; y5 y( |% V$ j, Q# W
5 q5 u4 Q. q) |0 w
6 S8 m+ l$ X9 w9 \
4 x1 t6 V" H8 o' G& X
四、cube.AI配置及c模型生成
' H7 v% w9 _4 l: F# o8 r 回到数据采集工程(stm32L496VGT6_AI),双击.ioc打开cubeMX配置页面。
' r, M: p' F, g/ K1 S( G8 b2 L& E
9 z, o$ I1 U. l% T7 a( b6 i+ U. x8 l# s" U, u9 O3 F J
添加my_har模型,选择刚刚生成的keras模型文件(.h5),注意值生成模型,不需要应用程序。
4 I/ C* D3 ?5 z8 K1 J3 ~, b% a+ F% i' L) j) J0 d/ @
$ U- [ l1 ^$ w
4 `3 O% {+ w; }9 n 分析结果显示,模型精度很差,意料之中,毕竟神经网络层只进行了简单设计,实现不了那么复杂姿态识别,但验证模型没有错误,支持转换,可以用来演示完开发流程就OK。
3 V+ P' Q: O1 e' O$ e& _; h+ `) D2 {4 ~
% Y3 G( v/ o8 Y! f
2 G z8 T, I1 K8 J1 d 根据分析稍微调整一下heap和stack大小
/ k% o2 H8 O+ E6 i u- M' l! V. `) e: I$ d2 b6 o O4 Q5 c
+ K0 X3 T5 K2 \- O& y% ]# r% I
+ Q) U% p2 s: g1 U
生成输出代码如下图所示。' u" |# N" Z4 h/ \" n7 W
% h6 q, I( V- C3 V4 ]
; L- O2 u t5 V% S. G7 Y
' B9 t, I. D5 b, y, N
2 D+ G. B; y' h2 @& p4 p. C" w: V" \五、模型调用及测试& d4 [' U$ Q/ B
在项目属性设置页面,开启float支持: Q+ _7 Z% S% S5 ]# b+ N
% f2 F0 [$ s) y6 n$ q6 G+ e. s: H
6 ^. h8 e1 q7 C
1 I: |/ f5 p& U0 G% F 在main.c源文件中,添加AI模型库的头文件
+ c! j+ A) Z7 V/ n; ?- v# B8 h- /* Private includes ----------------------------------------------------------*/
/ j7 S9 }4 j8 Y. `$ W* E - /* USER CODE BEGIN Includes */; @* J" v4 K1 O) M, W' o, Q' T/ N
- #include <stdlib.h>' y1 a! V0 K2 f2 N- R8 X
- #include "../../ICore/key/key.h"
@; T" F/ T- _* M0 r4 Y1 Y - #include "../../ICore/led/led.h"- [% E3 I. u' d" c3 V
- #include "../../ICore/print/print.h"; w+ v" p2 m+ I S& c' u. D9 b$ g2 b
- #include "../../ICore/usart/usart.h"" V+ C* F& I+ t; N+ o3 z. m
- #include "../../ICore/LSM6DSL/LSM6DSL.h"" J" x4 b0 Y1 n. r# ?
- #include "../../X-CUBE-AI/app/my_har.h"9 T v# e4 D' e1 x& A6 r" B+ k
- #include "../../X-CUBE-AI/app/my_har_data.h", s9 _. d) ^, ~0 y
- /* USER CODE END Includes */
复制代码
: O% Z$ `4 ^2 }! w4 ]1 q5 n, ` I 在main.c源文件中,添加AI模型库支持函数 `$ m" z, T. `' r0 \. j% u
- /* Private user code ---------------------------------------------------------*/! H' a: r6 s' q
- /* USER CODE BEGIN 0 */! e8 O+ q! {8 @' X
- void out_print(int32_t acc_x, int32_t acc_y, int32_t acc_z)% H. U: c" n$ ]9 ^. W3 u( i
- {
; I7 e% l6 b; v$ f }& U - if(acc_x>0)2 L8 R& h @/ c" |# j: v; F3 H/ q: M
- printf("%d.%d, ",(acc_x*98)/10000,((acc_x*98)%10000)/100);
E8 Y- K: o3 J4 ~/ X4 N - else/ ]! w5 p+ j1 m9 o9 T
- printf("%d.%d, ",(acc_x*98)/10000,((-acc_x*98)%10000)/100);* I5 P/ c& ~: o# m
- if(acc_y>0): }' g: ~( a, Z. Z
- printf("%d.%d, ",(acc_y*98)/10000,((acc_y*98)%10000)/100); r4 B) w5 E7 k
- else8 I* f- F- F" @- a: {7 S* g' h
- printf("%d.%d, ",(acc_y*98)/10000,((-acc_y*98)%10000)/100);6 r& @3 \* O, T3 D$ E
- if(acc_z>0)" Y9 O$ V* h2 p( e3 z o- t2 e
- printf("%d.%d, ",(acc_z*98)/10000,((acc_z*98)%10000)/100);
* ^3 x, P2 D# q) L. ] - else" b. F; X2 z" g' e% m* T
- printf("%d.%d, ",(acc_z*98)/10000,((-acc_z*98)%10000)/100);1 h# d6 _7 j0 U# y0 n. A
- }1 B! Q5 |! E5 N% j
- ! t" |& n8 q' {8 j9 ?8 g/ O
- /* Global handle to reference the instantiated C-model */* n: U, D' ~! m/ d' E% c2 C
- static ai_handle network = AI_HANDLE_NULL;
4 V( H5 K" P( Z* Q) Z - 4 q1 T" R7 P, Z* f
- /* Global c-array to handle the activations buffer */) [6 m6 f" ^' J" Z' ]- l
- AI_ALIGNED(32)
/ r1 l( |. `/ M+ z3 I) n - static ai_u8 activations[AI_MY_HAR_DATA_ACTIVATIONS_SIZE];9 o" O1 d# G/ A" y: I* A
- & n1 _) @' G$ ~0 P6 w) |. M% U5 b
- AI_ALIGNED(32)) B* }6 p1 I4 t
- static ai_float in_data[AI_MY_HAR_IN_1_SIZE];
3 m9 v' c5 p/ D -
6 C3 I5 ?2 V" w+ c. `2 k- b3 I - AI_ALIGNED(32)
& k% D; x: E# G: J1 ~+ O - static ai_float out_data[AI_MY_HAR_OUT_1_SIZE];
2 Q2 U& b' Q( W - ( P& `- b) z6 h
- /* Array of pointer to manage the model's input/output tensors */- O% R( c; u0 K$ D
- static ai_buffer *ai_input;# e. X! i1 J& b ?, H k
- static ai_buffer *ai_output;
& H1 X9 d! X! q% _5 P7 Y- f6 } - static ai_buffer_format fmt_input;3 T1 ^+ Q% Q8 `3 p4 \3 g2 ?. r P
- static ai_buffer_format fmt_output;
+ ?$ _1 L7 U7 k) v7 A -
x8 p9 a" f) M/ q! ]$ | - #define NSIZE 3
" X0 N. E/ r! i: y4 a -
7 b9 G u ?) d" O - void buf_print(void)
( O4 G6 a; I- l( ~! M5 [ r - {, l* D' \& z1 ] q, p( m i
- printf("in_data:");" \& g; {$ w' K: E
- for (int i=0; i<AI_MY_HAR_IN_1_SIZE; i++)
9 K& j& c; {7 n* F - {
8 O6 Y5 G( W6 [; a8 x# e+ P - printf("%.2f ",((ai_float*)in_data)[i]);! x/ T2 J7 L9 e- g) i8 \, r
- }
! r+ H3 g: w6 N0 \0 q! R* ? - printf("\n");
& Q6 h& M! d5 W" H4 K - printf("out_data:");
2 ?$ |/ f# F0 t! {* c* C* m - for (int i=0; i<AI_MY_HAR_OUT_1_SIZE; i++)
5 s1 a, ~' e4 |0 q6 R - {
Z- F( C3 P- G2 T - printf("%.2f ",((ai_float*)out_data)[i]);" {* y5 @! w5 j$ z# m8 x2 O
- }
! d+ _7 V3 z$ i4 `1 J - printf("\n");
7 }" M% r$ d* v; ]* m - }2 b+ d- f, ^/ J6 \2 H# c: w1 l/ `
- * V8 v) j6 s2 Z# i. j/ d1 o3 J& u
- void aiPrintBufInfo(const ai_buffer *buffer)1 I: d0 r/ P' k& `- A
- {% D+ n& a. G' I w }* }7 z$ g: h
- printf("(%lu, %lu, %lu, %lu)", AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_BATCH),
& t. `% U/ a$ V% e! s; C - AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_HEIGHT), _: b! M1 l. } Y! T( j: M0 l! S# p
- AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_WIDTH),
1 F/ a& V D( s9 u8 x' `/ G* H5 r8 R# X - AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_CHANNEL));
4 X1 R) X5 n4 l, d% ?- [ - printf(" buffer_size:%d ", (int)AI_BUFFER_SIZE(buffer));+ |, X: B8 \9 Z. ?
- }7 r, K( o, b6 G" G* g1 _
-
* N/ B4 q# t [3 ]- X: v - void aiPrintDataType(const ai_buffer_format fmt)
0 c* F7 t3 a- m8 `" i7 { - {) ?4 L Z; H$ p0 `( a
- if (AI_BUFFER_FMT_GET_TYPE(fmt) == AI_BUFFER_FMT_TYPE_FLOAT)
3 U! A6 ]$ l) V! c) l& l- h - printf("float%d ", (int)AI_BUFFER_FMT_GET_BITS(fmt));$ g" ~" V, ~9 k0 `# ^
- else if (AI_BUFFER_FMT_GET_TYPE(fmt) == AI_BUFFER_FMT_TYPE_BOOL) {8 U+ ]1 h) d3 N$ U- d
- printf("bool%d ", (int)AI_BUFFER_FMT_GET_BITS(fmt));: Q! y5 A4 V# m! k& D
- } else { /* integer type */$ x$ b/ |3 D( Z8 ]
- printf("%s%d ", AI_BUFFER_FMT_GET_SIGN(fmt)?"i":"u",
9 z: C1 `$ _9 o; F - (int)AI_BUFFER_FMT_GET_BITS(fmt));/ S1 k) E9 B9 T' t0 _
- }
! R1 [- ]3 u; E1 j - }
5 r0 h0 T/ z- m6 v% C -
& u: t0 W$ ^. i8 L* H( j( O/ a' K - void aiPrintDataInfo(const ai_buffer *buffer,const ai_buffer_format fmt)& U. N* P$ U# {2 e/ ]* u
- {
% E( v j: U, X - if (buffer->data)9 {$ ~ W; z0 m1 h* d0 V8 {. f5 G
- printf(" @0x%X/%d \n",3 ~5 c+ {% `' l6 j( b: C" Q$ K' I
- (int)buffer->data,, E5 l+ F! U- |. U; O _! B6 G. v$ n
- (int)AI_BUFFER_BYTE_SIZE(AI_BUFFER_SIZE(buffer), fmt)) N! h1 \7 z: {: @
- );- c0 x+ t, ^: g1 \
- else/ D# P; A8 i( f5 Q# V" N) }' L
- printf(" (User Domain)/%d \n",
; }& r7 Y' ~% I7 m5 T S9 \5 d - (int)AI_BUFFER_BYTE_SIZE(AI_BUFFER_SIZE(buffer), fmt)
- w( j* ?+ b- Y) p* ^ - );" G. ?! m( @+ w6 v( C
- }
2 U% K" ?. ]- U( g- }/ {2 o - 2 l( G9 f$ N" o& d. h* \* B. B! U) a
- void aiPrintNetworkInfo(const ai_network_report report)
5 m y+ ]! ^/ x: y; E c, n - {# G, {9 _9 w1 C. I4 r3 R& L
- printf("Model name : %s\n", report.model_name);5 ~& G9 A2 B% B7 r" E4 H6 v5 T+ g
- printf(" model signature : %s\n", report.model_signature);
; E' C% X* k$ _. t - printf(" model datetime : %s\r\n", report.model_datetime);* g1 K3 }0 V. ?7 N
- printf(" compile datetime : %s\r\n", report.compile_datetime);8 w) j) ?/ @5 S" w& z
- printf(" runtime version : %d.%d.%d\r\n",
6 A- |% O% U3 J7 Z - report.runtime_version.major,
' K! X6 }$ |: X - report.runtime_version.minor,& j f1 {3 b! L( `! M1 D) v
- report.runtime_version.micro);. J1 Z2 ^" B8 S0 c# o) E3 }! r
- if (report.tool_revision[0])8 J2 z$ S/ v+ m$ L J
- printf(" Tool revision : %s\r\n", (report.tool_revision[0])?report.tool_revision:"");
6 H0 o3 k) v; A2 q, P - printf(" tools version : %d.%d.%d\r\n",
. W9 c" C+ T6 C& W, y - report.tool_version.major,
: L& U% o, u2 z/ Q- D3 v, k, K - report.tool_version.minor,( |/ P: E/ m7 h
- report.tool_version.micro); f; x8 Q+ O y% h
- printf(" complexity : %lu MACC\r\n", (unsigned long)report.n_macc);
. d" ]& c5 V( z, [ - printf(" c-nodes : %d\r\n", (int)report.n_nodes);
" k6 b5 K5 b9 x$ }# H -
, j3 s' @ K( I" k, t( x - printf(" map_activations : %d\r\n", report.map_activations.size);3 x% N/ a# w# e3 Q/ V, A9 d4 g% q
- for (int idx=0; idx<report.map_activations.size;idx++) {
+ d$ }# V3 d0 g0 j - const ai_buffer *buffer = &report.map_activations.buffer[idx];; [$ i2 m; w% f
- printf(" [%d] ", idx);' ]1 ~2 ^# _: K @; e9 L% J
- aiPrintBufInfo(buffer);
' }% o: X" G4 u) a - printf("\r\n");# Q2 D. Q( t) k" v3 z2 ?6 g
- }
: Z ]3 F+ w% B6 k4 }+ l -
/ ]. X& l8 T5 L# V# ` - printf(" map_weights : %d\r\n", report.map_weights.size);
4 `8 U; s/ p4 b1 ~ - for (int idx=0; idx<report.map_weights.size;idx++) {, w* y; G3 P% `6 d& _0 v* O a
- const ai_buffer *buffer = &report.map_weights.buffer[idx];
2 S; V1 \- x! Z( G' h! n0 b - printf(" [%d] ", idx);3 l' l( N" y3 O
- aiPrintBufInfo(buffer);: |6 p5 n- i9 w# M5 x; ~7 O
- printf("\r\n");
- b7 Q. j8 `! r& `; @9 y! B - }
1 w) n: B& N& G - }- U: ?% ^* d0 S) A4 ]- Q, p
- & I+ R& a9 ^6 L+ M- e( v; h
- /*& N D0 Q6 y, m4 e5 b
- * Bootstrap8 S! B! P s/ c8 z# s* ^
- */! k) W% C) O# t/ Z- ~
- int aiInit(void) {) ?, b2 R# u: S- n3 i+ Z. p' X5 R
- ai_error err;, m& Z; X( k1 r3 w/ B
- : y* x0 P2 `) h8 F; f& A
- /* Create and initialize the c-model */6 B7 V, C; ]5 W. T
- const ai_handle acts[] = { activations };. }; }* v3 ^+ {3 K' G
- err = ai_my_har_create_and_init(&network, acts, NULL);" q' q6 o# o+ }* Y/ e% D; D
- if (err.type != AI_ERROR_NONE) { T" o6 Q/ l+ ?
- printf("ai_error_type:%d,ai_error_code:%d\r\n",err.type,err.code);
& v) Y8 b% J/ Z) n/ e* Z' ^/ M( s - };
: Z: r5 ~& G4 M - ) a1 } y( X; }1 H4 |( O4 p
- ai_network_report report;1 u3 {" R j9 E" f; P9 e4 U
- if (ai_my_har_get_report(network, &report) != true) {% x/ ]/ ~/ q$ D
- printf("ai get report error\n");3 a6 I# ^) s9 Q5 D" k
- return -1;& D1 P2 @1 ?" a$ h( X7 K4 g% N* |
- }$ N/ w& J. \% f3 ^
-
' h/ m# ^- B$ u- F0 G8 `, r - aiPrintNetworkInfo(report);' _( g: Q. K0 ?6 V4 I& o4 B" |" n# ^( P
-
: s& m) O3 f, |3 w' l/ [5 r - /* Reteive pointers to the model's input/output tensors */6 A8 g/ s6 c; I
- ai_input = ai_my_har_inputs_get(network, NULL);
8 F/ H* f5 G7 x" a - ai_output = ai_my_har_outputs_get(network, NULL);
8 L, _9 w V8 f& s) j3 _0 c - //
8 X; t) a8 O r( T1 u: R- d1 F% ? - fmt_input = AI_BUFFER_FORMAT(ai_input); u& R+ v) v: F. g1 f- B3 H
- fmt_output = AI_BUFFER_FORMAT(ai_output);9 _5 `0 w9 X2 Z7 d& B m7 W/ A; Z
-
' U; J! m/ d0 W9 `, Q7 y - printf(" n_inputs/n_outputs : %u/%u\r\n", report.n_inputs,
% O! q% A) ?! E1 f - report.n_outputs);
& ~) a4 H x$ l- | - printf("input :");2 J( k8 ]) z' Z
- aiPrintBufInfo(ai_input);* }; A/ G; J# d( A1 k8 y8 B
- aiPrintDataType(fmt_input);
) r9 p6 \4 l( w" y) C! f - aiPrintDataInfo(ai_input, fmt_input);
L8 p3 a# K7 m( C' I( P - //4 s' k \! K3 e5 r/ J, }
- printf("output :");' P; h1 x9 e. `' }- ]
- aiPrintBufInfo(ai_output);7 l- S6 `( \1 f
- aiPrintDataType(fmt_output);
* K/ K6 V U! Y) B7 H3 x+ K3 k - aiPrintDataInfo(ai_output, fmt_output);
) x' \6 c' D( [, ]$ o1 I# n! d - return 0;
1 L% w7 a5 Q r) L5 r - }# M- g. l6 ^! i9 ~3 C
- 1 L- Y, B6 E2 w [6 S, m
- int acquire_and_process_data(void *in_data,uint8_t index, int32_t acc_x, int32_t acc_y, int32_t acc_z)
- Q; J# J& P: Q9 F! t - {+ c1 D) ^1 N2 w' ~0 q" W2 I
- char buf_srt[64]={0};
8 J- m, Q2 I2 ?# K - if(acc_x>0){
7 \* i, m% h# L( q0 d - sprintf(buf_srt,"%d.%d, ",(acc_x*98)/10000,((acc_x*98)%10000)/100);
- ^8 B# Z% u' e: a7 r8 I g - ((ai_float*)in_data)[NSIZE*index] =(float)atof(buf_srt);7 J5 s, N8 N3 a0 Z; h7 _) P
- }else{
0 k# j! [3 @# `( g; | - sprintf(buf_srt,"%d.%d, ",(acc_x*98)/10000,((-acc_x*98)%10000)/100);
3 K1 O8 g( G: { - ((ai_float*)in_data)[NSIZE*index] =(float)atof(buf_srt);# m% Q2 |" v' G7 C+ w$ k# |
- }2 @& T# M0 Z/ i1 T+ d" d: m
- if(acc_y>0){
& p" b q& u% b! J- X. W - sprintf(buf_srt,"%d.%d, ",(acc_y*98)/10000,((acc_y*98)%10000)/100);* A! @* X4 T' u
- ((ai_float*)in_data)[NSIZE*index+1] =(float)atof(buf_srt);4 [4 u+ [. g" L8 W* [
- }else{" }( Y+ \* @1 x# B9 l- C' a
- sprintf(buf_srt,"%d.%d, ",(acc_y*98)/10000,((-acc_y*98)%10000)/100);4 u' E1 a: ^& F- l3 X
- ((ai_float*)in_data)[NSIZE*index+1] =(float)atof(buf_srt);1 S1 _4 @2 [! F+ Q, W2 x. }
- }
' ~* B% M; h. _# J - if(acc_z>0){
1 g3 N' C4 P4 k) A( ^3 x* { - sprintf(buf_srt,"%d.%d, ",(acc_z*98)/10000,((acc_z*98)%10000)/100);
& H2 a: I5 d' t+ N/ {0 v; S% n - ((ai_float*)in_data)[NSIZE*index+2] =(float)atof(buf_srt);, e8 ]# d; f: |
- }else{
$ G6 X1 R5 n% |; a7 G8 ]5 r - sprintf(buf_srt,"%d.%d, ",(acc_z*98)/10000,((-acc_z*98)%10000)/100);
! v+ {- P* a+ v* ^, Q - ((ai_float*)in_data)[NSIZE*index+2] =(float)atof(buf_srt);
9 _1 E7 m4 b7 j8 w/ y! p2 n - }. A3 |/ k0 A$ g: \! V* |& V0 j2 ]
- return 0;
* K; U* Q4 I5 d \1 @9 Q. T8 T' R: U - }
( I7 Q2 D% ?4 T& l- e' ] ~" C( y' B8 ` - /*$ S) J5 t- @0 e0 T2 r
- * Run inference
, V; }; m$ h, Q8 ^9 m - */- h; t' a$ Z( P8 @: q
- int aiRun(const void *in_data, void *out_data) {1 _6 `! l) K1 e' ^
- ai_i32 n_batch;
, {9 V8 g8 @: Q8 ^ - ai_error err;4 A1 A6 n a( N) y2 q
- " n) W# @) F0 B
- /* 1 - Update IO handlers with the data payload */( G. k2 i8 Y3 T! B6 H4 B
- ai_input[0].data = AI_HANDLE_PTR(in_data);
& G& y- k8 n7 Q- B3 ` - ai_output[0].data = AI_HANDLE_PTR(out_data);
+ G3 n9 o! N( I' T -
! o# k9 t" E3 |7 q7 L - /* 2 - Perform the inference */
; q; O1 x' W X/ g. M$ f3 y - n_batch = ai_my_har_run(network, &ai_input[0], &ai_output[0]);. ^/ \$ [0 `# j8 Y( Z
- if (n_batch != 1) {, t) X( v4 N6 z# Y# M
- err = ai_my_har_get_error(network);
5 u0 M( ]3 x+ _$ ?- a- J - printf("ai_error_type:%d,ai_error_code:%d\r\n",err.type,err.code);
( i) e @3 ~' ^3 `/ M6 A - };5 Y: ?' @5 A3 o+ d8 s5 u
-
; d2 C, F: `# e. S9 z \ - return 0;
0 }! G( Z! E) u - }- n" }$ W3 w+ S' o8 n1 h
- : [! @! v0 P; F2 v1 M- ~- ^# n
- /* USER CODE END 0 */
复制代码
- o; m/ n0 l. V$ A+ r2 Q9 s* w 在main函数中初始化ai模型; D# l$ P& {7 I. F$ t% B
- /* USER CODE BEGIN 2 */3 A) L( C2 ~1 a( Z! [
- ResetPrintInit(&hlpuart1);5 n/ B K, Z- g1 y
- HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断
0 z/ O; u0 t+ w- L - HLPUSART_RX_STA = 0;
\5 G# P" x" E6 W+ w( ]: w - //LSM6DSL; f9 N) u) N4 Q( d
- LSM6DSL_init();
% R9 s$ V8 M) b8 k3 ~, k; a - LSM6DSL_acc_st_open();
, `# }9 L) h( _; F3 k8 [ - acc_x = acc_y = acc_z = 0;6 z3 z1 z" `" d4 S1 J. g: @
- uint8_t menu = 0;
1 g% I, Q! z. j" ?, K - uint8_t step_size = NSIZE;- `( M1 l0 u+ H( Y$ @+ A( N$ y
- //
, l9 c# K7 k3 Y/ I% e - aiInit();$ A' W. s! N* C
- buf_print();
% f! H9 }. s1 \$ D$ R$ v3 | - /* USER CODE END 2 */
复制代码
8 n2 X) V* X0 }9 I8 Q, u 在main函数循环体中,通过串口lpuart1调试发送test,开启将实时数据推送给ai模型
+ q3 d: _: N' m+ O2 D- /* Infinite loop */+ q, `' W5 i& D# |& t6 ]: f" \
- /* USER CODE BEGIN WHILE */
% r/ J8 U( \% o; c' E/ F7 ] - while (1)
9 G( R R. n& O7 t7 j - {: d. W' q: A1 J4 d1 W2 u* N
- if(HLPUSART_RX_STA&0xC000){//溢出或换行,重新开始
' A- r( q$ O1 x - printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);
2 ~! w' _" _" ] @ - if(strstr((const char*)HLPUSART_RX_BUF,(const char*)"test"))
* T& u% `6 S1 s( b5 L - {
2 c$ `# H& ]8 @. C. y - menu = 0x08;
& f7 w6 j) }) ?, ] - }
8 I, P% w# ]" H* y) U0 N5 X A - HLPUSART_RX_STA=0;//接收错误,重新开始
' y* M& }! O0 j: x2 J - HAL_Delay(100);//等待" ^& q, t& \7 H0 ?1 A6 t+ P
- }6 G$ v. q5 k, s! x ?+ k: F! D$ z
- if(KEY_0())
( o$ J0 K9 U8 i/ F. C! G2 j - {
# F# j0 h% h$ S, Z - if(menu&0x01)" z# A: u8 e, b: _
- menu &= 0XFE; //取消静止不动数据刷新
7 `& `+ ?3 v6 V$ k2 y# p - else{
) j: e! {! U) ?/ L3 n$ s w - menu |= 0X01; //开启静止不动数据刷新: ~" H! p# E; A
- }
9 ?2 B' e/ S: d& |% k. b2 k) v- h - menu &= 0XF9; //取消其他数据刷新. j: G% x+ j7 D: f a, S0 K% O
- }
; b: Z" ^5 i; `# W - if(KEY_1())3 B/ u, [5 q5 j
- {8 v: k4 w! I/ W( r; {
- if(menu&0x02), t- s; u2 N* P; P$ r
- menu &= 0XFD; //取消左右移动数据刷新
3 v& W. J# A8 w9 v - else{6 v) W7 v9 C- ]5 B& H3 T
- menu |= 0X02; //开启左右移动数据刷新- w0 a) E/ t k1 ~4 Z
- }
1 M8 @% V! d" ^0 c. ^' O - menu &= 0XFA; //取消其他数据刷新; m* q3 X% o4 Y$ w* x) a5 T
-
9 O$ F6 X5 F6 g9 b - }; G: O: O& o% f0 U: j5 ]
- if(KEY_2())( n3 y Z, K7 l" A- s) H
- {
& G3 Z7 \% k; a4 N% t( } - if(menu&0x04)
8 M: X# ?5 g( z - menu &= 0XFB; //取消上下移动数据刷新$ v4 j: S! m- _; _6 G2 ]
- else{
+ R3 X$ J4 j0 F - menu |= 0X04; //开启上下移动数据刷新
+ M/ A. x% i; U1 U4 F8 N - }
4 H2 L$ e8 d. p) O: ^' T7 G - menu &= 0XFC; //取消其他数据刷新
: G& Q9 {( C+ k3 l" d -
: k+ E* h$ R( E9 ^1 P, t5 ?: [ - }
) G7 J# a: {, k9 o/ n - if(menu&0x01)//静止不动: U. z3 [6 m6 R
- {/ f. i Z8 X& C" l
- for(uint8_t i =0; i<step_size;i++){+ W- k$ O0 f( Y, Y+ [
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);3 I' a' ]6 B ]/ E8 ~1 t: w
- out_print(acc_x,acc_y,acc_z);1 h9 S ]6 u3 j; [% K& |
- HAL_Delay(100);//等待
) p- j0 x# S8 d5 O( H" S# S7 w - }( t2 Q! X2 k1 m2 N) _& {. G
- printf("1, 0, 0\r\n");( M& S( s1 S: t! s# U! _
- Toggle_led0();
0 j K' [: F3 M3 H$ Y- k4 m - }
. x; y" e) \+ k8 @ - if(menu&0x02)//左右移动* M2 b' Y( e8 d4 ~
- {
! w! d" A, V- @! A3 ?& H - for(uint8_t i =0; i<step_size;i++){3 m. r: q: D5 T
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);
/ J# X+ j) T9 b - out_print(acc_x,acc_y,acc_z);7 A" C" O$ O" j0 Y: n+ _$ p( P
- HAL_Delay(100);//等待" G \ y& g3 ^% G6 i) ?' E. p: H
- }
4 \) v4 ?1 x$ d2 J5 L5 p) V4 a - printf("0, 1, 0\r\n");
8 {' p: O- l1 Q" U" w - Toggle_led1();
$ V- L! ^ X( N - }
8 {& J) U5 P1 ~9 }+ \5 ~ - if(menu&0x04)//上下移动) R2 c7 b# z6 i0 c# }5 C7 E
- {
& H/ H, J. P2 J; }9 | - for(uint8_t i =0; i<step_size;i++){- p2 Q- d3 C# ^5 Q+ Y# G3 M" M
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);
0 m( {& h+ q4 G, O* }( N; B/ `! f - out_print(acc_x,acc_y,acc_z);1 m# R0 x- R+ B- P6 w( ?3 F
- HAL_Delay(100);//等待, k% P" ~" \0 x
- }. ^3 W- _: z5 V( u
- printf("0, 0, 1\r\n");
& ^ F, M; [1 g4 n* A) P - Toggle_led2();* v# |- G5 d# O3 h; p
- }& N6 ?+ D2 `* q9 V
- if(menu&0x08)//测试
8 a d8 @" I3 B* [ - {
2 H( r* h" |% Q" w - for(uint8_t i =0; i<step_size;i++){* k$ `) V4 ^- h$ p8 I3 {" F. z
- LSM6DSL_acc_read(&acc_x,&acc_y,&acc_z);2 @- F9 G- u8 G5 \
- acquire_and_process_data(in_data,i,acc_x,acc_y,acc_z);
! h, x2 ^1 h. a4 q" z - HAL_Delay(100);//等待
1 g( T& ^# D% s( i) i - }
/ ?2 P( ]; h0 h4 e4 E A1 V' W - aiRun(in_data, out_data);
% P0 F/ m5 m+ r7 ]' l4 B - buf_print();
8 w4 i* I: u J - }
0 ]( s* h6 q! E/ \: R) `2 _0 } - /* USER CODE END WHILE */
复制代码
2 e2 u' I8 `8 t: i! X, D) I 编译及下载程序) _6 I3 T* I. e& p0 \7 v
* p! }3 w( h8 y2 ^
6 s& ]& J$ E" h4 i, N
6 ?* I. m8 s; n- O& |/ d8 o8 f: b 串口助手通过lpuart1连接开发板,发送“test”,开启AI计算,静止不动开发板情况如下:
* U }$ \9 h3 q, b# \0 H
$ C4 Q ^- f$ {2 n @! Q
' [4 ?# y! [" C* N% W4 ?
2 L8 T" l% T! I. _# {2 S7 D. e7 p5 ~
左右移动开发板测试输出:
$ Z# p9 C- ^/ i$ ?8 ~7 q& s$ M$ s' `# X' m' b
" R0 a" @; c8 Y; |, y
% v5 L6 g) ?' R* ]% }8 u 上下移动(垂直方向)开发板测试输出:2 z" J* T4 a* X8 Q5 ?! R6 a
; w( F4 [4 u0 {5 L7 N* m% b Z
- M9 i/ R5 K: r1 E" r% L7 H' T3 x' H9 l1 Y9 B! M. O5 r# I4 I8 Z' p+ F
通过测试可以看出,基本能识别开发板的行为,若需要更准确的识别,更好数据采集方法,也可以更多姿态行为模式计算(开发板不同朝向、倾斜度等)8 Q9 H" e% B! n/ U
————————————————! Z+ d+ L1 V* Z* b" M6 }
版权声明:py_free-物联智能- R+ v6 ~ _; P6 z
如有侵权请联系删除
3 g4 Q& A6 f/ Y0 j
" [) i' J$ \1 I9 f3 u |