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