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