你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32L0 HAL驱动 串口 DMA,I2C读MPU6050 精华  

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:* h2 i7 v+ s! H* y3 H! b( \
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
6 p' T8 E8 E. q1 U; P& Tmain.c9 x* ~2 ]! Y8 R; U4 t
#include "stm32l0xx_hal.h"" n. S  I4 _1 u- F1 u0 {
#include "dma.h") |  C' N7 q$ s  z- [
#include "i2c.h"! T  V; x5 R% g4 n0 _4 V% V
#include "tim.h"
- l! c8 l. N( Y; c9 P  ]! ~* s/ ~#include "usart.h"9 \1 O/ u' ~& f) f9 T
#include "gpio.h"1 J2 B4 o3 }/ \
#include "mpu6050.h"
$ L, }$ f# C- J) L: Z#include "visualscope.h"
6 Z: c8 ~, \, v! R. j" z' x3 I" S0 m" U9 T4 o+ D+ M
#include <string.h>
, f1 y. c3 B  }  H/ p#include <math.h>: T- y5 }( u( f; D  t) C
0 }, ?) A5 C; a
/* Private variables ---------------------------------------------------------*/. d" q: d8 }2 F. h0 N6 }7 C7 Y
#define RXSIZE 8
$ L2 F, y6 T+ r- ~" c+ W#define TXSIZE 85 x6 r+ ]6 E! C; P6 U. z  t
uint8_t rxBuffer[RXSIZE];* ?7 I( ^+ A) H5 A- o+ ~0 g
uint8_t txBuffer[TXSIZE];( }" h- e# D5 A$ [$ ~# t
3 c: Q4 V/ ?, F- i
float Angle_accel = 0;, m/ y( ^- {$ T+ f
float Angle_gyro = 0;
/ s. B) ]& g, v! ^6 M; g- Zfloat Angle_comp = 0;/ @/ h2 y" E2 L' G" ?
uint8_t outAngleData[10];
0 J1 l6 f( O1 }! f7 m/* USER CODE BEGIN 0 */
  {; o! y) K. v( `# K& v" c) F4 s8 E+ t1 J9 p& R
/*---------------------------------------------------------------------------------------------------------*/
$ f! {6 D( w% X' N" k/*  重力加速度算出的角度                                                                                       */' K. e- R5 f' f3 R3 n( i& K- `
/*---------------------------------------------------------------------------------------------------------*/
2 E  a; l5 e& h8 W; k4 I( B$ xint32_t Calc_AngleAccel()
) t- V# H5 l; Y, j3 R{7 y. H2 S+ O$ u+ A6 ^4 v" d
    int32_t value = 0;
# y: e+ b+ T" {; d+ ?0 B    - w4 r! O& T3 X9 I6 v9 K
    value = GetAccelValue('x');- N) I) Z+ w8 n, N$ q' L
    if(value > 16384)6 Y% E6 u5 q5 N$ s7 A* ?5 [
        Angle_accel = -(asin(1) * 180 / 3.1415296);
: d9 u5 o( }" R    else/ h9 X/ C3 O5 H7 x. T
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
8 w! u. Y" D. M+ |* [   
- C3 l! l# X5 O  }* L6 x    return value;
% c" r& Z0 m8 u2 s8 O' I" t- S}) `% M* t9 ~2 p4 R1 q& G3 u  L

+ h9 t8 P) M- ?) X. S4 M7 Z$ z- s/*---------------------------------------------------------------------------------------------------------*/' Z7 _/ X& F+ X; K+ M# I* v
/*   角速度算出来的角度(积分)                                                                                     */
+ J4 t$ d2 Z. d7 V: s# |0 ]/*---------------------------------------------------------------------------------------------------------*/
) [8 s+ I0 ~6 [0 ~! aint32_t Calc_AngleGyro()
. f" T- z6 u+ W5 D$ Z  `{
0 q4 t$ e. ?& ?( f# n3 `- [) R    int32_t value = 0;: n9 \1 N  ]" {, j5 y" z

8 n% S0 P) ?6 u8 o0 w" B    value = GetGyroValue('y');
# P3 s( P# a/ \9 j" g    Angle_gyro += (value / 16.384 * 0.01);
& \7 c2 ?6 _- d, w0 o( d    : h) z5 D, G4 j. |: m
    return value;% B2 b2 z7 b5 ^# \* O9 x& B
}, K. t! Q4 S+ P5 {

" c* y# U& d; g8 ?/*---------------------------------------------------------------------------------------------------------*/
) ?+ M% @) I- L& Q) M$ q: B/*   互补滤波求角度                                                                                     */( n2 e( J* u. i$ i- I/ Q/ o
/*---------------------------------------------------------------------------------------------------------*/
* a+ G. h) G( {/ t0 [1 o0 X3 }) b2 lfloat ComplementFilter(int32_t simpleGyro)" V7 E0 H) z! U/ E/ V
{: |4 c+ }) r2 Y& B& S
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;) E# C9 e2 S+ m+ o% _2 j
   
