拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c$ N5 K! Q' K | #include "stm32l0xx_hal.h"3 A' H, e/ z8 z #include "dma.h" #include "i2c.h"& C- v8 ?( h5 j6 G #include "tim.h"/ ~ n% d. n8 `: ?2 w+ G #include "usart.h"" m& `5 y" a1 i3 X, |1 r; i! [ #include "gpio.h"8 ]& z* F' d$ D4 Z5 f5 S7 f* r0 l6 R; y #include "mpu6050.h" #include "visualscope.h"9 {7 Y' i* H0 k& J! W% v ! L8 _% p* z6 D/ x' T* U2 c #include <string.h> #include <math.h>" \9 C" y/ D8 q8 p9 { ! ^: X! ]( p* L4 A4 `, F /* Private variables ---------------------------------------------------------*/4 D( Z7 a! S! d. ^6 ` #define RXSIZE 8+ i' r* J U0 n5 e) E #define TXSIZE 8) N! a/ |7 `5 h+ s uint8_t rxBuffer[RXSIZE];( v* i& f$ l6 l' U& f4 ]& |$ h uint8_t txBuffer[TXSIZE];4 z! [7 y3 B2 D4 }3 r) T * U- B& p, B2 M% R1 G% n float Angle_accel = 0;# h" _6 H) v4 h6 U' Q( s, e; K' p8 o% m- R float Angle_gyro = 0;4 X8 S) B8 j+ b( Z' o float Angle_comp = 0; uint8_t outAngleData[10];7 F$ B( {% U2 A7 P /* USER CODE BEGIN 0 */9 X9 N3 m$ W, u2 N 8 Z& \1 {# c8 L2 @ /*---------------------------------------------------------------------------------------------------------*/6 Z+ A* g2 r! Z6 v% K4 o /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/" m1 ~0 [, ]0 Q( h- Z7 ~4 M int32_t Calc_AngleAccel()3 s+ _/ \8 ~0 G! _) @6 o2 {: n9 z { int32_t value = 0; 3 X. V% V6 u- F: P6 E" s$ \ value = GetAccelValue('x');2 D9 p+ q/ w; v# w3 P" Q* _' a1 m0 ~ if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296);9 N+ N% [0 S, L4 c7 _ else Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);7 O$ `8 H: L, w. u return value; }# O: Z1 O0 x: J8 d - u8 e9 }/ W, X1 y /*---------------------------------------------------------------------------------------------------------*/ /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleGyro() { int32_t value = 0;$ C( k9 C4 m Z! a' b value = GetGyroValue('y'); Angle_gyro += (value / 16.384 * 0.01); - D! s, `( F# t3 s! C return value; }' \3 K- S+ K( S# h + V+ v1 e, {5 m% T /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */ /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro) {7 G/ d4 S) B7 B& R K3 b Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;9 ]' [0 u: |2 H$ ? Y+ d return Angle_comp;) F3 f# T( A0 R7 x3 D$ K5 O }# h8 t2 l j. `6 r& ?. f% F /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */ /*---------------------------------------------------------------------------------------------------------*/' t) o" |: ^3 n0 V/ q/ @; V void VisualScopeAngleOutput()$ L) D! `' j$ j \ { int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;( E0 @, R. `, A( c1 q uint16_t crcValue; # n" H$ @1 W9 }' a AngleValue_Accel = ceil(Angle_accel * 10 -0.5);( v4 |. U1 V4 R2 N AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);; f( e" ]9 n( ]: |4 Z6 u AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); outAngleData[0] = AngleValue_Accel & 0xFF;0 k& X& |( f3 j! q0 k1 w outAngleData[1] = AngleValue_Accel >> 8; outAngleData[2] = AngleValue_Gyro & 0xFF; outAngleData[3] = AngleValue_Gyro >> 8; outAngleData[4] = AngleValue_Comp & 0xFF;6 c, T% k* ^% k+ M( ^ outAngleData[5] = AngleValue_Comp >> 8; //计算CRC( V" K4 O: }% c# q) s crcValue = CRC_CHECK(outAngleData,8); outAngleData[8] = crcValue & 0xFF;+ ?. }8 e0 Q% @$ Z R+ e; F$ f outAngleData[9] = crcValue >> 8;9 s- h! |) L0 m" M8 x* N1 t //发送至上位机7 v/ L6 Y& C5 ~) t3 J( t* c HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData)); } /* USER CODE END 0 */9 S# U5 Q9 z( F+ ^ ) ~2 t( {5 Y4 D1 R& N& |- H% q /* Private function prototypes -----------------------------------------------*/# q: [0 g2 R" A0 R void SystemClock_Config(void); / ]$ i& S& X Z* E; E- D 硬件连接图: 波形图:6 E" J' c) f; z# v' E& G 最后加一个视频:3 ?' \" c% f4 e i STM32L053 演示/ z* T" A6 j3 E" D' {0 o$ R5 w |
意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS
【STM32MP135-DK】裸机移植shell
【STM32MP13DK】 在Linux主机上交叉编译一个Hello Word应用
STM32MP135F-DK 开箱&开发环境搭建&硬件设计分析
意法半导体在意大利建SiC整合制造厂
轻松地实现ClassB在STM32CubeIDE上的移植
ST历史小知识(6)- 与世界共同塑造美好明天
ST历史小知识(5)- SiC衬底进一步发展
ST历史小知识(4)- 投资未来
ST历史小知识(3) - 布局新兴半导体工艺
#include "i2c.h"
#include "gpio.h"2 W6 s. X% g3 z7 L1 U
/* USER CODE BEGIN 0 */
/ m3 r, e* @! m. o0 Z/ E
/* USER CODE END 0 */9 f/ ~- S7 o- ]. ?" X
' s) B; b0 S; e4 U5 d
I2C_HandleTypeDef hi2cx;
- Q% M) S: L/ {) r) L; Z
/* I2C1 init function */* [# Z0 |# _6 |! \4 ]$ ~4 Z
void MX_I2C1_Init(void)
{# J4 u0 I- a7 ^- E a) A8 H
hi2cx.Instance = I2C1;
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0;3 }8 W2 S/ N* L
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;, }) ?8 I, ~( C8 f1 O
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;/ h! W! v$ m' C" F( |. a5 H
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);( v; n* r8 `, l5 y/ M& l! d
/**Configure Analogue filter! ? c& A6 g3 F7 ?& G4 N! N
*/' X- p( K/ ` e _+ M! z6 d
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED); s) x ?7 @8 N4 E
( ~$ m# y2 h0 p& c# P. Z
} b7 q( v% k0 U2 i9 M, f7 v
$ V3 h- i/ T' {5 J
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)5 N/ S5 @" q6 q* |$ L
{% R2 q% u7 `) }7 g- Q+ @4 y# J
GPIO_InitTypeDef GPIO_InitStruct;5 T, l5 q" K9 y3 ]1 Q1 z
if(hi2c->Instance==I2C1)* E- H; B. Q6 F2 H7 a1 b; B
{
/* Peripheral clock enable */; g) e$ T) a0 a# O& G1 T
__I2C1_CLK_ENABLE();
% L5 m+ j3 N( Z" ]
/**I2C1 GPIO Configuration 4 {- y7 m9 \ l% ^: y
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA( |7 j; P6 c) S, K* A5 w
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;+ f, r4 s- l" p, L
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;) r M" R( r b7 d$ U! \
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
5 i/ b- S% x1 v: T5 B: H. g
}
}: K9 l7 ^! Y/ G3 H
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{0 d$ I5 t. D- b+ T
/* Peripheral clock disable */6 @5 u v# L1 s1 |1 I
__I2C1_CLK_DISABLE();' H2 K5 f7 N5 F& }5 T
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/; `" R- ~, R( g, f: @
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
9 ~8 p6 z. I8 ] \
}8 ~ n9 {/ K/ o, l( Z
}; u7 }9 n( w- r5 p D3 C) P: M
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------6 ^9 |% }* K8 }, t0 _: @. S
usart.c$ \9 z* ^8 a9 u' U8 u7 H: F
#include "usart.h"% Q5 X% P& R+ a
0 N7 [5 }+ ?( G. g4 Y
#include "gpio.h"1 ]( B$ g& h3 u- ^+ O
#include "dma.h"
/* USER CODE BEGIN 0 */
5 _9 X4 ^4 U9 f4 V, {. S5 k5 r
/* USER CODE END 0 */
+ V- E1 E7 P. N; x. J
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;7 ?9 B* m& r' R3 }* o6 @
DMA_HandleTypeDef hdma_usart2_tx;) Y2 e. F$ A& Q @6 T1 |" r
7 P& V# e( d. s6 b2 E2 G9 s0 W* h
/* USART2 init function */
2 A& \) @3 ?- @+ L. A% U
void MX_USART2_UART_Init(void)
{ A1 @" W1 I# _7 ^4 |
huart2.Instance = USART2;$ ?+ c+ ]3 @: p/ z
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;) q) Z9 P8 y4 U2 A1 K4 [
huart2.Init.Parity = UART_PARITY_NONE;, P6 w m# p2 U+ J
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;* U0 i7 U" a; F6 F9 {( q2 y, ?
huart2.Init.OverSampling = UART_OVERSAMPLING_16;) Q& @% G4 W0 c+ {
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;8 W. h6 v8 L6 j- j/ K- k
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart2);
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
8 t1 B$ H* M' e8 d
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{& T2 Y0 N: R# U0 v5 N# g5 c
/* Peripheral clock enable */; |7 {; [ D) e+ l E
__USART2_CLK_ENABLE();
, [; t$ a3 u! v$ U( J! x
/**USART2 GPIO Configuration 0 q _. \/ N2 d3 m, s6 c2 @# {7 S( h
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;* \; f7 R. w1 U n: s
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;- l/ J; J, t" q1 j* |
GPIO_InitStruct.Pull = GPIO_NOPULL;$ R& U8 V! I; ~3 R) _
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;6 Y6 S/ `9 y1 z( |" Y( [
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;! {4 S1 ?5 S) P
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;* U' f) v. m6 k, ]8 ~4 |
GPIO_InitStruct.Pull = GPIO_NOPULL; |/ I# V/ Q) j" Z! h
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;" M- g/ P2 }- m6 y7 n0 G+ v
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;% A) n7 ?/ Z/ m
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);. K/ s. P4 \' S* \8 [. Z
; J3 v7 c( q/ T c4 K
/* Peripheral DMA init*/6 p+ v; T( C B4 b- R* \! d
hdma_usart2_rx.Instance = DMA1_Channel5;
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;6 V7 d( B; H& E, a* `% B
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;5 r# K, G. s; D0 _5 \( Z& q
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;8 g% I$ g+ Z" \$ S) t3 E+ G4 P: c
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;9 v+ q; @3 C: b# c
hdma_usart2_rx.Init.Mode = DMA_NORMAL;' o; _) E/ ^! M: l
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;, _& D3 a, H! e, q2 a
HAL_DMA_Init(&hdma_usart2_rx);6 H% m4 {5 U4 h! o& E! ^
. b, b' ^! H* n% f' q5 u
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);& w; O# w! N( t/ y. a" u: @6 z3 W
- d8 d- a! _5 J6 O- K$ t8 }
hdma_usart2_tx.Instance = DMA1_Channel4; X, n8 f9 v6 L
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;) S a" N- _0 t" F. x. k' ~
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;; R. K5 F: F5 Y; `# \' J
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- J# d1 ^# d) x# e' y; ^9 V
hdma_usart2_tx.Init.Mode = DMA_NORMAL;( ^% Q% B3 `- J
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);
2 s+ O% z! @% u; Z5 e/ A
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);" @- Y v$ w$ s% g
$ u d5 l8 m( X! }
}( x0 v8 s/ t& q1 N. F# @+ x
}
v8 d! u5 y2 T
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)! h+ [: u [+ q. f
{7 b z4 _- e7 Y0 M p. G) E5 b: l
if(huart->Instance==USART2)
{) n4 u4 C3 M5 O. l+ b
/* Peripheral clock disable */
__USART2_CLK_DISABLE();
, ^6 T5 e. G3 n1 G* c) J
/**USART2 GPIO Configuration ; n" B' z8 Q4 I
PA2 ------> USART2_TX6 ` K1 [7 A& A: w$ Q
PA3 ------> USART2_RX
*/ ~ J1 E" W% g! r" e
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);9 j0 K# J4 ^. @5 h
/ o# l. m) c- ~: N
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(huart->hdmarx);
HAL_DMA_DeInit(huart->hdmatx);
}
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------- J6 l* s0 f% d3 c
mpu6050.c4 j7 c0 X0 k$ b* O& F2 t! x
#include "stm32l0xx_hal.h" ~6 G) z$ ~: ?
#include "MPU6050.h"
& ~( u# m! B) p1 R2 d* O* ?
//各坐标轴上静止偏差(重力,角速度)
int16_t offsetAccelX = -195;3 Y8 o/ D6 i( E1 A
int16_t offsetAccelY = 560;; b: ~0 l' }6 s4 I
int16_t offsetAccelZ = -169;7 ^6 y o' \* A' F9 G
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;
int16_t offsetGyroZ = 4;
0 S7 a2 u: T. @1 k% S; T
extern I2C_HandleTypeDef hi2cx;' X5 Y4 K2 G4 B- a8 c1 h
7 q( ^# T( Z% M% _, S6 Y& T
//**************************************
//向I2C设备写入一个字节数据7 X% H$ f: {; O$ D& `
//**************************************
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{- E2 f6 h* y/ \
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
{* x Z. a1 j- z0 z( y
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)1 N4 D; r' N7 _/ a; I: |6 Q* K
{}6 z# g; g2 l, S& i, g
}
}
//**************************************4 c9 d. U/ T; L7 ^
//从I2C设备读取一个字节数据& j- G4 g+ D" ~* F7 G; [) Y, I
//**************************************, c4 X! ?' n$ M/ ~4 x R$ L
uint8_t Single_ReadI2C(uint8_t REG_Address)9 U5 i) o' \2 j; S5 K' c/ u/ t( s
{" D. ?# p( V* B- v
uint8_t REG_data;0 K n' `* O0 M, Y/ [9 ^
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
{8 f5 |' Y& C. q1 h$ q4 Z
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}
$ i9 ^2 ] N7 u
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)7 U2 W. D% d2 T) l
{$ I% a& W ]' F
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}
return REG_data;
}2 Z q3 O) w g
//**************************************
//初始化MPU6050
//**************************************" q$ ~9 }/ j4 E
void InitMPU6050()
{# e9 q3 ]5 d8 a" ~$ w$ R+ v
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_DIV, 0x07);
" \/ R# ]1 h o3 g
Single_WriteI2C(CONFIG, 0x06);
# F V& i; v; {, ^; R
Single_WriteI2C(GYRO_CONFIG, 0x18);
1 A+ A! j. @* s& J% m+ |; d- v) A
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************3 b* x- h3 ?2 Z3 d
//合成数据0 @, F2 x/ D7 z
//**************************************# z0 |! V; F, J ?, y3 I: Q$ w% S
int16_t GetMPUOutValue(uint8_t REG_Address), C# |# A: h. N2 k) F9 d
{
int16_t result;; d/ H' x4 K% r2 G
uint8_t H,L;) O; x6 A: b$ Y3 M
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);) J D5 s0 s4 Z+ _2 ~2 D* z
result = (H<<8)+L;
return result; //合成数据& e8 L/ e9 V" @7 F: b5 T
}7 x2 k3 }; K5 a. r" T9 A7 {! {
! s7 d3 p8 {% {4 V& H
//**************************************; p+ I2 w% l7 a; N6 ~0 i
//取某一轴上的加速度数据: N0 G; e0 D. k3 q/ d# w& f
//**************************************% ?2 p- ^6 q4 ?% v6 p) l: c% K$ R
int16_t GetAccelValue(char axis)* p1 ~# ~+ A; N1 k5 t
{
int16_t result = 0;
switch(axis)
{
case 'x':7 C1 {9 L& Q; }+ i, x; u5 n2 t
case 'X':5 A5 P0 X6 g" {9 C1 s0 x X" w/ {
{- m$ K* F; n0 ?$ _1 Q) ~
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;) ?+ R4 `+ l9 l' M' B
}# T2 M O" e5 s/ B
break;& z5 T6 Y' L9 } w6 a) Q' H/ _
case 'y':
case 'Y':% z! h5 M/ H1 P. a1 G- O
{ s- e, i# U+ o8 |3 Z* a9 O' l
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;* Z& g& @& Y* i6 Q. M
}5 L! t6 K* H$ ]( @' ?
break;
case 'z':
case 'Z':% [; S$ M' W f9 R9 f% M
{/ k" n, f; K q' Y) i
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;; |& q. t8 y. g2 V( W- P5 y
}
break;; Y* K. m" a+ A+ j4 f
}$ ]4 B4 t( }5 A6 F7 d- ]
return result;
}
//**************************************
//取某一轴上的角速度数据! @# t& y* c" ?; v
//**************************************
int16_t GetGyroValue(char axis)
{* M' U2 t" L1 d9 P' n) j% m
int16_t result = 0;% @) G Z4 }+ L
switch(axis)
{! ]5 r% _1 ]) t3 U2 r# \* _
case 'x':
case 'X':0 I: ]0 N' z! z5 N0 O1 e
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;% Z- b9 x. L, [; U" K
}' Y6 e* S+ x: w5 X& `) j0 ?
break;
case 'y':
case 'Y':
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
}8 z7 C# W6 X7 u+ U) A: c& J* \
break;9 u/ ?) h5 L; F7 K: F7 l- U* E
case 'z':% o( b: |" j# A& q9 a2 {+ I! R. r
case 'Z':
{5 r5 K! v; u6 U& J
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;# {( @, T# h( l7 B& v* l
}9 a+ {2 u& e3 t- F4 @
break;6 z3 j3 s4 O0 C2 L+ ]9 Y
}
return result;
}
评分
查看全部评分
{
) z9 f& f. M! d/ j: _( ~- r0 g* T; R
/* USER CODE BEGIN 1 */' I* E$ {9 z+ H* n+ n
+ S w$ [8 ~1 x P8 D9 r; [; M
/* USER CODE END 1 */
( P9 A; \" Q6 T0 q
/* MCU Configuration----------------------------------------------------------*/
5 H n. o* m) x/ E1 B9 u
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();+ S) j) K, u! w; h
& D. J7 ^8 ?0 q/ X+ A
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);2 M, ?6 Z8 q" Q9 x$ T: j( E5 r! g% x
0 @" q/ ~% Z3 \/ S7 |
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();+ w1 l- C' F' c+ @
MX_I2C1_Init();8 t* V: g _4 F! }. V
MX_TIM2_Init();# A, u$ E+ o" z0 w) Z
MX_USART2_UART_Init();
InitMPU6050();
/* USER CODE BEGIN 2 */' `2 v% f; \$ @
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);1 S% _9 F t* U+ X2 P" H/ ~ F! m
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */: @8 e: |( ]0 K9 Z5 S. u
# w: c" q) u% q% i( }
/* USER CODE BEGIN 3 */
/* Infinite loop */8 e @, W1 i: i& {$ g" Z ]7 r/ m4 _
while (1)5 u5 c2 R3 W( Q
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
VisualScopeAngleOutput();
HAL_Delay(100);' r: x# d0 |8 Z' n# y4 o5 f q! S
}8 k) j6 `2 \& J1 s5 z9 V* M) L" O7 I
/* USER CODE END 3 */2 R+ g9 w: T+ C' C
}0 ?; ?4 u/ Y8 ]0 ] m2 E
/** System Clock Configuration
*/( S& R; |+ |# K% Y5 A1 A3 P
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;, l( J( {3 p3 `
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitTypeDef RCC_OscInitStruct;
8 ^; T! e' V: ?) L5 C" w6 T7 c) J6 S, _
__PWR_CLK_ENABLE();
6 a- f$ t4 N% ^' R! v
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
0 o: t' G4 K. b: i Z) f$ h5 m2 L2 s
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;- b+ `$ E; i2 B" t- [: x. v
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;/ I$ ]6 X% F F1 H) b" g
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;- E9 A X6 |5 |- [ }
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;. Q7 k5 Q" K+ W6 I) G: W
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
HAL_RCC_OscConfig(&RCC_OscInitStruct);/ ~3 a* i* u Z* v6 Q# [
b. y+ _6 u% f+ d4 E
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;6 ], R7 Q" V+ L
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;3 N! z& Q+ i. L
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);( X- N/ x6 j1 L
0 U" F2 W; q# f9 }
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;( J( D. J' P+ J9 A H% t' }5 q
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);( q$ T' e+ J9 x
__SYSCFG_CLK_ENABLE();) _* o, M8 v6 h! T7 y9 g. W' J
}, w( B, g& l7 D+ m! u* [
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)8 o0 b5 |+ y- c+ J- f
{
if(huart->Instance == USART2)) Z* Z% q9 E! U! X$ `3 W# R) p
{
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);6 t0 `% h5 Y6 l6 n
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE); [' t2 Z6 |$ {* y2 t0 u! h
}
}' n/ X0 |: E+ ~4 G6 @6 w
# _' p0 G% u: @6 \ i8 D
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)* @: O0 p) {; k3 g7 O
{
- ]. I6 g# B" S+ G% L. w0 G
}. W0 z( }6 X ]! x
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)+ o) k x1 i: L) N) v! k
{
int32_t GyroValue;( x0 f; A, F3 I% M% @
Calc_AngleAccel();! ^& P: L6 a) t& Y3 a w" ~4 e/ W
GyroValue = Calc_AngleGyro();/ t& i( Y6 V8 f
ComplementFilter(GyroValue);& X7 I/ j9 U6 A; ]; h4 @9 U, Z
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。