拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c. k' U3 x F2 n5 k% S. m #include "stm32l0xx_hal.h" #include "dma.h" #include "i2c.h"1 R# Z/ y, Y$ @5 G5 [3 Q( r7 l0 C #include "tim.h" #include "usart.h" #include "gpio.h"$ X0 ~9 f# m; a% J9 |0 d #include "mpu6050.h"* b- m* K. D, O6 G# t #include "visualscope.h"7 @+ [6 Y8 F( Z0 K, A #include <string.h> #include <math.h># }# @5 W p* y5 r* x2 q3 | /* Private variables ---------------------------------------------------------*/( k9 d; k/ X; Y* S% S( [' N #define RXSIZE 8/ Q. @9 [3 d% \; C- M #define TXSIZE 8 uint8_t rxBuffer[RXSIZE];7 k2 A% c+ C8 s( U uint8_t txBuffer[TXSIZE]; " U1 J+ p1 y2 w0 K/ M7 n float Angle_accel = 0;* B! u U& Z# B/ E) g1 `( U float Angle_gyro = 0;3 q/ T4 K. x5 }, m3 n9 c float Angle_comp = 0; uint8_t outAngleData[10];2 w- v1 e/ h7 i, F /* USER CODE BEGIN 0 */, n+ B& t% o) w& s! g5 W % h& t" m: d* ~3 D% f: U /*---------------------------------------------------------------------------------------------------------*/* B9 @, |4 q3 }9 P8 }. y' d- T /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/( R- p4 Y2 q' t int32_t Calc_AngleAccel()# P6 H+ f9 W9 f2 _2 G {& ~. H: x; \/ l5 H v int32_t value = 0; value = GetAccelValue('x'); if(value > 16384)0 [8 `* j* C6 l% H Angle_accel = -(asin(1) * 180 / 3.1415296);/ ]$ {; K7 y* P, ~2 k else Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); ) a% D" t; |6 p return value; }$ F# b" O' @6 J! I/ o5 T /*---------------------------------------------------------------------------------------------------------*/ /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleGyro() { int32_t value = 0;& u8 {) N8 t- R9 W value = GetGyroValue('y');% y+ s2 M" A1 x5 n& D* ` Angle_gyro += (value / 16.384 * 0.01); / v- Q8 ~: X8 i% D; b; ? return value;7 Y/ s' ?( a8 v! i' J2 r# V6 c9 A+ W/ a } /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */# r! x. { m5 [, J /*---------------------------------------------------------------------------------------------------------*/2 n' F1 D5 Y! d. A( i4 E! R float ComplementFilter(int32_t simpleGyro)( [- v% X" d, c0 v# G! c& ? {( P1 x- H7 P( ?3 V Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel; return Angle_comp;( ]4 Y0 X3 D; {+ a) z6 U }8 E L5 `2 ]9 Q" \3 T+ ? /*---------------------------------------------------------------------------------------------------------*/- m7 P$ V. c/ Z+ D+ W2 Z* { /* 输出角度至上位机 */ /*---------------------------------------------------------------------------------------------------------*/ void VisualScopeAngleOutput(): y% m) \) Y$ n+ k {0 l8 k5 H8 e/ `% b int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp; uint16_t crcValue;: P: N" R! @7 [: h+ H0 x N1 n, L AngleValue_Accel = ceil(Angle_accel * 10 -0.5);: r' k2 N- p3 K4 q' @' ` AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5); AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); @( y% O2 J' C! s outAngleData[0] = AngleValue_Accel & 0xFF;% J* M! Q" ^( Z% M2 e8 X! A) z. G5 _ outAngleData[1] = AngleValue_Accel >> 8; outAngleData[2] = AngleValue_Gyro & 0xFF; outAngleData[3] = AngleValue_Gyro >> 8;, F a1 U) j# o outAngleData[4] = AngleValue_Comp & 0xFF;! s6 N: u9 w1 w. K9 q0 Y7 J outAngleData[5] = AngleValue_Comp >> 8;- d Z7 h4 Z+ A& a' X //计算CRC crcValue = CRC_CHECK(outAngleData,8); outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8; c2 d1 q2 D* k+ u! M! @9 S //发送至上位机 HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));$ Z0 x: _# j0 K% g9 k }" K- `% h0 F9 y8 {3 q& V: ^' R /* USER CODE END 0 */: R1 T; D: O& U) H /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); 9 P' P, h: l7 q D4 p 硬件连接图: 波形图:0 O M; i X- u; ]! G 最后加一个视频:1 \. }2 | c0 D. ] STM32L053 演示 |
意法半导体最具性价比、速度最快的单核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"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
1 R) S# p' ]8 W) e5 V
I2C_HandleTypeDef hi2cx;; A/ _, y' V. E4 y3 o& u& O4 ]* T" R( J
/* I2C1 init function */) h0 T Y! q7 Q
void MX_I2C1_Init(void)
{
hi2cx.Instance = I2C1;: x0 v5 H4 L4 m. s
hi2cx.Init.Timing = 0x20D22930;* i4 E. m0 k3 b8 S ?4 }
hi2cx.Init.OwnAddress1 = 0;
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;0 v3 j- Y0 o% L/ x9 @2 _! [ [
hi2cx.Init.OwnAddress2 = 0;$ f9 r8 O$ W" x9 C4 U! K. E& h' O
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;; Q% y2 J. u7 e
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);- H2 a4 O3 E i& C
- w$ A" F! }% j' c0 P7 j7 @+ e
/**Configure Analogue filter& r3 l( o# j1 T' N! f3 c( a+ W# R8 h
*/
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);: p5 c, ^9 J5 \5 m
}
' Z# O$ N8 X- B# T
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)# p0 _( ~) P, c/ ^
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)! K( m9 O2 v$ f$ P# [) F
{$ _2 a# [2 A* j. c& Y2 ?
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();% h; |' \. Z( O1 p. S: y6 O( W
8 |+ z8 F$ ~3 h4 m' d9 _
/**I2C1 GPIO Configuration - F$ k8 [& J' _2 N4 {
PB6 ------> I2C1_SCL* v3 z/ B. F' P4 t
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;$ u6 L9 E' w7 c+ e, y9 m( O1 H
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;; x, |' F: T& @' s* E+ W
GPIO_InitStruct.Pull = GPIO_NOPULL;& r6 M' ^: y8 f3 N# n5 Q/ E# v( F
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;" d1 h; x. f# N6 ]5 h
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);2 W) u' O9 S$ S
}3 N) Z6 N) g' w2 {
} ~2 l9 Q0 c1 Y7 _9 u
. D7 q+ _& W( J; k6 F
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{' a3 v$ y) B8 b0 T! [. a: s
if(hi2c->Instance==I2C1)
{) I9 u/ g! @( B! _- [: {" s
/* Peripheral clock disable */0 a9 A* H: p$ ^' j
__I2C1_CLK_DISABLE();* H- }6 h' I3 @4 c
0 m* e# g; C, k8 z4 w
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);7 m6 _3 w- _7 K U1 l, l8 k; X
7 Y7 o& K: r9 B- j
}
}0 c" x: \8 f. F' N0 }' ]
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------3 o( [1 V- J3 n
usart.c% Y, b' U* W7 _3 V5 ^- @: n
#include "usart.h"
#include "gpio.h"0 N$ l, D: r$ e9 ~+ }$ K C- {. l
#include "dma.h"
9 U# i1 L- O, d' H
/* USER CODE BEGIN 0 */& C# c( T+ a( }/ D" i0 `
9 Y, E1 H% } S6 H. h
/* USER CODE END 0 */& x6 y# u8 }4 q8 v: I( P- Z
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;3 p. W, x$ R; Z a- P O
DMA_HandleTypeDef hdma_usart2_tx;
/* USART2 init function */: `; v3 o& q% x9 D9 T8 u: l8 T
r j9 a* T/ l2 a U9 Y4 g3 Z
void MX_USART2_UART_Init(void)) b3 i* R6 _( N% d' l- J. [
{; Y) {1 Z( U4 c7 E$ Q
# v9 b* |9 `% d- n F" i- x& t
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;* J5 |* ^1 X6 b1 I* E- w! P
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;" s r- q! Q _( w3 k
huart2.Init.OverSampling = UART_OVERSAMPLING_16;! ]0 G5 j# W+ e8 ~! v; x1 R
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;' {; w4 x8 G3 G3 m
HAL_UART_Init(&huart2);
}
" J! d3 `0 ]1 m; i
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{$ q$ d6 c3 z+ C7 N7 ~" j# q
GPIO_InitTypeDef GPIO_InitStruct;0 b7 A8 I% e) Y3 K
if(huart->Instance==USART2)) Y3 t- h' O s# q C9 ?
{
/* Peripheral clock enable */4 D4 d& T3 E) P! C8 j8 u
__USART2_CLK_ENABLE();
1 A @/ y0 G- A* P# D+ N" ]! N6 ~; ~
/**USART2 GPIO Configuration 9 D5 G1 t6 ?) V& P; h @
PA2 ------> USART2_TX7 C- c! V! {, S
PA3 ------> USART2_RX6 b) b Y/ }5 ~* [
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;/ h" b y* f+ m; R |" F3 c
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;; ]8 n$ y! u$ r& G
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);: [. m6 |3 \1 D! H; [ ^
# [$ R" e( W& u+ z0 `
GPIO_InitStruct.Pin = GPIO_PIN_3;- J7 i8 i$ W0 E& d8 D) b; `
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;- z2 x% f% H/ i1 O6 B
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;: D; A* y) w2 G* k3 A
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;9 {" h! s5 U: B' n8 x
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);9 y( I( w D8 V2 z1 a
/* Peripheral DMA init*/: E! i% Q5 _* U8 u& r8 d& t
% d% r2 w, ]; D& W
hdma_usart2_rx.Instance = DMA1_Channel5;1 l+ n- X/ T5 p9 z5 @) T4 ` n/ O
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;( `1 V1 H M; _8 N3 v
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;* n2 P- b4 ~5 C( A$ R; Y
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;! |+ I# k6 `. A& h) J
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;' D! I& V$ H% b- d3 `$ P4 Q' B$ a
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;) E( m- K3 q9 n% B" F8 g4 ^
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;- x7 N( S5 ~" i9 U" F$ Z1 E, V
HAL_DMA_Init(&hdma_usart2_rx);+ V, d8 l! y6 J5 n% q. }
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx); W& t: X# z" \
/ _* G F- Y4 _8 C) r
hdma_usart2_tx.Instance = DMA1_Channel4;
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;+ V, y4 Z3 F5 g
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;7 C; d- v0 I# q! f0 k3 P
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;' @+ }2 _6 b1 R- \4 n" }
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;3 i1 M8 G4 y+ g: V
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;& _9 r% m1 C2 r7 v, S
HAL_DMA_Init(&hdma_usart2_tx);" I' y; U3 j" @9 s. b4 g
S; P8 } a" n/ C4 h
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
}
}
: ?6 m( U5 ~8 e/ h
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{+ ~! k. ` d% ]+ B. x( k6 i2 Z& R
if(huart->Instance==USART2)
{
/* Peripheral clock disable */ y6 h" P0 U# p' p9 u# Q$ x
__USART2_CLK_DISABLE();4 _" v$ }% _( W, L+ n
/**USART2 GPIO Configuration
PA2 ------> USART2_TX- @& b! a' m( a% a* i
PA3 ------> USART2_RX9 d. [% [ C1 u1 r, J' {2 Q6 B
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* Peripheral DMA DeInit*/5 @: }2 A- ~* y4 G
HAL_DMA_DeInit(huart->hdmarx);0 z. m+ f1 R, S+ i {
HAL_DMA_DeInit(huart->hdmatx);$ a8 i+ {- q( W4 C- r# b8 w
}
}' \" t1 q. L) M5 u# C) A- h! ~ p
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
mpu6050.c
#include "stm32l0xx_hal.h"; S, \3 g/ T3 x& y7 X
#include "MPU6050.h"
. Y ^" Y" p2 [. D/ p/ ?& v+ _4 {, a
//各坐标轴上静止偏差(重力,角速度)6 S9 b& P/ u" R4 E: Y O
int16_t offsetAccelX = -195;8 V/ t0 a4 O9 B% {; J0 T$ W( p
int16_t offsetAccelY = 560;. l' C6 [; p: }; O
int16_t offsetAccelZ = -169;8 y- |* V2 o4 \' J) R; @* {- C
5 ^2 {9 Z9 C& f7 X( f! p# V( `; }
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;; y! T9 g' L- {! v1 L
int16_t offsetGyroZ = 4;
extern I2C_HandleTypeDef hi2cx; C* w( V0 O, ?# e
) G* D% \: }; e
//**************************************
//向I2C设备写入一个字节数据+ Z) X3 Q; [7 p" ^ E: M% S' W
//**************************************" R& j# [3 H8 T% o+ @. |9 t( M
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)) D8 h) o: r' D7 \# p$ e9 E
{/ F3 J d, S# `9 j
uint8_t rxData[2] = {REG_Address,REG_data};% ~3 c, V- A5 r
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
{, E4 |: i3 a, R
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)8 t* x4 C( K" W) Y& e% b+ P2 h
{}
}3 A6 A) y W* H/ x5 H! O: K9 _
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uint8_t Single_ReadI2C(uint8_t REG_Address)- j$ Q7 o; a) y8 f
{, O- t K9 B5 r7 c
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK). }7 m, z/ y1 |7 v: ~7 Z; n
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)( ~2 z+ i) o8 A! a, @: P
{}
}; Q2 ~% S% J) F D& e4 @- K/ a
+ P$ E6 g7 ^% T, v! r4 x
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
{! [6 j/ |( c" j( m. ^8 ]
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)% J7 _% `: ^; m+ q% w+ g; U% Z/ j! |
{}
}
return REG_data;8 |5 V1 B; M6 Z( n
}4 a; x7 l7 q7 s& l" s; B
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()+ w! T4 Q8 c, N) h
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态7 O- i* k- x: o- @
Single_WriteI2C(SMPLRT_DIV, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);1 }4 p' ^7 i5 T* @; y/ A! v
, u8 R4 I6 F3 C5 P: L' h# j
Single_WriteI2C(ACCEL_CONFIG, 0x01);
} q7 S" Q9 j3 \- y3 R" [
//**************************************9 W9 C7 N) O7 [+ D. T
//合成数据1 E% J0 {% t2 A" V/ g- j3 n% w
//**************************************
int16_t GetMPUOutValue(uint8_t REG_Address)
{
int16_t result;, B. P5 J# V- D- V
uint8_t H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;: s$ i& g$ A0 O0 m
return result; //合成数据9 d+ @7 |1 b W! b0 d0 v. L
}) p; C! r0 S% C2 P9 K
9 U- J( J% J& ~7 d( d
//**************************************
//取某一轴上的加速度数据
//**************************************, k s2 g$ N/ D( A. Z' ^
int16_t GetAccelValue(char axis)3 U+ }; p" j7 s( S* r
{9 ~ {. U& G* f) z7 p) L
int16_t result = 0;
switch(axis)
{
case 'x':: y \6 F1 y1 F% X: w, V' C: | _
case 'X':& C+ [5 I3 {; U: o+ |+ m# W
{! ~; o D* G; g
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
}9 ?( G8 F' x1 A, V- i6 |1 f
break;
case 'y':
case 'Y':
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
}
break;2 m% O- k5 U* T$ ]! h3 ]! J
case 'z':
case 'Z':3 a0 k( I! P$ N7 F5 H2 m4 {
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}
break;: m5 K% [3 [+ `7 q0 H
}5 M/ y+ @+ Z' z
return result;
} ]; b5 l' |/ F& b) x. b
# Q$ V+ L' M3 N6 E; w7 R3 ]
//**************************************8 t! F @/ Q5 X6 f1 W: j
//取某一轴上的角速度数据- g! D5 S: m. m
//**************************************& F$ A4 |$ k7 ^9 [) h
int16_t GetGyroValue(char axis)* L( t& T, L) S% J1 k9 x+ Y
{3 c) G1 x; j; h/ t' T
int16_t result = 0;& I! G% b: C) s
switch(axis), D/ u' L# K( E
{
case 'x':
case 'X':1 F S3 S& X* @& O! `, x4 }
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
}/ d# l, }; B7 e* x6 N
break;
case 'y':/ t/ T) p" X/ T+ t0 N
case 'Y':5 j" h( b9 ~- E, X/ N- S
{4 B& q, Z4 f5 [4 u+ {& {( ?5 U
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;! m" H7 ?5 i. ? n7 L
}/ Q+ ?' ?8 s( o: H u- i) ^% X
break;5 l( T- ]- J8 }
case 'z':
case 'Z':
{4 r6 F( v; O! Q4 t) U2 V# k
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
}) [; k; E& c' g- \% u8 J
break;
} ^, X% h8 n& y6 a9 B
return result;" |, ~2 K7 y g, I' H/ N$ k* N7 F0 \# I
}
评分
查看全部评分
{0 b" \& w4 t/ d0 _
5 Q4 e3 y! ^4 e1 i: s
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */, r7 m; w) [- V/ L: `. J
/* MCU Configuration----------------------------------------------------------*/
# |0 A2 f% v2 R1 n0 F W9 n) b6 g6 B" Y3 z
/* Reset of all peripherals, Initializes the Flash interface and the Systick. *// X7 @- ]$ W5 p% i
HAL_Init();
* p% c$ f( t$ }8 z E1 X" [
/* Configure the system clock */
SystemClock_Config();
4 y! Q/ q6 N2 F: W+ e* M% S! L
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
( X" [% X" U7 _# a3 p/ u. N
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();! K6 o' O1 y/ r/ D* Q8 W
MX_TIM2_Init();) D E4 y. R) S, @0 y
MX_USART2_UART_Init();9 x8 d. ?; Q' E1 m
InitMPU6050();# f- ^! P! ? J, M9 C1 t- K* Y
+ m7 g Q x& E6 m/ P
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);8 h+ |; s" ^$ o# u
HAL_TIM_Base_Start_IT(&htim2);5 d. f4 `8 g* N$ G7 ]" S
/* USER CODE END 2 */6 C8 U' t1 a6 R1 G0 D. c
/* USER CODE BEGIN 3 */
/* Infinite loop */' V7 ?2 e4 z5 n a8 [
while (1)
{2 t2 C/ Y* w" g& d; B% T2 N' T
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);* m u& @" V2 ~, T8 U& X4 l. m
VisualScopeAngleOutput();: a v8 _5 ^% D, x* F4 Z2 m
HAL_Delay(100);7 X% R5 `) w5 u3 C+ D
}
/* USER CODE END 3 */6 f9 G7 O) I/ Q
! {3 c/ q8 s- V: |
}: O0 O! H* V0 i5 j2 l
/** System Clock Configuration
*/2 V3 @3 h; _0 H/ `: D
void SystemClock_Config(void)% O% _; P+ B. ]( _/ I8 b
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();+ U7 `4 y8 o* K, m M
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
1 Y* d; K, b1 M6 l$ {0 l: _! D2 ?
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;8 M V8 L5 E4 e% ?
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;6 J+ K! \4 e( a8 M
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;5 o4 Q, o1 @7 _5 I2 f
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;9 d' Z0 Q; b5 Y' |* E/ |
HAL_RCC_OscConfig(&RCC_OscInitStruct); A& j" G0 ^, F+ ]
. ^7 s6 b6 S5 c8 p# }/ J
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;* ]4 U6 k* ?& o4 M2 o9 c( Z
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;9 d6 `- H4 [% A [7 B
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);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;. w- T! K9 ?' F! z
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);* y, B7 c6 l: G" ~* n
9 ]8 V% V M" M+ M8 `, |
__SYSCFG_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); k6 m# i J# t$ ^5 |
{
if(huart->Instance == USART2)
{: k; j# A/ {; v3 h4 ]
memcpy(txBuffer,rxBuffer,RXSIZE);7 \4 |" }9 D% ]8 K; {, h h
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);# F# \; @# X7 {
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)* u( c1 W# H$ l
{% s8 B$ a2 n1 N p( _
; T3 o0 R4 h0 E, k4 Z
}
9 a+ K. G5 K0 K( \" N8 j/ M
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{( S" E( V4 F, z: _3 f" t
int32_t GyroValue;. M* T9 r p8 U* w0 k
0 e9 |% O3 L# Q+ j8 O
Calc_AngleAccel();
GyroValue = Calc_AngleGyro();$ {/ r7 ^3 W) w: Z
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。