
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c #include "stm32l0xx_hal.h" #include "dma.h" #include "i2c.h"+ M$ q8 [' I- H2 q1 u #include "tim.h" #include "usart.h" #include "gpio.h" #include "mpu6050.h" #include "visualscope.h" 0 D8 E: }: k1 ~3 x #include <string.h>& F0 g9 _5 U3 o% u #include <math.h>! b) t$ X& u: a; [, A4 } /* Private variables ---------------------------------------------------------*/) \, U, ]6 E. u$ N9 B #define RXSIZE 8: l7 h; q; ~3 M& ~* L2 `3 m: ~9 I #define TXSIZE 8 uint8_t rxBuffer[RXSIZE]; F& N q- a- F$ e; J; r uint8_t txBuffer[TXSIZE];, s, Q9 [) A& V4 o( h5 T+ q+ m 0 @* v; [# p$ B6 H B6 t float Angle_accel = 0;2 Z" {, @3 x2 i+ n$ D/ |# \* P+ z float Angle_gyro = 0; float Angle_comp = 0; uint8_t outAngleData[10]; /* USER CODE BEGIN 0 */ 1 {* ?" P, O% Q& ~, h. j/ O /*---------------------------------------------------------------------------------------------------------*/ /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel()) g8 }- y7 L' @" j# f {% l- r( K: A6 [5 D" f$ k int32_t value = 0; % F7 W% O/ q; W! [6 r* B4 V+ @ value = GetAccelValue('x');, T& n' ^9 Y, t4 t if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296);' j7 I: |+ M! _+ A+ T2 g" P else Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); % ]5 p! W4 N' ?6 y& B2 V5 r6 y return value;3 b1 z; `9 H B" ^ } 1 \, c! E) [- k' t. }- G /*---------------------------------------------------------------------------------------------------------*/( a3 p& w; ~+ M /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/! h8 A) |) a; P3 c$ ~0 s" o9 {$ H3 J int32_t Calc_AngleGyro()7 g5 L. h( S/ c. w1 z {) I& T# }+ D* s% O; V int32_t value = 0; * V8 e5 v; F& H* {, m' e: k value = GetGyroValue('y'); Angle_gyro += (value / 16.384 * 0.01); : |! A6 g* O1 h5 T) a! U3 x return value; } / E% W" p- X+ d" y& t /*---------------------------------------------------------------------------------------------------------*/( v- f! J' `0 v8 x% n. x$ ^ /* 互补滤波求角度 */; X/ N" W0 S4 b' T' y3 | /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro)" g% V t- l: T { Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel; return Angle_comp; }) B8 W8 c+ a+ Y ]' B8 W4 ` $ q( I/ R8 t; N* g+ I! y& }8 k /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */ /*---------------------------------------------------------------------------------------------------------*/ void VisualScopeAngleOutput() { int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;$ A6 q; R" q2 t3 T# g uint16_t crcValue;. O6 c' O% H$ Y ^% q3 N) C; E # B; W2 E) u( s& X @3 _ AngleValue_Accel = ceil(Angle_accel * 10 -0.5);* C$ S9 z7 ^8 x4 {3 z AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5); AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);& b+ {- y$ l# e. v l) S 9 P# p8 c+ U3 [$ \% }8 i outAngleData[0] = AngleValue_Accel & 0xFF;8 u* I5 U: K8 B outAngleData[1] = AngleValue_Accel >> 8;7 a* L9 B5 t8 D9 T- j outAngleData[2] = AngleValue_Gyro & 0xFF; i4 K: A! K% ]& j& f+ \4 }8 x outAngleData[3] = AngleValue_Gyro >> 8;5 d9 N% ?# N& {8 g4 L* ^ outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8; //计算CRC4 o* z# L* e+ B3 z" e crcValue = CRC_CHECK(outAngleData,8); outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8;4 w7 V/ M2 l2 S3 X" b //发送至上位机9 }. h* k0 Y6 h$ k9 L# i, u HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));* X) K1 T+ E5 b# e& }7 R }: k# {2 D0 |0 `* b* ^5 d# P /* USER CODE END 0 */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void);; D9 O) k) I6 m" c. s9 l; Q 2 p$ Q' r4 x7 y" L+ D 硬件连接图: ![]() 波形图: ![]() 最后加一个视频: STM32L053 演示 U. U3 s3 _; j8 q& e5 e |
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"5 X. k Z) v1 A, Q, y* ]5 }( b
#include "gpio.h"
( \) `% p4 t% B. x8 u$ c# ?
/* USER CODE BEGIN 0 */
$ z5 S% N3 Y# u
/* USER CODE END 0 */
I2C_HandleTypeDef hi2cx;
- N5 i. q) R+ H7 _8 D/ E5 o
/* I2C1 init function *// `+ ^+ R- W1 o% n, U% Q1 s3 A9 b6 O
void MX_I2C1_Init(void)+ v, V0 l6 l' G6 V5 f
{+ z4 F; i p, |* Y" X7 {7 ?
I- E1 d0 }' [9 M$ _% l
hi2cx.Instance = I2C1;
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0; H/ d% j3 |2 Y' u( i- e
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;# Q% A$ ~5 m5 l, h$ m4 s' ~- F$ c, }
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;, u6 @2 _1 X6 P! \
hi2cx.Init.OwnAddress2 = 0;0 o% t; y3 V+ Z& C" d4 L/ M7 p
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;" d5 c: a6 z, W$ U
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;8 p# K" ?- Y8 _! T2 a% ]
HAL_I2C_Init(&hi2cx);
1 G! i0 ?+ Q4 j: G
/**Configure Analogue filter
*/$ p2 J& i2 ^3 [5 y6 | I% o
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);7 t' f1 W3 Y8 D9 d
5 V. t& Y' ~ Z3 S$ N7 L. N2 J* k
}- J8 K, o. b* |$ v& h- x/ _# o% Q
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)$ b9 y0 G1 O- @: H+ H% R
{- {6 t3 w9 R" m% H! D0 I8 |
" \8 H T( X" p8 e. ~- E' ?* B
GPIO_InitTypeDef GPIO_InitStruct;3 |0 g( F4 `4 t; S+ |8 f
if(hi2c->Instance==I2C1)
{- P( I; _" I9 j
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();7 g( d$ h' U, [" f
/**I2C1 GPIO Configuration % u' v$ ~) X7 s: @3 P( v
PB6 ------> I2C1_SCL2 ]$ ?* Q5 P3 |0 y. g2 k: |* V
PB7 ------> I2C1_SDA. j. v7 _0 o. g% D$ p2 R! y
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;2 D( n* _, l( c" Y h
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;8 O& M/ b2 U5 J2 F5 N# @& y
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}- m5 ]* w; B) B* c. z
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
. V. l" o! l( [3 Y
if(hi2c->Instance==I2C1)( |+ w& i1 d2 a+ E) V0 B7 L
{
/* Peripheral clock disable */( P8 H8 A) M8 l/ d2 {
__I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL' j C0 ~: p p& ~) o' a8 ?& Y
PB7 ------> I2C1_SDA% A/ w, ]& j+ j- U
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
& R$ D: I- ~. z0 h N, _
}
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------3 n) ]( \& O, b. t- g
usart.c T0 S" Z9 x4 W S
#include "usart.h"& S, U: _% n! x1 l+ J8 h# w( ]
#include "gpio.h"1 D+ w5 B. C: p4 F
#include "dma.h"* a/ H9 A! _2 |! ]% \6 z9 }
$ {4 P/ ]4 q! u) G G
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
0 Y4 G" q" [ d* Z `
UART_HandleTypeDef huart2;: p9 G/ ^2 j& {/ I e( h- h& d
DMA_HandleTypeDef hdma_usart2_rx;+ \! D' ?- Z6 ^" c
DMA_HandleTypeDef hdma_usart2_tx;1 \! q a, w4 b1 S% ^1 X8 J
0 | p1 H& Y1 n* V4 o! ^3 a* ]
/* USART2 init function */+ S) q+ h: }- q8 Q7 b8 U
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;+ l6 P6 R( K2 \$ P" u4 ^" G
huart2.Init.BaudRate = 9600;8 ^$ A) V$ ^* U! s. R/ r5 i
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;9 T/ T# I& J$ w* k0 e
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;4 a- r( M) G1 X# b6 e
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;* j6 z( k" P& L3 l b8 Y, P* k8 f
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;( n' m+ v6 L4 c( p6 B& O; Y0 U
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart2);
8 |7 q& O% C3 V( m) A0 `
}% o/ L' r" S5 L" N* t. o- X. U/ U
void HAL_UART_MspInit(UART_HandleTypeDef* huart)8 L: X6 t6 _* n: m" O: C" ]
{& C3 @/ A% n% ?( R
& S" o% a4 P. l( b
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{; Y* c+ h+ Q9 J% N1 B5 u1 I) w* ?- {3 u
/* Peripheral clock enable */
__USART2_CLK_ENABLE();8 m- S" y- \$ T: g* H* x
. N8 n8 o- W' P+ i! }" ^
/**USART2 GPIO Configuration ( o: Y; e" V3 L, T# b4 }
PA2 ------> USART2_TX2 Y A# ?, X" ?3 c+ X4 ~
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;- k' l+ q) D) @
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;/ C q" U* M/ [# W* L$ @ \$ M
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;( W# R" d) X# i9 I$ m
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;( Q- t, q% J) d u ^# C
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;2 W6 }7 l! e; O4 `
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;8 ~& a4 H$ A, c
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;, G/ |6 \5 K9 S4 g
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);+ `& _+ e+ G4 w! x
" U! o6 u- o5 y
/* Peripheral DMA init*// S( x7 f( l% }/ H8 x
hdma_usart2_rx.Instance = DMA1_Channel5;1 o, Q/ q! e1 s& J9 ?! ~
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;3 G) P5 ^! r5 w7 o/ y+ |$ E" U2 L
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;5 t8 K @" E6 |% _! X7 B
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;: a8 _, c8 N* ^7 }+ } E6 r5 ]/ Z
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;0 v I& V$ f' f; T; n. D) x
hdma_usart2_rx.Init.Mode = DMA_NORMAL;- M' ^1 t1 S1 J. w, U2 [) F
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);5 q. a \& D8 W4 b
0 r# c& M: k6 ]9 B$ x8 ]& x
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: d: x: Q1 h, V/ b1 O" U; b" Q' ]
hdma_usart2_tx.Instance = DMA1_Channel4;4 k, `9 o! Z/ H, ?) a. e2 _, T
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;6 B6 Y0 g( k+ @$ q* t$ d
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;# _( I* L( \! ^ X1 J
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;5 J0 K+ Q9 Y% s: }" Q( P
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- }: P; A8 M( o* Z8 |8 W1 }6 l
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);, `0 {6 p9 Z0 v/ T5 M& X5 t0 X
2 T) C& U$ H Z
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);1 a8 r$ E0 h$ o' B- Z
# x- l2 y* Y: x
}
}
, F# q4 V7 M: H3 r, X9 n6 E
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{. R# l% I( _+ _
if(huart->Instance==USART2)
{
/* Peripheral clock disable */5 m4 U5 l Z. g! e$ ]
__USART2_CLK_DISABLE();
4 P# T4 u' n2 n
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX& R& v/ A- y7 w: @$ [
*/4 ]. h4 T3 o7 m# @1 \; X
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); S0 |! z( |+ J7 T5 I1 ?; N
( z, s( p; z4 w o1 X$ ~
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(huart->hdmarx);. Q: g7 M2 \/ B" P
HAL_DMA_DeInit(huart->hdmatx);
}. L6 J% Z: {4 W
}5 }/ `% v) |7 l1 R/ M
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------& r6 d7 k6 {7 T) S; E& J, B
mpu6050.c% Y6 }& @* M1 @8 y5 h8 H
#include "stm32l0xx_hal.h"
#include "MPU6050.h"
//各坐标轴上静止偏差(重力,角速度)
int16_t offsetAccelX = -195;2 `, F8 K/ e8 R% ~. @8 p
int16_t offsetAccelY = 560;
int16_t offsetAccelZ = -169;
4 ?0 v4 n7 J0 p. V
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;
int16_t offsetGyroZ = 4;9 c2 H+ h1 t- T9 a6 `
+ D3 J6 N/ x/ x# u" A- o
extern I2C_HandleTypeDef hi2cx;
//**************************************6 R- E0 z$ m1 g) o" Z
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK) F8 q' W9 W4 ^( M
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}- F/ ?2 _( C% ~7 d6 A$ s" \9 H
}
}2 ` G5 V, ?' m. g" Q/ W
//**************************************
//从I2C设备读取一个字节数据% j* U& k; g- h
//**************************************7 \7 r5 r! Z( Y: A0 f$ Q
uint8_t Single_ReadI2C(uint8_t REG_Address)' _2 Q. v# q1 J8 p) ]
{ b0 p+ N. O/ N. O, ?( H8 C5 @
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)% g5 q+ ^" W+ N' D( U- M! l( P
{}
}
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)" z0 ~1 w. Q4 k& d% J4 p# a
{% k) J( O" D4 {5 X" l
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 n0 P6 O9 B% g
{}
}
return REG_data;
}0 ^0 k# q9 q- C% y! H% ^
//**************************************& B/ S0 O E7 @- z
//初始化MPU6050
//**************************************6 u5 m/ l7 Y- l
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态/ K' K8 C& a/ U- s! r
Single_WriteI2C(SMPLRT_DIV, 0x07);; @0 d F7 X2 M( |1 @; Q
Single_WriteI2C(CONFIG, 0x06);1 p+ }( J4 D$ _; D4 r8 g
Single_WriteI2C(GYRO_CONFIG, 0x18);
- R H, t/ N- b8 _+ h Z0 U
Single_WriteI2C(ACCEL_CONFIG, 0x01);+ Q7 O, D& z8 L9 L& y8 g
}
//**************************************) o+ H: \+ X( e2 K$ H: P. v
//合成数据( K& y. O7 D a% u! b( K8 a
//**************************************
int16_t GetMPUOutValue(uint8_t REG_Address)
{7 A/ d4 _: A9 X
int16_t result;* U# }# q: X: i' u; n
uint8_t H,L;- g. X9 L+ Z% ^* H& W8 b
H=Single_ReadI2C(REG_Address);0 F1 @. }" V1 ^6 t( x# p4 y2 A
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;
return result; //合成数据' [4 N/ }8 ^, B$ e* U" @3 v2 n
}
//**************************************) c$ `8 j& _6 Y6 H0 D j3 D8 m
//取某一轴上的加速度数据9 l+ b% D. o( k" X- N7 Z, ?
//**************************************
int16_t GetAccelValue(char axis)1 {, n: `: R. t6 g2 p; W
{
int16_t result = 0;
switch(axis)
{
case 'x':+ V3 e( M0 A* J8 L. x6 O0 W' y
case 'X':. W u$ ]% H# o3 @9 \8 n8 c
{) w! `! z! W' ^( R. {! h( p2 {
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
}/ ?9 S" x4 h! e
break;
case 'y':
case 'Y':2 Z& n9 E$ p+ t8 d r
{8 v& Y) H2 f! W8 i
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
}/ N- D* L: q x! c
break;/ s: ?* _7 J+ T6 o
case 'z':, B I' ] [. U8 ?
case 'Z':9 B/ b f- V1 [8 I
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}' e$ x2 V2 g* ~/ T% u
break;
}
return result;
}3 w3 }9 P9 c. B$ R" I# R" N7 w
//**************************************8 s2 S, c% D7 Z# i
//取某一轴上的角速度数据0 U) G2 q+ |7 N& ?
//**************************************3 p7 b) j$ ]. C( U6 _/ @! E' ]2 p
int16_t GetGyroValue(char axis)) E( ^, u! d' o
{* L. H2 E- g6 c* ~3 v" v' K& m
int16_t result = 0;) X. n* | l4 b6 {( m
switch(axis)
{8 v3 m6 c; j5 {4 P
case 'x':
case 'X':
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;2 B" E3 ]6 b/ V6 g/ E( y/ r" G! d
}4 k0 C7 ^, E' C: H4 f& @. V, [, I0 `. ?
break;9 o" j& m+ I' N# `( n
case 'y':2 a; c% m. \ r5 Y9 m; D6 u3 Y
case 'Y':6 m" R: F2 m- y. x; c5 a% ] s
{$ y& P, I! {) }. P# D; K' c
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;0 Y7 I" d3 z' X! e3 u3 I
}1 I, }; e. h; p% t4 d6 ]9 g* O
break; J7 s& C# [* s' U# ?
case 'z':0 |+ {1 m- ^6 v$ z/ v4 ]
case 'Z': D% _2 x2 \- B1 r* U s+ l
{ l y$ w! D* j: K1 W6 s" V+ o @
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
}- {* P( ~/ C0 h: y9 S% \. i
break;' P( w' A" d% p0 B6 d2 s6 N) I; o
}3 h* y( x5 z. m2 P9 n: n& B
return result;( L2 _. ~: N2 b& s
}
评分
查看全部评分
{6 I) K: B% c9 U
/* USER CODE BEGIN 1 */: L, _% q9 Q8 y0 {
/* USER CODE END 1 */
7 q% W. I- |/ I7 [$ r2 K
/* MCU Configuration----------------------------------------------------------*// a4 j) U, r% A# w
; W1 I- t ]9 a% C: m/ f
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();* j- A% {8 m) {/ h: f4 y4 a
/* Configure the system clock */
SystemClock_Config();! T I4 `& u- ^0 y
; ]7 u7 c& B9 |2 g- @9 k
/* System interrupt init*/" H% ^& W l3 [& m$ U
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */0 ^$ Z6 q7 e' X/ m; d
MX_GPIO_Init();6 S0 ? }! d4 V7 o0 i- Q: t
MX_DMA_Init();
MX_I2C1_Init();* g+ |. D- E8 Z( ~4 \
MX_TIM2_Init();
MX_USART2_UART_Init();
InitMPU6050();
' n2 L5 j8 ~$ s: d
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
HAL_TIM_Base_Start_IT(&htim2);' ~5 j1 H, ]0 P6 P$ U8 Z+ {& B, N
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
/* Infinite loop */% r2 c( k% m+ E3 |1 |
while (1)" y3 e Y9 B0 H3 T8 @# Q" q L
{$ f; [2 V. W' B, Q4 U _
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
VisualScopeAngleOutput();
HAL_Delay(100);# k% k# E: U, Q8 j- r9 Y9 V! @3 [8 E: c
}6 w: [# R; q! R! B
/* USER CODE END 3 */4 _# q# {2 V' Y! z! v& f h
}
% x1 ]4 ~1 r, h* C
/** System Clock Configuration* X2 V* i* _, z( ~4 R7 S9 b
*/
void SystemClock_Config(void)& G* ^- U' d5 [* O7 ~5 ~* g
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitTypeDef RCC_OscInitStruct;
, m( J2 j3 ^. U4 S; d
__PWR_CLK_ENABLE();. ^' X: F; S5 I1 c% T* r
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);' w; [1 D5 x7 Q7 u4 ?
9 y% q' \) \4 p" j, ? C( M
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;. @* p' p7 J& ~
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;3 n$ |+ P5 e: g2 R
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;; w! d, y0 u5 G0 l- I8 Y
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;; c8 a* K9 Q0 Y' P/ [% w! D# a2 n
HAL_RCC_OscConfig(&RCC_OscInitStruct);0 B$ k* P, F$ Q# P& z1 |3 F
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;' H( w v4 i6 G; ^9 y
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);
2 X8 ~4 u/ x3 W: A3 d6 {2 C5 x
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;: |* V- Q8 V+ U; }
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;" \; i. _* K0 n/ x7 s" Q
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
__SYSCFG_CLK_ENABLE();
}% I. q m5 E/ ], w* F, K; E4 b
& U+ H1 S4 Y$ }- k. w2 [- |
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)- s' T0 r" D: e+ K9 C/ h
{# {: Y2 g3 ]1 p
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);9 ^$ q4 U: b: h, l* ?
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{; T# {: C& F8 v
0 P: n* [2 q1 p4 z9 v
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)- A! w4 T7 O- Y( v
{
int32_t GyroValue;
Calc_AngleAccel();% M! G9 M0 d9 s3 v8 }' q
GyroValue = Calc_AngleGyro();$ R- O5 u4 ]( [. |9 X. H! L) h3 V0 i
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。