7 ^" [- ~. K# ?; }# d9 h8 j    return Angle_comp;* f+ e# N/ {$ _
}
% |9 U& ~! a4 W/ T9 K1 B
- q8 H) A& ^$ P- O0 I5 Y" y/*---------------------------------------------------------------------------------------------------------*/
2 f, M' {; \; t' C/*   输出角度至上位机                                                                                     */) V$ c! v8 }3 @+ s2 K, d, }
/*---------------------------------------------------------------------------------------------------------*/
/ D; l6 ?( x- S, Ovoid VisualScopeAngleOutput()
- v1 W( T* e, }) h' B  g4 s6 G0 k{) S5 l9 C9 I, `' a$ ]7 L9 v
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;3 t: @  N: R! D8 N9 o/ @
    uint16_t crcValue;# x/ ~1 `1 Y; F5 P2 n/ }
    , J* s' v  @  Y9 y
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);4 |- ?7 U4 S; E1 V. A
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
% P+ u# y( ~- x+ q' i' N    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
) s5 k" B" q4 f; I* t" U    % {' k. {9 o, s! C2 {0 R
    outAngleData[0] = AngleValue_Accel & 0xFF;# X/ J; Z9 r: T! {, b/ B3 {
    outAngleData[1] = AngleValue_Accel >> 8;; i: ]( A" \' p2 g9 {4 |, E# e
    outAngleData[2] = AngleValue_Gyro & 0xFF;" C2 A% Y3 ?; h- I
    outAngleData[3] = AngleValue_Gyro >> 8;
9 H1 q2 m& V  K& L: ^1 A! [" o    outAngleData[4] = AngleValue_Comp & 0xFF;
# p" M) ~  }2 c    outAngleData[5] = AngleValue_Comp >> 8;% d: B+ w: Q, Y
    //计算CRC3 ~* }" E9 {) U9 z0 _
    crcValue =  CRC_CHECK(outAngleData,8);
/ U$ x3 W, {, z5 i    outAngleData[8] = crcValue & 0xFF;, s4 I- F  S7 w. W
    outAngleData[9] = crcValue >> 8;, ]/ o  ^" _3 Z8 [" ~( V; J% I
    //发送至上位机+ \- v, y" e: a- o; l! |+ |$ m
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));1 t; }( U+ M  E+ S( T" D- W( c  P, h
}
- Q% t5 r( s; i4 B; }2 b/* USER CODE END 0 */; W. ?8 e* }! d4 P. |% R$ v5 Q3 _4 i
  w0 k: _# U+ A4 r2 e: J' l2 ^+ I
/* Private function prototypes -----------------------------------------------*/
. }7 l2 P& i# B4 i" w8 xvoid SystemClock_Config(void);
' ^7 R6 d- U7 C/ k# N
1 c6 @# p5 g/ R0 X3 ~" n/ x5 ]( z
硬件连接图:
6 A4 K: E3 L6 j 1.jpg
# ~' x/ b& c* K# o波形图:1 J# R* w$ a) Q/ S
2.jpg 7 x( b! d  R( p" ^
最后加一个视频:
9 m9 A4 n  C' w+ KSTM32L053 演示" t8 }/ r2 W6 P8 N7 o5 S
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
* J0 g7 }, j# k- `" l0 ?#include "i2c.h"
% q: u+ }) v6 l; ^1 A$ A8 T5 ~3 k2 ^1 S  v
#include "gpio.h"
  B3 Q, \5 K% S: b& J2 f% U* C. v+ F* n! ]- _/ ]- ?
