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