
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------& e; B, M9 h" {1 P9 }$ o main.c #include "stm32l0xx_hal.h" #include "dma.h"8 m' s8 }* @2 s #include "i2c.h"( S+ c0 l. D+ R) L- G! c$ C k5 k8 Y #include "tim.h"" b9 Q4 }) |& p7 A4 F! _( D1 }! M g% {: b #include "usart.h"0 r8 F2 |' h4 |9 z) n #include "gpio.h"8 k7 V' G6 M& c( M2 w #include "mpu6050.h". E- o; `: w% S1 \) \ F$ U$ I #include "visualscope.h" 7 G! l; [5 k+ q$ I9 F5 q #include <string.h>. a7 p+ W1 }7 _3 t) w2 f* x #include <math.h> /* Private variables ---------------------------------------------------------*/9 E, Y" s- G, L; ?$ v: \- S% N' } #define RXSIZE 8 #define TXSIZE 8 uint8_t rxBuffer[RXSIZE]; uint8_t txBuffer[TXSIZE];; r i* Y* q4 q, ~0 X- l0 F ! Z% W0 h/ d7 N float Angle_accel = 0; float Angle_gyro = 0; float Angle_comp = 0; uint8_t outAngleData[10];% d2 _0 ?" n% H' \% T+ L* H /* USER CODE BEGIN 0 */ /*---------------------------------------------------------------------------------------------------------*/* H) K, X% T) K# F5 O: G /* 重力加速度算出的角度 */8 N; e/ ^+ u+ s1 L0 Q; ] /*---------------------------------------------------------------------------------------------------------*/% A' K) Q% g5 Y: w6 P int32_t Calc_AngleAccel()7 y! T$ y! Y5 V& w. J {5 u, I) Q" D. k2 k/ C% t9 }# l int32_t value = 0;* _! I+ e8 I6 p* [7 ^' W; ^; a. _ value = GetAccelValue('x');& ~! U1 ^& q% i5 E* C3 i& p if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296);. C' h* g |3 G# b( Z5 _4 h else4 L5 W$ r3 @. k Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);" v: I" N) N1 J return value;& H; S4 U, g. @" a: `0 d } /*---------------------------------------------------------------------------------------------------------*/, j1 k/ v8 ]5 E s9 p0 t4 d /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/0 p* d$ _1 z9 A1 G! F$ z2 M int32_t Calc_AngleGyro() { int32_t value = 0;0 r9 q1 @$ C' ^ 9 B8 h$ P4 G3 z3 t value = GetGyroValue('y');; q2 D: e8 `, B& U, N3 f$ B Angle_gyro += (value / 16.384 * 0.01); return value; }1 k5 L2 {/ ~1 B! L" r8 p /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */ /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro)2 m! y' j9 @3 N* t { Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;2 G7 T' g0 d/ p5 O+ Q0 |5 Q" F ' a2 S; t7 {9 n8 T6 ^& n return Angle_comp; }/ \( }$ S% e) M. Z+ L; d; c + A- v' o! l7 [6 [0 L; s' m: @1 ~ /*---------------------------------------------------------------------------------------------------------*/0 T5 M8 u) z0 g$ `& v" b! } /* 输出角度至上位机 */4 b i- y- ?% F' e9 S/ M5 _ /*---------------------------------------------------------------------------------------------------------*/6 z: _5 t( S# L5 `' m void VisualScopeAngleOutput()+ A# m ]1 U& V* w, |3 a3 Y/ X {0 Q- X* N8 o% {1 ~1 H int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;' N; f) U& }$ R uint16_t crcValue;- E9 M6 K' ^( O, b/ a AngleValue_Accel = ceil(Angle_accel * 10 -0.5); AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);0 V ~2 i: ?8 ]" Z- J1 Y AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);! c7 Q2 O) |) \( Y2 T " u0 y# p! C* W6 F- |7 Q& \ outAngleData[0] = AngleValue_Accel & 0xFF; outAngleData[1] = AngleValue_Accel >> 8; outAngleData[2] = AngleValue_Gyro & 0xFF;" l$ L* c& L0 a outAngleData[3] = AngleValue_Gyro >> 8;- d/ f$ B5 \ z, ]5 I5 l) ` outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8;* c- T E9 Z5 t2 O( p9 S4 K/ @) a //计算CRC crcValue = CRC_CHECK(outAngleData,8);) ~* \+ S4 Y* R0 L outAngleData[8] = crcValue & 0xFF;- m4 i, F( j M" \ outAngleData[9] = crcValue >> 8; //发送至上位机! S, z9 f. |( y' M( q$ n! ?7 c9 G HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData)); }! I. }( B" D( N( o3 f2 _% n /* USER CODE END 0 */2 n L9 ]7 o7 a' x9 Z /* Private function prototypes -----------------------------------------------*/- L! U$ @5 i8 x# J# y# u9 h void SystemClock_Config(void);. j% u, U d1 p1 x3 Q! n 5 S5 P0 w4 M# U3 d 硬件连接图: ![]() 波形图: ![]() 最后加一个视频:+ c' Q' Z" T2 }( a9 `$ S STM32L053 演示4 G$ f0 A9 x3 M' Z) N0 \ |
STM32如何分配原理图IO
利用STM32MP1和STM32MP2为嵌入式Linux提供有效的安全措施:供当今决策者参考的3条宝贵经验
有奖直播 | STM32MP2x 资源隔离架构 (RIF) 介绍与使用
STM32ADC过采样及几种ADC采样的处理方法
分享一个STM32L031的串口调试程序
白皮书下载|边缘 AI 变革:MCU集成 NPU 的破局与领航
OpenSTLinux:为STM32 MPU生态系统带来超强助力
【STM32MP257】轻松搭建A35 Linux编译及调试环境
【STM32MP257】🥳STM32MP257-DK-开发板开箱体验
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
#include "i2c.h"& r7 C% m$ [/ J8 ]+ Y
; h4 m3 {( l G( t w- \7 G
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */+ p8 \: w: @6 N" [, o& X
I2C_HandleTypeDef hi2cx;2 r$ Z# u# y- U( i4 l2 n
2 t7 n3 |4 |* I" L
/* I2C1 init function */. i! c) g% J" J% V9 e6 g
void MX_I2C1_Init(void): W& v4 |, P! [: C9 }+ _# b* P3 a
{
0 m6 V7 `; y% k/ u( m
hi2cx.Instance = I2C1;
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0;/ X9 R3 `$ K2 C$ m
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;: z* v$ h0 J- F- J/ f% U5 e& _ {
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);
; i o* G0 V1 i; L/ {* x
/**Configure Analogue filter
*/
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
. v3 {) Z9 @0 f j8 @( v& a
}$ b; K. e, Y; O% V/ ?5 {; k. }* O
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{- \2 M- T! f( M7 Z6 W3 Q
+ {. [) h. |7 @9 |/ A) E4 u
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)! {. n6 Q/ }# k' f! Z3 ?! {2 v; f. Y1 R
{3 }& m7 p% H' v! U4 r
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();4 B( n' r1 a3 t+ H: {
/**I2C1 GPIO Configuration : u5 y) f& c# i8 f; f n' \
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;7 e4 _. F2 S3 `
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;3 d8 n7 D) V( Q& f& u5 c+ x, o5 r6 ^6 j
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);7 v. h; _$ \) u/ s! b/ K
}
}
" y6 `" j7 b2 E, M: d
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)/ f7 l& s! l8 A8 L9 q
{1 J$ Z1 U$ d7 O
4 F! D9 y# J; e8 t3 D$ B, I
if(hi2c->Instance==I2C1)
{
/* Peripheral clock disable */
__I2C1_CLK_DISABLE();8 W) \. e! j0 E, z( j0 p0 j9 M
/**I2C1 GPIO Configuration ; V m C1 J- ^- ~8 I1 Z/ }; h
PB6 ------> I2C1_SCL' \ x6 D6 @0 j7 ]1 j
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);& `7 `+ a! n1 \( d* O* \
$ k. `/ Z; v9 O% S: |, K
}% w3 Q) v5 K5 X7 u& V1 m
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------( M/ a( l5 s6 L2 S
usart.c9 {( h, ?8 K/ [, g1 Z& `: W& L
#include "usart.h"! ?3 ~9 e# D; B! L
l2 I/ }2 T# G" k6 p
#include "gpio.h", m6 i7 F( b ]' C" ~# ]5 x# I6 V# R& x
#include "dma.h"- B3 b0 [7 G3 L: z c% x) \
. r2 t3 y) ^' q( U4 {2 M
/* USER CODE BEGIN 0 */
& |1 m" B) k1 U( p. J: G; X2 T. s- w
/* USER CODE END 0 */; f; X4 O4 L- [7 P
1 j$ C+ r z* Z
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;) w) W* c" m4 |/ y$ L9 ~0 d, ~6 H* A
/* USART2 init function */- s3 g9 U, `. ]) b0 w4 E
7 A1 s3 Q+ B$ b1 B5 } D
void MX_USART2_UART_Init(void). T+ u. Y9 X! T1 c
{" c: I- e. [, c, n6 J' `, ^" y
huart2.Instance = USART2;& h# m$ {- h2 m; }6 ~ h
huart2.Init.BaudRate = 9600;. P4 h3 y6 b4 e& h' W7 H( h7 W7 W4 |7 A
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;) F8 z: ]6 z6 l$ ~
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;9 u0 x \& B- @6 }2 {
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;0 s# K. q9 {/ L6 q' n3 o
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;2 _& b+ s2 E, i% }
HAL_UART_Init(&huart2);. ~ J+ L3 c8 d; B8 @; q
}$ S) @2 B$ g# w& z7 @1 T6 n
void HAL_UART_MspInit(UART_HandleTypeDef* huart)7 a* \/ D! j: J: `* k: q
{9 x/ s+ }* q4 T, F% @" C0 d4 m
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{
/* Peripheral clock enable */
__USART2_CLK_ENABLE();
* @- H$ g+ Q2 z% } @, N
/**USART2 GPIO Configuration ' U8 V- X# e4 a* ?
PA2 ------> USART2_TX
PA3 ------> USART2_RX( [6 H8 o I! p* u. e' G. e
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;* [' ?! Q; F1 R H1 s
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;) }& C) j) J, l
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);- h1 K( X( x6 {8 {! d7 Q
; Y! q' ~1 T1 u1 D) D4 @
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_usart2_rx.Instance = DMA1_Channel5;
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;, ]% h+ t, e7 p
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;$ y& O0 K4 {9 \1 x0 n* Y( z' P5 y
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);
" Y) l5 A' _$ x
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
hdma_usart2_tx.Instance = DMA1_Channel4;
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;5 R3 V' f+ U: M, _5 ]; N
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;" g+ i& j/ a9 ?) a3 s6 ]: s
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;! l0 U4 `8 i3 ]5 s) U% w1 s* t9 H- W
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;! `- V* A8 q0 B- R5 }
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;' m9 K) Q7 G' E$ q
HAL_DMA_Init(&hdma_usart2_tx);$ Z6 P/ ?/ x& W. b9 Y# B
7 |" I5 b% U- W, u
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);$ d8 {! s/ e1 ^6 |$ P x# Z
}
}. b, e) q% |% ]7 u
4 k2 r' A/ m8 h! s: N
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{' i- P* h4 A0 f9 L2 u* g* }' f
if(huart->Instance==USART2): {- w% @. C# L
{/ s' q' \5 e9 ?7 A7 k, F8 i
/* Peripheral clock disable */
__USART2_CLK_DISABLE();
2 N& {$ x, Y" w+ C* _" q
/**USART2 GPIO Configuration
PA2 ------> USART2_TX' s& f+ D/ W# q6 P" r
PA3 ------> USART2_RX8 c' U- K6 O' Z, z" q& O5 N4 L
*/8 s1 ^, x( d0 u. r
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(huart->hdmarx);
HAL_DMA_DeInit(huart->hdmatx);
}
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------( J. Z4 j5 I$ N' m" S1 Y
mpu6050.c
#include "stm32l0xx_hal.h": G4 w% l% w' B O; H0 s$ x
#include "MPU6050.h"
//各坐标轴上静止偏差(重力,角速度)# D+ f: K3 H2 i
int16_t offsetAccelX = -195;
int16_t offsetAccelY = 560;
int16_t offsetAccelZ = -169;* F6 \7 m4 G( V* N5 M# i
7 J, k1 k0 Q9 |' B8 [
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;
int16_t offsetGyroZ = 4;8 C0 O- }4 [3 |
/ M0 c$ E7 c- h7 A
extern I2C_HandleTypeDef hi2cx;) \, V4 h; y# Q1 ?! R" x. z; C
3 m5 q8 x1 w. ~& g9 z
//**************************************4 r1 d# p+ _7 J% \
//向I2C设备写入一个字节数据, K' | \6 J. [2 U! D
//**************************************
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{
uint8_t rxData[2] = {REG_Address,REG_data}; g: m3 K* D8 W+ H2 K
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK); q% O$ S* I% D3 a7 I0 p4 D G
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)* Q4 J: q: N$ i$ n8 @. W4 J. h' N
{}, j8 L4 {" M, b2 G5 N: I
}
}
//************************************** d( m; H. e Q* F- h, A* E$ t
//从I2C设备读取一个字节数据
//**************************************4 d# ]% o+ O `. _5 {
uint8_t Single_ReadI2C(uint8_t REG_Address)# x$ Z+ f J' `: w# y$ z, d
{
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)1 l- [( C! Y7 [; |) E0 I5 J' u
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)* A6 S& u8 ~/ h) ^5 w- @
{}( m- m3 v" m; ]% x4 e. K- s
}
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}1 o# ?4 b7 Y1 u
}; W: j& o% O0 I# \
return REG_data;1 ?( b2 M% D8 D* D8 V7 p
}9 M/ p7 c8 _9 ]) f8 T/ D3 a( _3 Z
//**************************************8 e" g/ K4 A4 W% o
//初始化MPU6050; Q. Z& P. _4 D% k, i$ X
//**************************************/ p" I+ x% P. G. t: F
void InitMPU6050()2 f8 I$ q7 k* f' G- _% U
{. H1 O& ^4 [5 X/ i8 p
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态3 U% z* D. ^4 q% o7 e
Single_WriteI2C(SMPLRT_DIV, 0x07);" Y" Y9 p; O& p7 d) ]; i0 O# x) r
Single_WriteI2C(CONFIG, 0x06);
5 h0 H5 J0 X5 V8 @0 h# o2 G1 o
Single_WriteI2C(GYRO_CONFIG, 0x18);
) ?/ K. g1 Z( n& `, Y1 {6 a
Single_WriteI2C(ACCEL_CONFIG, 0x01);6 N! ]. e* ~! o5 N* ^
}
//**************************************3 k1 b. Q. ~& G( M
//合成数据
//**************************************
int16_t GetMPUOutValue(uint8_t REG_Address)6 o7 v; Z8 Q. n: G. _
{( F. x& V; }$ x# G1 p5 _- M
int16_t result;6 K' }- K' B: Y9 K' a1 P
uint8_t H,L;
H=Single_ReadI2C(REG_Address);3 H8 C( q: e- q- \* T
L=Single_ReadI2C(REG_Address+1);+ c% C( r6 L; m2 V8 X9 t( i- `
result = (H<<8)+L;# Y; T2 {. r3 o4 f5 v
return result; //合成数据* A. w$ [* D. j6 H" A( [- x
}
//**************************************5 n, }# Q- p2 c2 f; Q
//取某一轴上的加速度数据% ?! h1 d8 ]8 E" b: S, }
//**************************************
int16_t GetAccelValue(char axis)5 y( C! `" E* {/ r F
{/ N% X' T$ ], K) Y7 U1 ]6 o7 S
int16_t result = 0;, ^, D' g: j: k3 P
switch(axis)$ @( ?$ c7 X1 a% G
{- C$ k0 w* N. f* t1 l
case 'x':- R6 u' B2 b, b5 r4 e6 w
case 'X':$ Y. q I+ n/ Y, S' v% p+ X6 X
{
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
}+ N2 I3 H' R" G) R
break;
case 'y':
case 'Y':
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
}
break;4 ^+ O* W# f Q* i& q% T
case 'z':3 ~' k/ [/ ?- _" z4 ]
case 'Z':# Z- ?# r" c: }$ \5 n/ [) g% h
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}0 E4 K. B/ @3 i5 h( V
break;
}
return result;
}
9 K( l7 U2 R9 ~2 d" I. ^3 n, k3 U
//**************************************
//取某一轴上的角速度数据; O( s" M% v9 r% W3 O" D1 i
//**************************************
int16_t GetGyroValue(char axis)' j- r6 j5 w3 n
{) E/ w+ w5 x3 a7 f; R
int16_t result = 0;
switch(axis)
{& r# `' H% S6 r' W8 b
case 'x':. E! _. S- D/ R2 y j
case 'X':
{" h2 _( K. {* r" f, y, J
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;' R8 R6 J( x9 l' L
}+ \. m1 q2 k, h. e3 v
break;
case 'y':: H" a5 U S- N) E. A
case 'Y':( s' }+ V) e# r: @
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;3 X( N u+ X1 }% w$ J; W( [
}
break;! S& p8 r3 a9 d2 }9 x- D+ J
case 'z':
case 'Z':
{
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
}% E( A5 ]& _7 i" d. H4 i0 u
break;$ w5 a5 @( @" z: g
}3 g4 C4 l1 b3 H, c0 |
return result;2 E5 O1 k! Q( O( ~/ J
}
评分
查看全部评分
{
/* USER CODE BEGIN 1 */& S& D9 m/ Q* X
2 B3 F7 ?2 \6 |
/* USER CODE END 1 */# a" S) i+ |: N4 g1 T4 `
/* MCU Configuration----------------------------------------------------------*/1 P: E t3 I: `! U2 `: G! C
' m0 l* r$ F% A0 y& V
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */+ b! ?6 e c) ~. ~2 c* o' S p! K {& a
HAL_Init();; |# s# P8 Y( @" G1 B
! F- H6 g s! f0 w# ?* a# o
/* Configure the system clock */
SystemClock_Config();
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */7 w" B$ H' q' o+ z, k' y
MX_GPIO_Init();9 H( N/ y; w) D
MX_DMA_Init();% V1 q: Y! x* b! A% M
MX_I2C1_Init();
MX_TIM2_Init();* n; y- W1 r- y1 X8 y7 ?+ V6 f
MX_USART2_UART_Init();
InitMPU6050();* F0 Q- T& v, I9 ]
/* USER CODE BEGIN 2 */+ F5 w7 R* |$ x* d1 @
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);2 v/ J+ I' A% j# [4 J6 w: H0 @
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */% T* t4 F4 T7 G/ q t
/* USER CODE BEGIN 3 */' W3 l# v( O& R/ a) j5 g- o* A
/* Infinite loop */
while (1)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
VisualScopeAngleOutput();
HAL_Delay(100);
}6 R- w2 P( l6 c3 i# b
/* USER CODE END 3 */
7 E) X1 u* K& V/ }' q
}2 `4 q$ S2 i8 R8 s6 O" L# {6 C
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;/ E: O4 }+ {1 V
RCC_OscInitTypeDef RCC_OscInitStruct; H0 H& L0 }9 A. s+ M+ W0 P) \
1 M/ W$ M: L0 V# e Z
__PWR_CLK_ENABLE();
& n8 M& U( |& ]: r
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;; ?4 }) n/ S0 n: R
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
HAL_RCC_OscConfig(&RCC_OscInitStruct);1 Q1 w- J0 f9 [% H" I/ U
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); Q0 e; S' w2 P
: w$ d" s0 V* J6 u! x
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;- y, B5 c/ m8 a% D% e" o& j
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;. E0 s9 z& x: b6 F2 \% l1 c+ }
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);' a, n' r2 A. m0 |3 h
3 F g! A9 o& \) T9 Z
__SYSCFG_CLK_ENABLE();5 W p1 \( ~7 q+ @
}+ z" z: R0 {7 q% K8 [
& [ J6 h: u& f, e
/* USER CODE BEGIN 4 */3 S+ J0 s, }' n7 B8 }& ]
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{# M1 T$ }: n k3 ^0 ^" s- Q
if(huart->Instance == USART2)3 x$ A, A/ V7 s! O
{! X' f- l1 P; {) l2 E9 S5 J+ ~
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}
}. A) ~& x! n( V. j. d! x1 w
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)( R! c" `( C+ W U5 ~
{
}
" S; v* O* A6 P% M4 ?4 i# p
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)4 J% D- z$ o+ P/ b
{% w4 W" U& Y$ _# ]9 c# N
int32_t GyroValue;3 v# ^4 P) q. |% \. H( _ b
Calc_AngleAccel();
GyroValue = Calc_AngleGyro();
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。