/* USER CODE BEGIN 0 */
% }6 _" B/ Z  Z2 a* Q* i8 I( D- H" T$ t8 h% S! D5 L! u2 ]
/* USER CODE END 0 */+ z/ T# z1 x+ R7 {, M% J
/ V2 n4 h1 f3 ^) n$ h; a
I2C_HandleTypeDef hi2cx;( L( a  b9 w( X$ t7 N* ]

7 d( ^* I. I: q8 j2 c1 u/* I2C1 init function */1 p2 M1 g. w: \) G- N
void MX_I2C1_Init(void)
6 s5 Q# r) f2 l# {# v) U{  l( Z  Q; t# }6 L( G) t! ?, z, P

6 u) R" P+ |  ^7 O4 ~7 @- I  hi2cx.Instance = I2C1;4 S+ @! W" u: }  \, ]7 w  `+ B
  hi2cx.Init.Timing = 0x20D22930;1 {$ e- k' r$ k$ R" h6 X
  hi2cx.Init.OwnAddress1 = 0;! G, C8 i2 j* w' K
  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
. b9 V. h) G" e3 F  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;3 S% t7 Q# }0 y6 l. E
  hi2cx.Init.OwnAddress2 = 0;
/ d& o1 A/ R7 ]# s0 l, a" {  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;& j4 A  d# k3 `  ~4 G
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;' ^+ l" \/ H! x
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
4 C" [! c6 A$ n1 n- P  @# A  HAL_I2C_Init(&hi2cx);
- [: @1 I, T2 l4 [( J# n
/ P3 a% B. m0 w0 J# b9 n    /**Configure Analogue filter  D/ b& G6 B* |9 r: `7 }4 S' S, q4 v
    */# k: x" ~2 l1 W; p, l( f" U
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);: E9 w' `6 ~& {& u4 J

, F' B# W+ T  E$ \}7 ^4 k. p; L6 X

( }4 g. B; ^* |3 u3 svoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)0 O1 Q& {4 k! l* d$ @) T$ \
{
1 }% W4 M3 y, `/ P. f7 m$ M
# m3 C+ q1 x" Q0 y2 A+ j  GPIO_InitTypeDef GPIO_InitStruct;! N* c: y1 H; J7 {% ~6 E7 {
  if(hi2c->Instance==I2C1)3 E* o! |8 f& u$ b1 `6 c
  {
9 A0 a8 i& z5 b2 ~' o    /* Peripheral clock enable */
1 p( M  J4 s1 i* t. L9 l    __I2C1_CLK_ENABLE();
- Z+ O- F$ p- g1 @- [# F  
, D3 s; b, a) B% M  S    /**I2C1 GPIO Configuration   ; v5 ]3 v. ]8 ?4 R6 W# |0 L
    PB6     ------> I2C1_SCL
: b" O; q  ^2 d/ L4 D    PB7     ------> I2C1_SDA
' U  L8 E7 R; b$ b    */" _+ C& P. z4 z* x0 M
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
! K0 u7 X  K0 L% @8 {    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
. P! n3 k# A# E8 y    GPIO_InitStruct.Pull = GPIO_NOPULL;
* z' L& C" [& @- F    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;* z0 b8 Y3 e: _* b7 n3 E# l( j
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;# U5 _! X. h) x/ e
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/ ?* B" w3 _; V# V! O
2 s5 r' \3 W" n4 T( Z0 e$ y8 [/ w  }
% K' Q. a; C6 a}
5 G5 K; [( a$ l+ z  ]& v% q* i' {+ _0 p. y
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
! r, U) L- v: Q- a{
- x. ?) W1 {, Z3 P2 g4 Q0 ?/ ]9 u% Z2 u$ E% |) t
  if(hi2c->Instance==I2C1)1 b6 `2 l* D, x9 @
  {
; |. o/ S) N: z! H/ Z2 i    /* Peripheral clock disable */
4 I: a7 B  X% S9 N8 l% R  W    __I2C1_CLK_DISABLE();- q4 U# D5 p! |9 ]# o$ ?
  " C  H; i( K" e9 S- p9 R
    /**I2C1 GPIO Configuration   . }' U8 W5 e5 `" A) t" k
    PB6     ------> I2C1_SCL
/ T0 E- p! M5 M  z. Y    PB7     ------> I2C1_SDA
. d; V" p* Q. t" f" p! w. s# o9 B    */
- }4 ~8 a% V+ a& c. ^# _9 w    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);/ l3 q3 F7 Y. i( {% D
8 f/ W2 |; o4 C# A
  }
1 `$ G% C9 q4 P}3 q: T$ b, K" \% f# I8 X
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
$ M7 r7 {+ S4 [* kusart.c8 V; M5 v5 Q1 e! T9 L  x# x' |
#include "usart.h"
$ w- h$ `$ O! ]4 \" X1 o! l
: p" f" W. E4 O- D$ w#include "gpio.h"
3 B0 e% d+ k; e9 m/ T#include "dma.h"
. P+ @6 j  Q/ y( ^# P0 K
. X/ T/ X5 u0 {3 R& s, N% i/* USER CODE BEGIN 0 */
2 v" }# o* h7 K" R0 r
4 Y( G( |3 W) c! l/* USER CODE END 0 */- Y' r) y- a( A9 I/ T* }
3 ]3 j3 Y# Y/ O
UART_HandleTypeDef huart2;* r) ~* i! o7 E3 ?, T" G
DMA_HandleTypeDef hdma_usart2_rx;8 _( _* I, M1 ?# R
DMA_HandleTypeDef hdma_usart2_tx;5 P- m. B. d* K4 s
6 a3 N: f. o3 P& T( {
/* USART2 init function */
; i6 n2 |- j) x3 ^. H/ k% p" D( B" B. D% r1 n- |! c
void MX_USART2_UART_Init(void)
& d% M& j0 j! }  l9 G) y' R; J2 s{
6 ]& _" ]2 I- x1 q( y* ^: r, b+ G
7 V/ ^( J/ r* T0 r  huart2.Instance = USART2;) ~" p) u8 P0 ?, ^, g: p
  huart2.Init.BaudRate = 9600;
