拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------3 x, B; ]6 p. b3 \6 `3 p main.c #include "stm32l0xx_hal.h" #include "dma.h" #include "i2c.h"6 i$ Q! ^$ V1 g' P #include "tim.h"9 I& }5 l6 T5 N9 d+ [ #include "usart.h"0 J# Y. r; d7 M7 m! \. v8 n #include "gpio.h"$ v- j2 K" ]( }4 j3 |3 E- v- T& ^- A #include "mpu6050.h" #include "visualscope.h"6 w! g! E8 o+ t; W9 c ' z& H: T2 R2 T9 i- K #include <string.h> #include <math.h>, P- w, _3 k' N$ Y! a1 c 7 h' n' J6 J a) M, k l$ e/ ^& J /* Private variables ---------------------------------------------------------*/- \8 R! `7 J8 I. J" e5 @ #define RXSIZE 81 V$ l8 q. n* M1 g #define TXSIZE 83 a+ `7 B- ~6 o1 Q" @ uint8_t rxBuffer[RXSIZE];# Q" L5 Y! Q, {/ ` uint8_t txBuffer[TXSIZE];3 z( f4 O$ ^9 m* H# d float Angle_accel = 0;3 A1 d3 I- ]( B/ W& t float Angle_gyro = 0; float Angle_comp = 0;" I0 M1 j- x T6 | uint8_t outAngleData[10]; Z2 x" [% C M9 p /* USER CODE BEGIN 0 */& {; z/ F* c& h6 B7 S , d8 U0 x+ K" s% z7 V: Y /*---------------------------------------------------------------------------------------------------------*/& l6 q/ X9 I/ `$ V/ x2 s /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel() { int32_t value = 0; 6 S5 \1 |: Q) W( ?2 |3 A8 J value = GetAccelValue('x');& F) e# p/ _5 ]& w8 ^; w1 U) @ if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296); else9 Z$ N$ t, ?- Z0 @- h0 ?; Q Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); " H R. g& y* \7 M: N return value; }( `1 y N' {) C5 k9 b & G& |, S K/ Q: G# c /*---------------------------------------------------------------------------------------------------------*/: |6 Z. y0 h9 R! t) [. _( x /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/9 F4 A6 J( t% m% I- R2 T; n int32_t Calc_AngleGyro() { int32_t value = 0; 1 @' m! { _2 R0 `# i, L0 k. C! C value = GetGyroValue('y');, J' l5 O/ B, P6 l2 }; v Angle_gyro += (value / 16.384 * 0.01); 4 H- v% T- n. a, ] return value;7 `2 A3 _8 A% q4 Q: I }. _5 s2 C% H6 F `6 W- B8 _$ A /*---------------------------------------------------------------------------------------------------------*/% m9 a' c& J7 s* X" D. e' z9 v /* 互补滤波求角度 */1 [0 |$ J7 L2 M. \" v0 A, | /*---------------------------------------------------------------------------------------------------------*/3 E! O+ I4 X" |6 j2 q& d float ComplementFilter(int32_t simpleGyro) { Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;% q) g; P' O7 | $ a6 F* s2 D2 Y( P return Angle_comp;- G7 g5 B, e1 w- n, L. N! R% l } ) k! f. d; |1 j0 ~6 |$ b N /*---------------------------------------------------------------------------------------------------------*/) U: x$ S/ ~& R3 r3 f /* 输出角度至上位机 */. B3 |+ y2 P7 w: |. i# z |0 p /*---------------------------------------------------------------------------------------------------------*/ void VisualScopeAngleOutput()9 e' c$ ?9 _8 P$ [ {2 C. Y3 V; {6 f, S& E( x7 A int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;& |2 X! a8 _6 H, d3 C& O( T5 c( H7 v uint16_t crcValue; AngleValue_Accel = ceil(Angle_accel * 10 -0.5); AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5); AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); ) o- S' y) J& I+ ~/ A6 A" g- t outAngleData[0] = AngleValue_Accel & 0xFF;! C8 V; n% J2 Y1 ?! E" L: A outAngleData[1] = AngleValue_Accel >> 8;: W+ e! ^( n3 k7 D outAngleData[2] = AngleValue_Gyro & 0xFF; outAngleData[3] = AngleValue_Gyro >> 8; outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8;0 S6 D6 e3 t9 v1 I. V6 ], f7 |3 F //计算CRC crcValue = CRC_CHECK(outAngleData,8);- V8 Y. \+ Y- P# c+ H+ v% O- m outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8;4 i% Y. p4 r8 l& \ //发送至上位机1 Z o2 d9 q6 z# ?1 r) J' l0 d HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));5 y8 Y: J2 Q. I" ~# L } /* USER CODE END 0 */9 W- a% }+ Y1 R* L) I/ C /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void);9 @& ]- B' r; W* J2 d0 e 硬件连接图: 波形图:$ \* z( z6 Z& {0 G) l' C 最后加一个视频: STM32L053 演示: i$ y8 ~) F1 {/ N+ F |
意法半导体最具性价比、速度最快的单核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"1 G$ ?! f# U4 p
#include "gpio.h"
" C+ L+ ~. s$ q: Q, K6 Q
/* USER CODE BEGIN 0 */- f: l* z9 V6 T U' x6 ]
/* USER CODE END 0 */, A* }+ E: H- {) K9 n* j
, l) Q9 q) L/ O) I l
I2C_HandleTypeDef hi2cx;
/* I2C1 init function */
void MX_I2C1_Init(void)6 \5 L( F% z8 h# a7 H6 {4 p. P
{
hi2cx.Instance = I2C1;
hi2cx.Init.Timing = 0x20D22930;" I' g' F. L1 I1 ^
hi2cx.Init.OwnAddress1 = 0;
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;& a7 \ ]7 J0 t' y' L% [
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;" {. Q9 }# b0 i8 q6 s# r y+ f
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;, s2 d- r& R/ k5 A
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;8 B0 e" y }! \% Y4 I, x
HAL_I2C_Init(&hi2cx);
1 ?- E. i5 s, U, D- u7 g O
/**Configure Analogue filter
*/$ n1 y7 Z' o& F* v' h+ E
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
3 ^5 H9 s) R+ x6 p2 {5 w* B+ _
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
# ?# ]# f7 ^: d( r
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA2 ~% r# Y5 g1 R& \/ V7 v% f' f* ~
*/9 ]6 H3 @, V; l- ]& e% J9 y7 L# R
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;4 L0 L& S! Y6 e4 Y& v/ G: D
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;; U9 i4 i+ g Y5 e1 U6 N
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;" T4 _* @2 P" G) J
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;# s+ C f9 m5 T$ o- [7 e/ Z
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);# Z) Q9 {: W* d8 j
}" z5 ?4 S1 @* ]' @" g. O/ ^
}! L5 f0 e& k, _
u6 f( t8 O' W# |! x
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* Peripheral clock disable */
__I2C1_CLK_DISABLE();% [2 V, s) k: m7 b
/**I2C1 GPIO Configuration % A( Z, W7 b+ d/ `1 c2 d0 U3 x4 }
PB6 ------> I2C1_SCL9 E. `6 A. y% u# _
PB7 ------> I2C1_SDA
*/; J' z% j8 l3 f' q2 {. E h
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
* K6 l2 V9 O! l7 m, a& B; y: X
}
}& ?' p' w4 m) H+ P
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------- B: t) P! d$ L2 y$ J+ l
usart.c D$ o0 C& g4 F& O$ S
#include "usart.h"
#include "gpio.h"- G1 ?2 ^2 H3 I5 n
#include "dma.h"$ P I6 E9 g5 W8 G/ I S6 v9 ] u
/* USER CODE BEGIN 0 */6 F, Q3 e, b, I% \; T% q1 x
/* USER CODE END 0 */
6 }1 Z! {+ b4 s$ [. s
UART_HandleTypeDef huart2;* F& \, O+ p: ]6 R
DMA_HandleTypeDef hdma_usart2_rx;1 M( w0 f* f r {+ j* F
DMA_HandleTypeDef hdma_usart2_tx;) `" {* O# C- z* f& d7 P* q; k) C
/* USART2 init function */
3 q5 {7 z4 C% ~+ I$ r5 Q
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;' D' u2 d5 `" A5 _7 e) z! w
huart2.Init.WordLength = UART_WORDLENGTH_8B;# _2 j. W; C' r3 Q3 V( [$ I
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;2 C/ N! T F- |4 V
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;4 g. i2 M9 L( M1 o+ l4 g
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;3 I- L4 [- x# }$ ^6 T( k
HAL_UART_Init(&huart2);
}% T9 H! t" H- ~1 r& f/ _
; _0 \( {& }: L
void HAL_UART_MspInit(UART_HandleTypeDef* huart)1 c2 s2 F8 d6 N9 F, b5 f* K
{+ i W5 T! s+ R
GPIO_InitTypeDef GPIO_InitStruct;& P0 C4 ~& m7 W3 e9 k0 I9 W
if(huart->Instance==USART2)
{+ k( i, G/ Q7 W8 r# U
/* Peripheral clock enable */
__USART2_CLK_ENABLE();0 J' h' \7 a/ K ^9 N! h* o# g& V; X4 K
& J9 ~, e6 a R7 @( b/ ?7 E+ q
/**USART2 GPIO Configuration 4 b u. P2 l" E4 S j' a4 h+ }# G
PA2 ------> USART2_TX
PA3 ------> USART2_RX" ^" I1 x2 t# ^
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;* C/ Q$ A2 l4 [0 O8 ?0 w# Z: T
GPIO_InitStruct.Pull = GPIO_NOPULL;8 d; F0 W, ^/ E8 c
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; W! b2 w/ w% K2 e0 c9 ?2 k
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
0 F6 y" I: m/ x" g# ^
GPIO_InitStruct.Pin = GPIO_PIN_3;6 A* n \( V" y( R6 k) I
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;) i) l2 R; w9 d9 u; K. Y- B8 e0 o( i
GPIO_InitStruct.Pull = GPIO_NOPULL;3 `) V: F8 C5 w' D9 o) c8 L
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;3 ~. E* ^& r3 Z/ o8 d
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;' @. p, v+ W/ }1 \. d) m4 w
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_usart2_rx.Instance = DMA1_Channel5;, D; d X: }: n# v$ H7 z. z
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;) B4 R0 W5 v% z3 J
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;! @: y; Q0 Y H% l$ s$ ^7 F
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; U+ f4 X% r+ @( ^6 p8 M
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;/ D/ F) N( ~. _ g
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);1 ^ Y4 Z- R7 d5 o6 ^. Y
7 V) p6 _- T2 g# q- p9 P O
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: U) P. U0 m2 V9 U, A
; r8 f1 k6 ]* o
hdma_usart2_tx.Instance = DMA1_Channel4;/ h! D: U; s0 R* M4 r
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;) E% F" Z' k! Z9 R7 D4 g, t
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;% @- K' l. H8 ?* O7 F
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;! h7 h9 M" l9 p, u" Z2 y. W7 {- g
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;+ y: X% d! D7 J: L- D- n
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);+ p- l4 U2 g7 f) H* z3 a! x* u6 f6 M1 r( C
}# \9 E* F. C8 C7 _7 H
}: D$ c/ o9 K1 X+ l% _' t
+ @8 [( O9 {1 l$ s# m
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{3 ]% w! d( i: K* q h
/ I1 @4 j: T% P5 H N2 n$ e
if(huart->Instance==USART2)$ |; F# B* H _/ Q/ N! U {
{ u2 c; k, o& \9 `; Y, p
/* Peripheral clock disable */& D; l9 l& c3 r& ^8 I9 z, v0 Y
__USART2_CLK_DISABLE();
/**USART2 GPIO Configuration : C% s4 i6 P6 p) d
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/7 J' S; {0 @3 x* z' h% h
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
4 I; U T6 E! i' m* Q8 [5 ~) [
/* Peripheral DMA DeInit*/, ?9 ~7 E+ D+ V/ @4 s( }# q
HAL_DMA_DeInit(huart->hdmarx);
HAL_DMA_DeInit(huart->hdmatx); A V# U/ ~: L( T# B9 q6 ?: _2 h
}7 F' S. b% w2 r. d$ d/ ~2 X5 T
}" |+ B7 Y- }* o, g0 ^
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
mpu6050.c
#include "stm32l0xx_hal.h"8 V3 Q- s+ x1 X0 j4 T
#include "MPU6050.h"
: Z r, b, L) X4 g& y: s. _9 G
//各坐标轴上静止偏差(重力,角速度)2 Z v/ A' F2 F' M E! L+ ]& d1 r
int16_t offsetAccelX = -195;; }/ D6 d, t0 K2 e& ~
int16_t offsetAccelY = 560;, }0 h6 F+ ? p. |" E6 F2 ~. J
int16_t offsetAccelZ = -169;
9 U+ Y- r, H& j9 s4 \0 z
int16_t offsetGyroX = 12;! I; n9 H: ~8 |
int16_t offsetGyroY = 33;
int16_t offsetGyroZ = 4;
5 h# w9 f7 a7 O3 B) N3 ~
extern I2C_HandleTypeDef hi2cx;
//**************************************
//向I2C设备写入一个字节数据
//**************************************; i" Q) f( s' z) o' |
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)1 c4 U" ?/ @6 F8 x1 x# T5 Y
{
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}4 _( j7 l/ i1 _2 ?. A/ ^ c
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************: ^6 B a& M% Z/ P
uint8_t Single_ReadI2C(uint8_t REG_Address); S* y& _: s9 R0 |
{
uint8_t REG_data;; D, A: Q0 c4 @0 ~
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)1 l3 c; K- g( x& H
{4 u* B0 l& P( g6 z/ I* A
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
} I& _: U; R) Z% N7 |
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)% V8 c2 E. D# P& |; L
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}6 Q- c6 L2 Y" D7 u- \% P
return REG_data;
}
//**************************************
//初始化MPU6050
//*************************************** f0 Y4 ^/ s3 E R
void InitMPU6050()
{+ P" m: c$ |, b) K% F: {+ {
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态$ B7 h' T$ X4 a; s% o! ?
; @" U4 @: B, G$ u) v
Single_WriteI2C(SMPLRT_DIV, 0x07);
8 c4 U h! X2 h: z- y& _
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);( y# v x4 j9 r, }
) B( r' a2 m* Y% S) C. x
Single_WriteI2C(ACCEL_CONFIG, 0x01);
} e. \. {9 v* D6 A
//**************************************1 h n( J; p" b! F/ Z. c, ^
//合成数据" w) @9 }" i: m# _0 J% \/ Y* P
//**************************************
int16_t GetMPUOutValue(uint8_t REG_Address)
{
int16_t result;
uint8_t H,L;' z0 f% Y( S- p
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;" w3 t7 N" t: v; G' b
return result; //合成数据* a5 N, c1 Q. N
}
//**************************************
//取某一轴上的加速度数据
//**************************************
int16_t GetAccelValue(char axis)1 ?7 F4 D4 J$ @! z7 d
{
int16_t result = 0; L; ] X% e3 P+ x" t' d
switch(axis)/ j& j- n; C' X3 p6 L6 v3 ]! q
{
case 'x':
case 'X':% H$ Y$ b' h4 [- u( L/ v
{
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;# h! y) `* S$ b+ g5 Z
}
break;2 D, n' E5 b& ^4 P; L
case 'y':" d+ C9 V* T# R% l5 b
case 'Y':
{: }. ?$ f2 s, d& q
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;/ G4 a/ R4 X' m
}3 E0 T4 f' ~$ s
break;2 X& z K/ P6 Y4 L, {/ C& j' D
case 'z':
case 'Z':
{! l7 H. d& U5 \5 b& g) u/ A
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}' t7 B e! [, J- M; C
break;
}+ I# t' i3 ?; `. f3 X
return result;
}
//**************************************
//取某一轴上的角速度数据
//**************************************
int16_t GetGyroValue(char axis)
{ f) \) M, H3 r% q4 \8 U6 Q
int16_t result = 0;* c5 v7 R) o9 Z J! z+ K; h6 \
switch(axis)- o7 b+ |: @3 B' R' `8 J
{
case 'x':
case 'X':/ z5 B' \9 j) Z; m
{7 o& l7 Y: n" q4 @
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
}0 n7 b% g2 c8 I7 {/ j' f1 |( t
break;
case 'y':! C) o1 t u }
case 'Y':5 t% r5 N7 D' ^) j, c
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;# f6 L/ h% v* G2 ~# r
}
break;, b% Y& @" g3 I1 m- e9 \4 S: c4 f
case 'z':% m7 e* m5 v! W1 P
case 'Z':' o0 g( d) t# s9 H# ]/ S2 f, D' S8 K! L$ G
{
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;5 j% [, Q- {* G
}5 g' J" h6 v& }6 Y6 V7 o
break;
}% G+ A* @8 q: p$ g
return result;
}
评分
查看全部评分
{7 n. w7 }" G* Z9 _0 K) G
/* USER CODE BEGIN 1 */
1 O3 S/ [' q" z) K- U
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*// [- z! F; v, c0 ~+ p
, b) {8 j c+ O6 g
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */, m8 G, n! S3 v. K c5 A" C+ M7 A
HAL_Init();% [5 x# P8 Q, F
- _ K" e( V! r
/* Configure the system clock */, b: ~& {. s( Y7 \% x' ^# g' U1 k# {3 P
SystemClock_Config();3 J9 o) m% z9 J
. q3 ^. ^' u6 c; u
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */$ x( O6 V8 L# y5 l9 {3 d0 e
MX_GPIO_Init();
MX_DMA_Init();2 z9 r! h; {) l( v7 v' ]
MX_I2C1_Init();) z" p1 c3 z3 S6 v, ]2 s4 T
MX_TIM2_Init(); ]4 U" x' H, Y3 Z: m! h" m- ^
MX_USART2_UART_Init(); q! u/ ]; t' n3 [3 F7 a
InitMPU6050();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);& g/ g m6 W0 x& m1 c' A. i C
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */% ?: q! C8 z. C
7 i6 I# M+ S7 ~. v& P& { P
/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)1 l. v9 Y! k/ L" [( `2 O* B
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
VisualScopeAngleOutput();" r+ Y/ ^2 J4 q9 f( `7 I4 p
HAL_Delay(100);
}
/* USER CODE END 3 */
}. O9 q6 |) n4 S! s
/** System Clock Configuration0 m$ E6 O5 j/ l" X0 Z$ T2 f
*/1 N3 g R8 u* W
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit; w. m! F, y/ h( m( S
RCC_OscInitTypeDef RCC_OscInitStruct;
1 v' Q/ p6 u* b: l z$ K( Z
__PWR_CLK_ENABLE();
+ [9 W7 ]+ J2 e6 ]/ Y
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);% j' F- f1 h- G( H
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;( S' H& _+ D) h- p" E: u
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;/ c' u) R) Y+ R: Z5 d
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
HAL_RCC_OscConfig(&RCC_OscInitStruct);* n4 C: x% r- |( E" @
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;" I' k9 t- `8 b1 U
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;9 d% n$ m- k3 ]4 X" Z3 Y
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;$ e( x% i* @) F" Z) g
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);, `6 h: r. c6 x6 g6 X- }! b
8 | m ?% ]3 ~2 U
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
1 R4 H2 W2 C) ?; q# ~
__SYSCFG_CLK_ENABLE();. K a, }7 z7 L8 v3 o
}3 u9 R4 R' k: X+ O2 W6 ~7 y
3 m; Q2 c; e! F2 K/ d1 h, g" E
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{% B: B0 [" W+ u
if(huart->Instance == USART2)% a9 r/ S. V' d# M
{7 ~* [7 M/ C0 ]+ `
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);. L' E' [) U" e2 d& Q# |' }# X
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);( {- s8 f' R( R6 Z
}
}: {1 P6 k$ B& M _3 i( s
3 R, G8 {- J; N, |9 N. d
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{3 Q9 }6 {# J. g" E& s3 W1 h/ Q. E1 c7 Z
} s. Z0 H; P! V7 v1 n
1 \" t/ Y# i$ T1 ~- @( ^- k5 o: l9 o F
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)/ h/ `2 f2 d1 g& O7 o9 R; c& ]) |
{
int32_t GyroValue;
3 }- y+ r, q0 S5 a" Q1 ^- u
Calc_AngleAccel();4 m( w# }3 }' [
GyroValue = Calc_AngleGyro();
ComplementFilter(GyroValue);: @3 h- P2 W* G( [4 u6 @% C
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。