1 t0 o9 y" ^  {' t) ~  huart2.Init.WordLength = UART_WORDLENGTH_8B;5 z6 m0 `% I1 W2 x. l4 }
  huart2.Init.StopBits = UART_STOPBITS_1;
% |* O  X# F* G' |" ~  huart2.Init.Parity = UART_PARITY_NONE;
  i4 e$ R# m4 y9 u( J: |4 ^  huart2.Init.Mode = UART_MODE_TX_RX;
( s: A. _  @' F9 Q  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;% ~& O$ h9 P  B3 {3 f' z
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
! J2 P# N6 M: p; H2 ^) g  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;/ a! L& @$ G; x3 Y) B
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
& b. L- s" j* M9 X) k  HAL_UART_Init(&huart2);
( @" E$ _+ |* c: Q- ]" {: ~* a+ v) H$ \. F
}7 y; v# s0 e4 A! h$ W; p
, F8 A: z. A# N: T/ O4 c
void HAL_UART_MspInit(UART_HandleTypeDef* huart)( g% Z  m- _* J8 Y+ q
{! T" p! @' x- X( R" ?
6 F: P' F- J- n6 }
  GPIO_InitTypeDef GPIO_InitStruct;
$ J; p# A; X1 N& R1 T% v  if(huart->Instance==USART2)
6 s+ d1 m0 L' C8 M7 J  {. J) d2 U5 _* X. _1 X. D
    /* Peripheral clock enable */* L; O0 n" F! h4 S. @$ Q
    __USART2_CLK_ENABLE();+ L0 L3 N# {  c( ]* ~) `4 t
  3 R) A, Q% `' O: M4 M
    /**USART2 GPIO Configuration   " A' @; P" N# ]9 G0 P
    PA2     ------> USART2_TX% }( Y1 `$ X% {7 H) p4 r4 k
    PA3     ------> USART2_RX8 {# X# ~8 ?5 z+ N0 m* D) q
    */3 x9 d& ?+ _7 v4 b, N
    GPIO_InitStruct.Pin = GPIO_PIN_2;( z" }1 h* ~; M4 c6 n
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;+ Z- y2 {5 Z0 U( D% t
    GPIO_InitStruct.Pull = GPIO_NOPULL;
- a; T, x0 t0 G" x$ }8 g    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
' v5 ]1 T# R# N  T6 [    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
# h- c. u- s/ @9 I7 d3 O" D; x    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
; D( l1 z8 X. s
0 n. G% G$ ^3 ]  m) D: g$ R7 D& N    GPIO_InitStruct.Pin = GPIO_PIN_3;
9 t: ]) ?7 S! `2 K6 e7 y: h    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;( V. U: _! _) t5 M& u
    GPIO_InitStruct.Pull = GPIO_NOPULL;
( Q  @# s4 Q3 L0 D2 p1 i    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
1 m$ C5 S' _" R3 g+ i% j/ G1 s) x    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
+ L- \+ W$ P$ i' K" O: q& c  k; z    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);) n) e# q5 D# V7 X

2 j  \2 ^$ F3 g8 i! c1 g    /* Peripheral DMA init*/
- y0 u0 Q% w. `1 d1 k  
! P" |) u6 V) x7 K7 Y: f    hdma_usart2_rx.Instance = DMA1_Channel5;
( r! Z* }" O) l" X5 f    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
0 A' g6 F' Y) n* O    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;4 Y4 ~# G; |1 h0 q  U, q
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;8 ^- c0 {6 N% ^% P# U: D7 v0 ^. n; X
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;+ _9 @7 }1 n) v  h# B- ]' b
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
6 ?! }: P8 z% M    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;$ F: N, e" S! r& V" ]( k5 t
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
& D" ~& {# R6 E" A    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
$ k( B; H# ?/ |    HAL_DMA_Init(&hdma_usart2_rx);
4 C  i* u' W/ P9 U7 a! Z
5 R  R% i( A' i0 z4 k    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
/ w6 L3 c; U  M2 Y) i1 f& \/ y. C
    hdma_usart2_tx.Instance = DMA1_Channel4;
+ C% m6 e2 u+ |* @$ w$ R    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
0 |( {' x" J! T! K7 w) V/ E    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
9 |) |& E3 G8 x* R, P" o    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
6 \9 k' Z# i# s5 X1 b# ^    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;1 n3 T  F* U# S2 E+ A
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;6 s- w- m1 L. Z2 o; y2 X, R- k9 J
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;: o: u3 U1 p! ~6 d( W/ v
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
0 T4 w: G" q5 J) Z3 P5 A    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
, B- f* ]8 z5 y# G    HAL_DMA_Init(&hdma_usart2_tx);
9 @# A( w0 K( ^8 i/ G
5 z6 b! ^+ C  X- o! J# I; y5 S    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
% C6 u: L3 R  U5 R7 p3 I/ v2 T; x6 o6 l9 t! q* B6 ^' u% a
  }) h0 Z4 A& w9 V; i& D9 j
}  H9 H. }/ Z9 m* @/ F
% e; s0 A( [% [7 i! k" L% a
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
2 S8 E: r- g9 D" _5 S{- e/ T( L, N+ o: q
" @3 F+ A# r& n2 t
  if(huart->Instance==USART2)
. K: o7 y3 P. o0 F  {
3 h+ P2 {& f, r8 A    /* Peripheral clock disable */8 D0 h% N& F, M! Q
    __USART2_CLK_DISABLE();1 w0 u9 [& k" S8 W
  7 T8 W! ?& b1 y; o& Z, o4 x) k1 s. @
    /**USART2 GPIO Configuration   , g% J* q0 C! l/ D4 J' V
    PA2     ------> USART2_TX1 X. X4 a/ i! g% ]1 P: v
    PA3     ------> USART2_RX
/ \) W4 B/ s! g, F3 m    */; [) Z+ i- w" ^; j
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
4 q- l& N8 G8 ~0 V) f( o/ w5 |+ k0 a/ `( Y0 L3 m3 p
    /* Peripheral DMA DeInit*/
' G: q9 L! z# _; t" w% Z6 _+ S    HAL_DMA_DeInit(huart->hdmarx);9 a% t9 Q: E- }/ P$ T$ Z' X
    HAL_DMA_DeInit(huart->hdmatx);
* F8 F& j. R# z8 B8 T: K! D8 Y  }
0 @* D1 x0 h+ |* z}
, C' R" O$ V; y4 x------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------* x: d* u! H  x2 o* R/ D0 N
mpu6050.c7 _- w4 I8 a6 ~" T  v( G
#include "stm32l0xx_hal.h". k) Q# p7 p& ]% G1 l
#include "MPU6050.h"
# x  r% k3 E/ ?' M
: [( L  T5 D" A9 Q5 R) r' i//各坐标轴上静止偏差(重力,角速度)6 ^: ]- o" u0 l3 Q
int16_t offsetAccelX = -195;$ k' T, |$ G- l7 i
int16_t offsetAccelY = 560;
' Y0 g$ D0 N# A) n* gint16_t offsetAccelZ = -169;
# l- j5 r/ p% O( P4 f1 S; S; l% ]( b3 g- m7 p
int16_t offsetGyroX = 12;
) e; L" Z3 M3 f7 Y  _7 F9 H6 ?int16_t offsetGyroY = 33;  s& f" D4 l5 O# s: i
int16_t offsetGyroZ = 4;$ D* W; g3 |% w, V

8 m; d0 k  }2 F5 Z* T# W, n0 jextern I2C_HandleTypeDef hi2cx;
0 b1 ]' m* b3 K9 o
2 a9 l& _8 T+ |( |. Q9 }. d//**************************************5 E, Q2 h# e4 \- }
//向I2C设备写入一个字节数据
! Q) I1 h; P) e4 s/ a//**************************************
3 n8 L- e# d% ]void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
* a0 @( U6 s1 W- e1 h/ D/ ^6 B: P{, F' I* x7 ~6 E6 D4 L7 C3 \! v
    uint8_t rxData[2] = {REG_Address,REG_data};& I: c( E, W( a& `8 Q$ \$ X
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)' d# k0 G) h1 W
    {- B7 N; a4 ]8 [1 c5 l1 l
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 N+ _) g+ l; t( u8 ~8 H
        {}
' p" B) a# t# a  D7 w    }9 \& j+ e3 Z7 f1 V) j( M7 i- ^) e8 J
}
5 `; e: i5 k. q, k+ ~- L//**************************************
5 E( f( [" @4 Y# C% C; N//从I2C设备读取一个字节数据
8 W, q9 O2 Y/ ?" }# @9 O8 \//**************************************; I/ l# ^# X! N7 m
uint8_t Single_ReadI2C(uint8_t REG_Address)6 h0 Q: s& r3 E( f3 I
{# e+ x( D. A, `7 f% Q
    uint8_t REG_data;+ E+ B+ Q* N7 h+ C
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
* e5 S) H' @# X$ e+ m    {% k6 n5 k, `* x' o! p3 i( N
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
) @/ x# \% K) b. R0 [- f/ G        {}+ f' w4 K' k* Z) E0 j
    }
. f& e# H$ W! Y   
9 V' a3 u  R2 p) y7 t    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
+ \9 ]4 a6 U% N: g. s    {
1 J  a4 a/ d5 W: E        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)/ S: N) V+ ^6 Z0 Y# c* G! p
        {}
  o/ j! M. a# ~8 J3 E    }6 K: V: B: g% X0 t, x4 J  ?) s6 A
    return REG_data;9 _' D" V0 x  p# c0 `/ N
}) J# c+ x+ L7 x0 X
//**************************************& @% u* ^1 b' K
//初始化MPU6050
4 L. R0 n8 M) g6 j0 X//**************************************
' q% a' x/ v' x, {5 w' \" L+ @void InitMPU6050()3 h- S9 b% m# f  v! v
{" @; u/ u  l7 Q" v5 r
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
; v" j/ Z$ ^1 r8 B7 _6 U; g4 T; b: X* {6 U& s7 R) @
    Single_WriteI2C(SMPLRT_DIV, 0x07);
) n, j& L9 J  }6 ^' v
% f5 f: @: u# u1 b- z    Single_WriteI2C(CONFIG, 0x06);
# s- _# Q  A, w
# K3 l, K9 o+ h5 X9 _$ {& ^    Single_WriteI2C(GYRO_CONFIG, 0x18);0 B' h2 v' G8 J4 Q4 j, t. _

( X' ?) `, Q' _8 t9 L  D  J    Single_WriteI2C(ACCEL_CONFIG, 0x01);
, {$ k5 c0 j" G+ G}' A5 |/ m$ D8 B4 S4 j3 s
//**************************************$ z  C  C8 k) ?
//合成数据+ `3 `  D$ q0 K. a/ j* c. [; W
//**************************************# T  @6 \+ U" W% A' U5 T# ?. J
int16_t GetMPUOutValue(uint8_t REG_Address)
' G; W& o' ?; O2 ~: \. i{2 g) i2 m: y% |
    int16_t result;6 W: O& V- E3 ?: D4 E
    uint8_t H,L;2 c" i. M' \6 A" R7 Y
    H=Single_ReadI2C(REG_Address);1 v# [  _2 m/ F  A5 M9 @( W
    L=Single_ReadI2C(REG_Address+1);) Z5 H2 V( v2 y" D
    result = (H<<8)+L;
3 S2 ~( Y) `$ x    return result;   //合成数据7 n& j1 i4 V3 u- q2 g" R& E
}
! q6 T1 E7 s  v. r% c" c8 s6 t
0 @1 h8 w/ v5 L' \$ \% B//**************************************  e0 H, A% i- W2 w6 m
//取某一轴上的加速度数据2 S8 ~+ I- C  y5 B
//**************************************
9 `+ f' F2 q4 pint16_t GetAccelValue(char axis)& T3 \$ o: C* A, G; i" T
{
% n# h. I5 U6 c# _' k' L    int16_t result = 0;
8 l, c$ x! o: o  B$ w$ d  S$ \& h    switch(axis)
/ N% W2 F+ X3 s) I. X6 E    {& d$ ^6 E  F9 @
        case 'x':
' x  e+ G& h8 b8 y% ^0 g        case 'X':; I; w) O1 V" T3 J2 A9 {+ Q# c- d
        {9 T" P  j0 h& [% u0 B# F6 X
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;% z& u5 i3 {. J: H
        }
1 ?2 @( F0 ~* v& j' \        break;3 T, t! ~# S7 f/ h, T& d" v6 w* L
        case 'y':$ X' a5 V% H# P5 Z; G
        case 'Y':# o5 _3 A8 W: e. u
        {
; a1 I: h$ Z& _. p; A: |- K' {; N            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;. G, M0 X; }3 M+ o
        }4 j8 k9 s% X! Z7 E
        break;
! G3 S$ q  V/ `7 Q9 W% ?/ B; n/ i        case 'z':
" W2 k8 w; T( C- ~8 U; K        case 'Z':
; I: m+ Q3 I  j. Z) g# v        {
( b( c6 e$ J/ _& c! O1 g+ z            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
4 k# X7 P* |, ^9 |# @        }
6 e2 I5 d0 t& u8 D5 q- H        break;
2 E2 v! k, c5 @" D# B# E2 u    }
8 g2 F' V% L* w% I) \  |    return result;/ Q! c; [( o" _( r! M. q0 a
}0 F9 O1 d  i  \

8 Y. X3 J5 x1 S5 |5 G5 a0 g//**************************************3 h$ Q9 O7 \  I& P! w
//取某一轴上的角速度数据. H3 f; S! W1 H% ]# u$ ]
//**************************************
0 d1 ]" j0 ]+ Q4 {int16_t GetGyroValue(char axis)8 [6 |: I# c' G! \
{
; t" `& o# H' s5 K. ]    int16_t result = 0;+ h5 s% e% R; X6 Y* g5 Z
    switch(axis)
0 q/ V! v/ S5 H- r# q  r) N' v* \6 e& g8 K    {
- t. K) h; V) u* D$ {0 H5 S* \4 @        case 'x':& P6 i6 Y# z* R- P) p
        case 'X':
  u4 Q- @9 W. J) ^6 e        {
( k. i( ]9 J$ b            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;" Z6 }5 u4 M! Y7 f
        }
, a4 }- u9 D& V) S+ G        break;  n* {, J1 c0 q  q
        case 'y':& ?, ^( c  [, f  _) M
        case 'Y':
& r; b% u) E3 o( H9 W        {; n& f5 [. K0 ]( J( d& W
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
' i3 _  Q, ?6 x  T6 G        }
: G( R$ y, C0 _4 V4 O        break;" g+ j6 p# e" D1 Z; ]9 ]
        case 'z':
7 z: Y! _; P% M5 w" f, S6 W        case 'Z':
3 @! x0 I* W2 `4 x# X        {
( e2 ]* K& K) K            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;+ x* x+ A2 F* W0 @& B9 R( R2 A: z
        }/ g$ C" a- e$ e/ G
        break;# \7 F" q7 m. |" W& H% z; _
    }
9 T0 L) E: b4 o/ \: o( Y    return result;
& \6 z) h5 G% J  y1 ]' T}

评分

参与人数 1ST金币 +30 收起 理由
zero99 + 30

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)( w. Z& W! t2 m8 ~2 v* A
{; l9 U5 A, B' R" x: w3 Y+ T  h
% z) g& \* }" R, M* _; q
  /* USER CODE BEGIN 1 */8 i+ \9 R! V4 p5 y/ ^: T

  a) ]% t& ^, ^: p  _  /* USER CODE END 1 */
+ k. k+ \( e2 O, L: H5 W3 `# G. K0 P8 j- h! h
  /* MCU Configuration----------------------------------------------------------*/" i1 ^+ E6 M1 F8 k, j1 L; f
4 m. S& p$ i* C( B
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */( c% R3 \1 S% ]1 G$ _
  HAL_Init();
. [) H2 e2 b, x3 ?$ G0 ~
7 ^: c! s( r) A( Z( Y  /* Configure the system clock */
" o* V/ y, I( {' C' ^2 j  SystemClock_Config();
( p- s' A- k: G' ?$ e5 W) |6 O/ F( K; o& i4 i6 ^
  /* System interrupt init*/0 L8 C" E$ n- G4 P2 G4 v% N
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
9 s& Z+ H0 O4 w9 J
& o4 P, o6 d0 r7 \; }; q  w0 J$ l; |  /* Initialize all configured peripherals */$ k5 U% s3 B/ S9 J
  MX_GPIO_Init();
; ~" I, F( G: D1 c( c9 U% b  MX_DMA_Init();# \8 I' w, \$ j* r
    MX_I2C1_Init();
1 ^8 o2 u$ n- ?& n" l    MX_TIM2_Init();
9 T* s* I2 F/ ?* S& z+ ^0 `* u! W  MX_USART2_UART_Init();1 A$ D2 U9 ?8 A6 x
    InitMPU6050();% r: B( e4 B- L: y5 F# h
: y) p; C+ A0 s9 J
  /* USER CODE BEGIN 2 */
% I$ T6 N. Y$ Y4 H    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);! N. w. y& L  Z& h1 k& j- M
    HAL_TIM_Base_Start_IT(&htim2);
8 b- P$ Y! @3 w! s/ v  /* USER CODE END 2 */9 t6 U* F/ G1 @! g" o2 ^6 ~

* p- E- j8 O/ C  /* USER CODE BEGIN 3 */
' p5 j" }, K) \" C% _' M  /* Infinite loop *// ]) m% g5 d0 a9 P0 P1 G
  while (1)  _0 ^- e9 G, f$ w
  {  R, @. ?8 e: o' Y7 _0 u
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);' W1 _! R8 |2 b# N" `: _
        VisualScopeAngleOutput();# |1 `7 d2 U0 c% ]7 ^1 ^) T. r
        HAL_Delay(100);
" Q" o0 t* ]- X! \: H  }
8 a: S$ O; L6 R% Q5 v  /* USER CODE END 3 */
- v& J% F/ Y* j( p' q0 z( `; X- {% o! a* S0 y. `6 }
}" S' o* m8 f$ c9 E* l

0 G6 F4 l0 [+ w6 V/** System Clock Configuration1 x" o; A/ i7 {9 n9 `
*// Z, N( x/ C6 Q% D, k, z& Q$ _4 S
void SystemClock_Config(void)
# _# o. n, e+ ?% s: U{
1 D+ i+ `/ d& W& \" @  K. C: x$ I9 x; t2 J
  RCC_ClkInitTypeDef RCC_ClkInitStruct;! T: i* a( c9 y: V
  RCC_PeriphCLKInitTypeDef PeriphClkInit;2 j5 R  Z* e# B: t" H/ M  V
  RCC_OscInitTypeDef RCC_OscInitStruct;$ f" G; W! X1 M" R7 l

3 i1 X( ^! G4 A7 t" X& u) V  __PWR_CLK_ENABLE();, @  w* C. {0 }2 E: n& G" N5 i% c
4 J9 Q5 k5 A0 b# k, p; x$ W0 `
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
* g) n$ v7 T& W  P# a: `, i$ t9 x
+ }3 n0 J& A. t6 g( {  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  L, r! n2 y. N3 G8 s  RCC_OscInitStruct.HSIState = RCC_HSI_ON;! B- [/ j4 X0 z: g  ^& t; Y$ |
  RCC_OscInitStruct.HSICalibrationValue = 16;5 Z( Y& v9 J9 T9 h9 T
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;' Q* X+ X5 g3 R0 I* Y: H
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
% e) O! W9 M; @- i, p  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
! q# o3 U+ p, w/ M$ \  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;. t, \6 J0 h0 t1 I9 r6 U! Y
  HAL_RCC_OscConfig(&RCC_OscInitStruct);& n% t6 M+ U2 u' h3 t" ?
; w! u$ t5 }& G
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;+ b. @# S% v( {% R( R2 }8 @- K
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
0 y- w7 H0 G: Y  p* A0 F- Z0 C  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
6 H# n7 G( p9 ^) K) J3 [# K: g$ j9 j' G9 ~  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;: X8 L" v9 G! v: b7 ?
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;: c' \7 \  C; X) t1 ?6 S
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);" F( E6 S6 V) D  K0 ]
5 r* p- ?1 J* ]4 A+ t4 k7 V
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
+ P5 t* S9 S8 F5 h* N/ d  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
/ N. G6 V) @5 ?1 Z' r  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);- @& x9 @* `9 [- R- V7 e- ?" |

) X  Y1 h5 s5 M1 X) n) Q$ m7 z- I  __SYSCFG_CLK_ENABLE();
% P' a( W: x' S) i2 w7 v' A0 H! Y1 ^' w5 G! ~: ~$ a
}
) A1 ?( }6 I; X3 p1 @4 |. ]3 b
5 K3 n8 S7 [! F- [* a1 p! o/* USER CODE BEGIN 4 */$ b" p4 r. o5 B, A! I; `' U
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)& A2 ?8 B9 M( [  C. u  i
{
) [, T+ R; p; ]3 T8 ?2 v    if(huart->Instance == USART2)
' f1 o. Y* @3 W: t. M    {9 O0 C! v/ Y) k, A
        memcpy(txBuffer,rxBuffer,RXSIZE);- B0 s9 y! v# q8 X0 v
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
$ V" h* v- n0 D( `. F        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
# `! A% H- `7 S. _4 Y6 m' I    }
5 W2 f5 |) C8 f}
  l2 v7 @+ L0 n: N$ b8 [
; V+ E% I; k' Q. ~4 E+ Fvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
6 `) T1 a" D$ d7 ?- G{
5 [8 p1 W' T* S% Z: E8 m8 Q; m+ |   8 M: t5 c; ?0 ]! _( x$ m
}
6 X5 i& e) T; h; ~7 E3 `/ s
3 G; k3 e" i% D# Z4 ^. I, yvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  }6 D2 l, Y3 p) `  v7 C- `{4 ?  \4 n. i# U; Z" v
    int32_t GyroValue;
% G1 ]+ H; T  C, S6 N   % g! G3 K4 t# u; f
    Calc_AngleAccel();
" y0 U2 l8 l8 e2 g5 w2 a7 S    GyroValue = Calc_AngleGyro();( H& U5 d5 S2 F
    ComplementFilter(GyroValue);
$ P) ?# Z8 u3 @" p" y/ C}
foxglove 回答时间:2015-2-13 15:04:47
这么好的帖子没人顶,我来了
stary666 回答时间:2015-2-13 15:08:45
星辰一方 回答时间:2015-2-16 19:00:05
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长度不匹配怎么办?谢谢!
党国特派员 回答时间:2015-2-17 09:20:41
星辰一方 发表于 2015-2-16 19:004 ^0 z. W, ?6 q/ t  {& n7 ^
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

+ l5 Z7 o9 ]" ?& C' H' R使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
) u7 X* C1 M& }' L' J. u楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

% I0 K$ m+ i, C6 ~6 Y% o7 `如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间:2015-2-17 15:04:30
6666666 闲了我也玩一下
123tango 回答时间:2015-2-17 17:53:00
我也去试试
feel-376797 回答时间:2015-2-17 19:07:13
谢谢分享
星辰一方 回答时间:2015-2-28 09:50:50
党国特派员 发表于 2015-2-17 09:21
- {0 }7 V8 X# Q2 r/ h/ a如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
" [  |9 V$ j7 b1 V, V
好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
7 e! l: H- F' ?4 C请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:087 D! |7 F6 M; M, a" Y4 T9 U& U
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
1 v  e) }* K" m请问应该注意什么地 ...
+ R! v2 f# I; ?- S* A
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版