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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:( F0 b# J3 Z4 d8 |% r
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
6 V9 V1 @' I6 x2 u9 |- hmain.c
; c& B: K, B8 j#include "stm32l0xx_hal.h"
: T: ?( w3 g# l0 y5 C) D! s#include "dma.h"
( \( g* h  d1 W- |5 ]6 V" }4 g#include "i2c.h"
- N6 D, y' m) d4 w#include "tim.h"
4 N9 V8 r. d  y7 Z/ P5 o#include "usart.h"8 v# o7 [% |# Y% @, o
#include "gpio.h"
5 L) I5 s4 c" @$ o$ i) O/ y#include "mpu6050.h"
) h; h3 r) r) T5 S#include "visualscope.h"* v! M" ^# m) [: u: ^7 I

& B% \+ w8 @+ J, h( y, u#include <string.h>
8 l* e; y5 P) z! a" g" H, v#include <math.h>2 F2 p1 f9 H3 L1 p

* z4 k! D4 I: X9 H+ l/ |) l/* Private variables ---------------------------------------------------------*/) y. p( }: ^$ M# s+ z/ \# ]
#define RXSIZE 8
6 P) f! ~1 d$ s. p3 p#define TXSIZE 8% e+ A' j9 N# w
uint8_t rxBuffer[RXSIZE];) q( G. J" j$ W9 K$ I
uint8_t txBuffer[TXSIZE];
' H8 L, C$ e" E1 h: F7 A8 R( F" O7 h! d. k7 V7 c. y7 ~% p
float Angle_accel = 0;
; ^5 G5 @, u) a2 k+ T8 ~float Angle_gyro = 0;
( o- f/ m* v! v6 I' F* Sfloat Angle_comp = 0;
! K1 z, O7 I6 P. T: d- ]uint8_t outAngleData[10];
  i( o; {9 H$ k/* USER CODE BEGIN 0 */4 A8 P6 ]  G6 a0 ^4 k+ S

1 e# E! N% X* E5 p% F: @1 _! C1 m/*---------------------------------------------------------------------------------------------------------*/
. E' \" W: b9 J) ]0 Y- n( Z; N; W/*  重力加速度算出的角度                                                                                       */
6 W; T: F. A: H6 I- v/*---------------------------------------------------------------------------------------------------------*/
5 F* i3 ]7 O1 m6 g2 ]" aint32_t Calc_AngleAccel()
; @( X9 i. R" ?6 R5 q{2 U- X% _9 F! U+ q6 R- ]
    int32_t value = 0;
# U/ H8 S; ~$ F6 b* Q5 u1 ~: I    + J9 j  d3 q# v: s' r
    value = GetAccelValue('x');; `/ w9 f$ z# u( M4 V8 U+ F
    if(value > 16384)
5 B, ]% H: I/ G8 Q8 w7 n        Angle_accel = -(asin(1) * 180 / 3.1415296);- N$ S/ Z' ?3 e" Q) `, p& }. S
    else
) A: R1 ~- D; X$ @        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);% Q3 h/ s, V1 }+ ~8 K: C7 h
    " u1 S& c" Z& B7 j  X" }' I# D; a
    return value;7 j! n- D3 M" G/ t
}3 _) {. P9 e( e* F, W" z! D

5 C- m4 R& b8 Y" k' C, X$ F  X  w/*---------------------------------------------------------------------------------------------------------*/# H( I: x1 U0 Y& o
/*   角速度算出来的角度(积分)                                                                                     */; u0 v4 e6 z( t
/*---------------------------------------------------------------------------------------------------------*/
1 N. q1 Z7 ^) f& @9 D! gint32_t Calc_AngleGyro()& A1 `. l# [2 a+ z) G9 ~( x
{/ d  A/ i1 p& k$ M9 D0 ?# Y
    int32_t value = 0;
' h1 \% S& F; ]. v. E, N5 I
& T; P, s* ^0 M7 o    value = GetGyroValue('y');* F5 s& _. d5 A" m3 c
    Angle_gyro += (value / 16.384 * 0.01);
0 I  w  e2 O7 b7 @2 z  N/ W   
# w$ p) J$ e) g( K2 v2 u$ B    return value;+ E" I% W3 ~8 G. d! b
}
. v5 n. j& I- a$ b* e  i& Y2 d8 [+ {8 \6 T: q, q8 r
/*---------------------------------------------------------------------------------------------------------*/
4 G8 H8 R3 B$ h9 y. E, y& D/*   互补滤波求角度                                                                                     */
5 x, q8 h6 \: R/*---------------------------------------------------------------------------------------------------------*/
0 Q+ x* _& C. q/ dfloat ComplementFilter(int32_t simpleGyro)9 P  O, n7 e0 \: {( _0 ]
{3 x3 e) K$ O% q9 f7 B; ~
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
. I' H. o, y! E* b; O    0 G7 X5 r. U5 h$ u$ T
    return Angle_comp;
! c" {( O  }. q: T1 i* S+ T4 V+ E}
  ~  u5 H  H7 k4 o# c- a! I
7 d+ y5 h. s4 r. [# X6 ?/*---------------------------------------------------------------------------------------------------------*/) i+ D% a& ^  Y) _" g6 r$ P, y
/*   输出角度至上位机                                                                                     */
& x! G# q7 J8 m1 Q& ?3 }/*---------------------------------------------------------------------------------------------------------*/: a' z& v1 t! v
void VisualScopeAngleOutput()/ E/ C2 s3 T) |+ o4 c$ m
{/ g. _0 i) [; F
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;4 N! i1 v+ P0 w& D
    uint16_t crcValue;( z' O2 g0 L) `0 X
   
7 Z9 T. i* o0 K6 x    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);' o3 @2 ?& `. B$ _8 _5 D
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);  y3 h& C% g& p- F: M2 _
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);4 f: ]5 Q1 O+ w! h
    8 R) b8 w2 v6 E0 N
    outAngleData[0] = AngleValue_Accel & 0xFF;
& U9 m* t3 ]9 C    outAngleData[1] = AngleValue_Accel >> 8;5 P3 X7 F/ Z( P: O4 }# K& Y! y
    outAngleData[2] = AngleValue_Gyro & 0xFF;
6 O9 O- l& A' b- o6 S    outAngleData[3] = AngleValue_Gyro >> 8;
9 i) C! C+ u$ Z5 V( e# t2 h    outAngleData[4] = AngleValue_Comp & 0xFF;
& ]6 \: f9 }4 |' d3 M    outAngleData[5] = AngleValue_Comp >> 8;
* Z5 Z' [& ~3 T    //计算CRC5 ]- [! C" G# S/ X# w0 [
    crcValue =  CRC_CHECK(outAngleData,8);
! Z' w/ A$ N1 |* a9 G    outAngleData[8] = crcValue & 0xFF;" V8 W% a& [$ p8 O+ e
    outAngleData[9] = crcValue >> 8;+ T8 X$ i+ j5 @  V6 y& G
    //发送至上位机
' `5 `4 F! e+ C4 {    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));: f0 ^- F2 e8 I4 P1 L
}0 O" d0 N; s) A# j- y3 t: ]: H# v  O% Z
/* USER CODE END 0 */9 R( c7 w& ?( t" `

  g0 Z+ y- F- e; R/* Private function prototypes -----------------------------------------------*/
# ]3 L& U, t% p( pvoid SystemClock_Config(void);
7 A, M2 c% H# v  K; J, C, ]/ Q3 A# F! Y0 K: F

- _" x3 M8 S1 r' Y: P7 F. x- y4 w硬件连接图:/ J) c6 V  d) Z7 O# j
1.jpg 3 l& G1 S' I/ F' i4 M, l
波形图:
4 I0 R5 [/ m8 S' y% C 2.jpg 4 t$ M  [. o2 |6 m% a# F
最后加一个视频:
1 K. d* {  n+ x  X+ \: BSTM32L053 演示6 l. K( [; Y( ]: a
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C" R- _) u; c. t( o0 {6 j
#include "i2c.h"1 G* _! Y3 B4 M$ h% e( k. {2 _% q

% Q/ u+ ^( Z; e$ `2 J5 K+ Y#include "gpio.h"; `7 J' G. P( _* n9 e
: W+ c! O# C2 U% |, d' J
/* USER CODE BEGIN 0 */
  V- v5 |! \' B7 }
  }; {4 Q3 h* K3 y9 [/* USER CODE END 0 */
8 v4 D8 V8 g9 f4 w( Y/ H) g, B/ `+ ~- T( O, H7 a& z
I2C_HandleTypeDef hi2cx;
7 G) S7 k1 l; l& s! ?$ C( ^! q9 S
7 J- c& v. T& g/ w2 U6 I/* I2C1 init function */
3 T5 H; ~6 ~( ?# o- vvoid MX_I2C1_Init(void)# Y, ~7 a5 E" Y0 k3 ~) j# C0 K: D( X
{; n5 t  D+ f+ j9 A2 k

) G% C3 a2 v  X3 y  hi2cx.Instance = I2C1;
% x  P. B: ?6 W  hi2cx.Init.Timing = 0x20D22930;
8 W$ y( b( {1 }. X: E4 K  hi2cx.Init.OwnAddress1 = 0;9 R' R( c. e6 `% W$ v' H8 S
  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;& y2 V9 O- ]; u9 I. ?; _
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
; [2 n0 u7 Q- N. ~; v  {  hi2cx.Init.OwnAddress2 = 0;( m; Y1 p  I% s7 ]  ]/ \
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
" A/ s- d* _+ {  w/ Q2 F  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;  l- L  n. Y" ]* i- e- t5 j) F
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;* P( X9 W7 \# y% f2 W* s
  HAL_I2C_Init(&hi2cx);' U! D9 u$ T) p2 d

' b8 L: b( B. |4 l    /**Configure Analogue filter
5 f  C7 w8 c1 \% h8 N2 n    */# J4 R0 m+ r( y2 a0 K
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
0 e3 p( }' h9 k5 S
8 ?% j$ I- T, L) J, K. B2 n}0 ?" T7 }7 R) C7 d0 }
, L& D/ N. P2 D/ O. n$ H# l
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)5 w1 ]* o! W+ k( s6 y
{
: b3 X9 I9 P0 J2 x* t& M4 b5 n4 g. w
  GPIO_InitTypeDef GPIO_InitStruct;
# N$ n, g3 g& ~: z( x  if(hi2c->Instance==I2C1)! W1 Z2 X+ g. ~) T& l0 W# P
  {
5 G" M" x) Y5 t; u    /* Peripheral clock enable */. ?. G3 W- C: s. P. ~- k$ L
    __I2C1_CLK_ENABLE();  n0 q. A; X3 p' T) U2 s
  
. t1 B8 e) W! B& \7 Y5 Q  K    /**I2C1 GPIO Configuration   8 c  ^8 t* Y1 P
    PB6     ------> I2C1_SCL
& P; _1 w6 M( R; N0 v* r    PB7     ------> I2C1_SDA  }0 D, e; A* y4 z+ y
    */
" `8 x* V1 A4 Q( Z' v. u. K    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;) a; w0 l4 z4 |$ D
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
6 ~0 T! L) j$ r2 K' }    GPIO_InitStruct.Pull = GPIO_NOPULL;2 f! A+ J) X6 w! X9 W% B
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
) n6 ^5 t0 A; A# f5 A8 M    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;1 q# M2 \3 l' b/ S; g
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  {- A  W3 ]0 s& \4 |3 u5 h
# S+ y5 z  c7 C: p, f  }0 N$ f! ^+ j# G) V" G% t
}
% K+ J2 V* X  U8 b+ F9 p* k/ j& u$ @  n. J& \" @" m
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
3 d+ `) B$ K1 O  C/ h! Q) b- w{
* B4 ~( K' l- v$ V* z3 ?# g/ m& a1 X( W
  if(hi2c->Instance==I2C1)3 C* G8 I% Y& ]9 n$ [0 G7 Q
  {6 v0 [1 q8 q' J( M8 g
    /* Peripheral clock disable */
  t4 C7 u# m: u; @- ~- H" K    __I2C1_CLK_DISABLE();. z' J+ s6 q: X% z0 e
  
3 W$ @2 |  J) Y$ H    /**I2C1 GPIO Configuration   % T0 o; ]* J3 m0 ?8 n& d$ K
    PB6     ------> I2C1_SCL# L- M  P' B, V0 M# H
    PB7     ------> I2C1_SDA
2 U, H5 v) ~, x8 N, y    */
$ m% m8 S" u% o9 E3 c    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
5 m+ b. _" v0 ?9 k$ V6 e0 A) E( z; `2 i$ B# P6 A$ F. T4 M: a0 d
  }' `2 J! D/ Q0 V  [# s
}7 ~) @  X8 w+ S6 H/ y3 P
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
( R! n: L% }1 x1 m8 ausart.c7 s& ^. P& I/ G+ c9 B
#include "usart.h"$ @' q; L  v. j0 X, D& }; J
! j  o  M3 D; O3 A
#include "gpio.h": i" ^0 l' T$ H3 }
#include "dma.h"6 j  Q+ }+ x' l- U8 q( `# n. e" G

9 B8 l& L& _) ]2 I" r# ~/* USER CODE BEGIN 0 */
# B4 I5 A4 {- f' ~. C( V
* b3 n& F$ m9 \& ^/* USER CODE END 0 */% c' R  P" p# m0 w0 e$ r  }8 b
3 S, u+ v0 _7 K
UART_HandleTypeDef huart2;
; f& u+ ]8 }3 I+ [, oDMA_HandleTypeDef hdma_usart2_rx;
8 c' ~; [) d6 ]: X# f: [4 i* ADMA_HandleTypeDef hdma_usart2_tx;
  K. G0 V7 u! z) ^1 `. ^0 V/ Z
/* USART2 init function */
) ]% v% X* b" o$ l' G% v- n/ I
1 x* _, g3 a) N- D, p- }void MX_USART2_UART_Init(void)1 w$ m5 u: r  L2 t
{
, Q6 F/ T) w8 F9 H6 {6 }
% w( Q' d8 m0 x7 \  huart2.Instance = USART2;$ b- b1 N- g& M' M8 G' u
  huart2.Init.BaudRate = 9600;, [' S' Q; Q, _+ G0 F: ~$ |
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
$ \9 H. Z6 a  a  huart2.Init.StopBits = UART_STOPBITS_1;
7 i& U$ k4 I, ^8 f5 V8 Z  huart2.Init.Parity = UART_PARITY_NONE;4 i; I# B4 Y' n3 k; \, @8 c
  huart2.Init.Mode = UART_MODE_TX_RX;& C/ R* z4 k3 q  q$ M" \, D/ I
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;4 G  B. B7 A5 l: O
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
8 _8 y+ C. i2 u/ E  R+ q$ k4 h  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;& d& h" B4 G9 a/ B; ?% @) B
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;$ B  h! }" G5 b7 {: h
  HAL_UART_Init(&huart2);% c4 U: x4 D4 ^( E8 C/ x( n' g: N

3 P7 ]7 F- x+ v: Z! n}
2 O+ m& M/ k# `0 [1 M1 a! v3 h( d) ^) U4 K: h# r" q  K
void HAL_UART_MspInit(UART_HandleTypeDef* huart)0 r3 u! }# q2 ^4 {9 t
{# p+ @  c) ^8 B* }2 J1 o4 _/ B  o  f

: I6 h3 M( @9 T2 `; e. n  GPIO_InitTypeDef GPIO_InitStruct;  W& t# ?) a4 U
  if(huart->Instance==USART2)
: A  B' c: L9 z8 K% Y8 D& y  {
# Y9 w/ Z- F9 g) |    /* Peripheral clock enable */8 Y1 g1 I4 C$ X- Y" k9 ^4 o8 C# }
    __USART2_CLK_ENABLE();
& W7 ?% ~- G5 O3 p! C  & K9 N: j1 v6 L0 }& l
    /**USART2 GPIO Configuration   4 u4 S- m7 Q' \# k) e; d
    PA2     ------> USART2_TX
4 n$ E( |0 n% H1 X& n2 i2 `) H    PA3     ------> USART2_RX
- u4 z/ v* p; S2 v' J    */
' G: m- \9 d& `7 a/ u    GPIO_InitStruct.Pin = GPIO_PIN_2;0 t; M( |4 V3 x$ w
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
! v7 v, }0 d0 ~7 q  j+ j' e! q9 e2 w    GPIO_InitStruct.Pull = GPIO_NOPULL;
5 u0 s- ?7 Y" @* D( h+ l- }    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
* U% b+ \$ A% U# T# s    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
! r7 Y! U0 y9 m- d    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
; L- x6 s. Z1 V! L9 G6 K2 F  I: s- d5 l! U
    GPIO_InitStruct.Pin = GPIO_PIN_3;
+ g$ f. B" q4 p9 |" S7 p8 V    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
: j5 i; v5 d6 ]$ y* b- j    GPIO_InitStruct.Pull = GPIO_NOPULL;' x: t9 Y+ m8 Q* w8 v+ x/ v! \% {/ v
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;& W, w5 W# K% q8 E5 r4 i( t% Z
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;: c9 b; n2 ^0 m6 i, `
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);. _7 \2 v* G/ b8 W: c# Z8 z

# r6 ?6 ]4 `: L9 P9 @    /* Peripheral DMA init*// r- a6 o$ q, K" e: s# P# |2 [
  
* R4 T5 i! G. J5 b1 o/ X- m: X' O    hdma_usart2_rx.Instance = DMA1_Channel5;
1 a2 |! M) h/ h  M/ v# S    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;. h. A3 }3 v, s" |; u; [2 T2 m* B: r
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;0 Z, D4 N& b. ?" H. F3 f
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;& g; f8 b2 `0 h
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;; \# \& E, p8 x+ Y$ F
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;9 [8 |- E8 G- ^& R9 w$ W
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;: f6 x2 n  h( k% f( \4 T
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
/ a  N3 ]4 @* S3 n" G( G5 L    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;1 h& m% ~: Z% ]
    HAL_DMA_Init(&hdma_usart2_rx);
: h( ~5 K" ]3 A) r" `0 O( H6 S
! Q3 x1 ^) [- ?1 G6 H% {    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
; \4 p/ J9 u) k8 ~. B5 L' w# ^( \6 L2 q5 R9 O/ q: ~
    hdma_usart2_tx.Instance = DMA1_Channel4;
! f1 Y; }" I; q  W    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;- `) d9 q4 b5 y  n' f
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
2 Y3 T1 h' C4 o, N, R( i    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;9 Y- U7 A, @0 E* r$ R: n: H
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;2 q2 x$ B1 p  m, C, z
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
) A  {- m2 m- m9 {- ]$ F8 \    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
. @$ P+ }/ M* F0 ?' N' U0 Y    hdma_usart2_tx.Init.Mode = DMA_NORMAL;: T1 O+ A; B6 \6 R
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;* a( R, u8 ^; @. M1 q: ?. D) q2 z
    HAL_DMA_Init(&hdma_usart2_tx);9 b" q: D0 G* \( }+ h4 X- H

, X) d% j- O8 `2 M    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
; c# @* z# U* R4 _! h  ^' S) Z! d/ L2 {2 C( G/ W) Q  [
  }3 x, T7 ^1 Z; G% n; v3 i; O
}
" C4 r3 U2 n4 L8 ?/ V( _# k
! e3 \9 v0 Y  ]7 q7 Qvoid HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
, N* {. Z8 ~& a( |' q{
( B, u0 P5 ~2 X4 {0 U, w  K: R6 e
  if(huart->Instance==USART2)
9 F; I4 ^0 q* `; h  {4 y  r6 _/ k3 D; _
    /* Peripheral clock disable */
- x% }& d9 q. Y/ D4 R# }, E' f    __USART2_CLK_DISABLE();- v9 S3 c' U& B, N2 [6 J
  + |, }& _" T$ e' q. ^/ J: K+ c
    /**USART2 GPIO Configuration     c8 T2 A" p: {7 @+ u. M+ M6 U4 @
    PA2     ------> USART2_TX
- Q% H1 Z# Q' _    PA3     ------> USART2_RX5 b+ @( T' Z+ ^4 r, h
    */
" A) L2 n) T, D" l- k3 }6 l+ O: L    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
" Y: u6 @' s4 o& @. k& Q
; Q$ U7 n6 z! e1 k; a. y4 r/ L    /* Peripheral DMA DeInit*/! b# W( x6 o. `' @
    HAL_DMA_DeInit(huart->hdmarx);
' Z' e6 `( T0 {5 w, u- \+ y4 b    HAL_DMA_DeInit(huart->hdmatx);
3 X; Z- z' A" I8 C7 n5 e* x  }
$ W7 p- }# e; b8 T}* w# ~; [  Y, s/ `. Z% J6 m5 ~% \
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------3 s5 W2 ^& I+ E
mpu6050.c
  k7 L4 V; @0 E8 v- s1 x#include "stm32l0xx_hal.h"
& D0 y3 M  a9 i  ~#include "MPU6050.h"  @! k0 J! X0 r2 z& B; v: B4 s
- C8 L9 Y( E4 M1 y& c7 |$ V
//各坐标轴上静止偏差(重力,角速度)8 k9 T9 p5 \) V/ W. N% P" W
int16_t offsetAccelX = -195;
* i6 l6 B; B* c$ Z; \( z- x+ L, E7 mint16_t offsetAccelY = 560;$ w6 j/ I( \/ {" ^5 X
int16_t offsetAccelZ = -169;- o# V- |' N+ l2 X1 P

6 W8 _) q8 e5 J6 s8 N; T" z9 Jint16_t offsetGyroX = 12;
2 U7 J3 y8 b$ Z# P4 ~int16_t offsetGyroY = 33;+ [5 q% |2 r; e6 ^1 C% }5 D- P# Q
int16_t offsetGyroZ = 4;1 f+ ^& Y* i/ S: ~" q
7 Q$ k4 V* ]! T
extern I2C_HandleTypeDef hi2cx;! P1 ^2 w5 i% m7 h, o9 g6 y

6 N3 k$ g. C/ L7 y  q' G//**************************************
3 Y( G8 X) _! D- _1 }//向I2C设备写入一个字节数据# S* B, B5 D& y# I
//**************************************) n" j  }0 m" U4 F' z. l
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)% S$ r  ^4 q* `2 Y1 v6 B7 l
{
3 T8 R( z9 b4 ]4 k. L" h    uint8_t rxData[2] = {REG_Address,REG_data};
9 A0 d) c# T& V% T    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK); K3 |, E7 A  Z+ {" j% Y5 }
    {0 z4 b4 ?5 ]  ^: e
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
# z3 l/ Y5 r2 q) }% |& }7 b        {}) l5 L! G7 P1 D: s- B% d3 {+ a
    }, Z4 \4 O: |" E) D
}
) }9 C- a, _& Y) z) a: k% w//**************************************, D1 |) O& `7 p
//从I2C设备读取一个字节数据9 n0 q$ e! l, U' M6 w* ~* z
//**************************************
, G# g  a8 k/ b5 J  x( M: ?uint8_t Single_ReadI2C(uint8_t REG_Address)+ {0 K7 ?& L9 I* g& Q' A
{
4 W# E/ U1 w' W  e. g: W    uint8_t REG_data;
8 M# E9 p  D" ^+ \1 v( }' L    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)2 o3 @1 O0 L1 S' M8 {! u
    {
- i+ w+ ~( u% f        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)* C3 a$ z. Q8 l. \) \- G
        {}
# n/ P  {3 L: f    }, `4 O: n  P) @7 }7 X  }
   
, Y# M+ V: i; _6 P$ o' D8 B    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
) @, Q! E, R' s. r    {! o4 R0 i3 ]- R8 z% j
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
. W1 v1 e" U" [0 I6 |        {}
' V5 {! L: z; m2 f    }
5 C/ s0 a# N( ?) Y( l    return REG_data;
5 h) p+ s5 l$ d' ~9 j7 X9 }}
) W, B' x8 [, [//**************************************
' ?: h. k& U% A# ~3 t1 b//初始化MPU6050
: f' w7 W( T: M- K2 o//**************************************
- ~7 y+ i& p3 C- `% |" P2 {4 `void InitMPU6050(). C' J9 l! Z- J0 s/ S( K+ m. O
{
( l5 Q- b5 ~3 ]" Y7 ]1 l    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态" i0 [: k- s( J2 U
% s* Q- L$ Z5 l2 l1 d
    Single_WriteI2C(SMPLRT_DIV, 0x07);- H3 {/ p" `2 Z* U: M* ~% r
2 v- m0 _5 A3 ^8 ^5 N. s$ U
    Single_WriteI2C(CONFIG, 0x06);
- A& ]% [+ a0 G* ^) O) p6 S  z: e
  I) }+ y; @. D+ H5 }* e    Single_WriteI2C(GYRO_CONFIG, 0x18);
4 S- x* [& I9 C4 d: B
/ d9 x! i" d1 ]1 C- c) y    Single_WriteI2C(ACCEL_CONFIG, 0x01);
, [6 Q% b; V' ~: F- a}
9 T. T- b) C  A1 U; I: I0 b//**************************************
$ _/ l7 F9 T; D3 J  T* N//合成数据6 l2 l, X0 W! g# [+ E
//**************************************4 l: I; E( R: e, b- r( |5 o
int16_t GetMPUOutValue(uint8_t REG_Address)4 N" L' m+ q6 `+ X+ M
{
" k9 d" V- s) _% ~8 |$ i    int16_t result;
0 M" z% T5 ^: L    uint8_t H,L;! y8 k6 q: L, E4 ^; X2 {- b4 M
    H=Single_ReadI2C(REG_Address);  h+ _9 h# O/ ^! s% a
    L=Single_ReadI2C(REG_Address+1);
  h! n0 {  k$ ?4 L% h: M3 K    result = (H<<8)+L;$ z* ]9 u. @4 r/ L
    return result;   //合成数据% B. Q8 w8 i& d* _/ n/ S
}( @5 s% _; `# i% K5 K

3 w+ W& X4 p7 y/ I. H1 s8 s! e& u/ Q//**************************************6 D4 O" K8 H$ O2 {
//取某一轴上的加速度数据
! F3 [: k* b( d//**************************************
% w& _' z2 T' L" A8 Nint16_t GetAccelValue(char axis)
% Q4 ?0 l8 \9 y{, }+ h- @- A6 s& V" p
    int16_t result = 0;
( \2 V0 Y. w* q9 @4 J    switch(axis)
0 l/ _6 X7 _5 |9 g; e0 [    {
, n: w0 c7 D% N        case 'x':! _# t& ]/ w; B& V
        case 'X':5 I9 \  U6 `0 R8 ]- A* W
        {
: Q1 b+ M! R; M* V5 \7 V& ^; w- l            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
- x- H& I4 S! c9 r! F) e' S        }+ r0 |1 D' j( j) {* W" D* ?/ x
        break;
) g8 U+ L) m0 Q/ @/ D        case 'y':
+ w# \+ x8 {' k; \: Z        case 'Y':
+ O6 G1 B# y$ t% b$ ]1 x        {1 E; B! s4 g% P& L/ C4 H
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
$ u) D) h& t. v4 i        }& g1 T; c- u$ J4 o6 Q( x
        break;
8 O7 t% ^6 [& v' ?: X" y: ?        case 'z':
& @" Q1 j& [- U' ?/ e. i' Z        case 'Z':( _( w' E) B  Y8 \3 |
        {, t- e- V" K0 T$ \
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
$ N* Z( x6 b9 k) L9 n2 D        }4 \" e, b# ~: t( Q8 c/ D( N
        break;1 ^# B& d4 N  P2 a6 ~! N  Q! d
    }
/ Z% r! V+ h) H    return result;0 Q8 x3 j8 W; C5 V. C2 e( {) O
}2 y% _- o4 M  A* z0 X6 w

  L& g% e- S  h  t; c# y//**************************************, @( t# C0 t/ n1 i# m% g5 n2 `
//取某一轴上的角速度数据
+ v; Y7 S+ {1 m$ [//**************************************: i: q& B' U+ i* s3 M" G; z0 s* @
int16_t GetGyroValue(char axis)
" W2 e0 K+ W; E{+ }% [  O% {' G+ ]/ G7 z$ k
    int16_t result = 0;0 D& M: p( Q' Y3 l; k  g* a% @
    switch(axis): c( Z9 x1 n* Z0 a1 ?. ]
    {
8 F$ e/ I3 `2 m# n        case 'x':
5 F' O' T6 h( O" @  ]        case 'X':2 e, q, D2 z( r0 {( x0 ~% p2 l
        {6 O* F6 u- o" V# D$ i9 c
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;" |, o( z* N3 k
        }8 B1 k# j$ q  Y; B* d
        break;
6 B" a% E  u, c& t6 g/ S5 l% r        case 'y':2 ~7 z# T2 h3 K9 q  Q, ?1 Z+ \
        case 'Y':
# _" b6 x7 p& s; N0 N        {  z7 S/ M7 U$ M/ i
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
+ b0 R2 c7 [! r" w% [: [        }
1 b7 }  V. Y7 K  w4 P! [1 X4 Y        break;3 G* j, ?; O/ @6 X' }8 G+ N
        case 'z':
. ^- [" e' u3 [1 g6 q        case 'Z':
/ k2 V5 x7 Z- q8 E/ Z/ @# E        {% r8 G0 x! G& g# j1 |7 t* C# E
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
" Y" x: V" s' Q% R        }
' q  d* @5 S$ l        break;
( r2 b0 B3 q7 l; o    }% C0 S8 M9 e) p
    return result;
+ b8 c" C' t3 x4 e- P+ ?% i}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
& z# A- \8 J" K" w{
' O- w) R4 L- B; _! d6 z8 D, v. K; x* P/ X4 ~$ e8 ]
  /* USER CODE BEGIN 1 */0 e- c8 F9 }9 ]. G0 @$ l

% H* f" d" K/ H# C& g6 l( }% m4 g  /* USER CODE END 1 */8 r# q8 h  I1 P9 O
  J1 {1 R4 t9 s. e. Z- O
  /* MCU Configuration----------------------------------------------------------*/
3 w* @; L! n4 R3 f; I
9 t# f6 ^) A3 K' W6 }) l  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
, x$ W! s- Z8 c2 J5 v5 x' D0 x8 D  HAL_Init();
+ ^- r& `1 g7 U7 M7 L2 [, R" \, V& I& q# g
  /* Configure the system clock */: p  V& }& ^; C
  SystemClock_Config();
; _$ X4 L7 w5 M( n$ ~
' _4 p* E8 F! b  /* System interrupt init*/3 Y3 @5 R! Q! Z- y! U
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+ {& {' {3 t/ s% r/ |4 c2 o" N! i% M4 ?: I5 a8 K7 E
  /* Initialize all configured peripherals */: T% X) k+ I7 q# V0 g' g2 F. I
  MX_GPIO_Init();* M4 M. c, ^, Q- ~
  MX_DMA_Init();* U2 [' D1 W, v6 O+ P
    MX_I2C1_Init();
2 b$ D8 r+ g5 v3 @    MX_TIM2_Init();
1 h5 g9 y, d2 F  MX_USART2_UART_Init();8 P- d' z: U5 d- E) z
    InitMPU6050();
+ B" Z6 F  n6 v/ z9 K: p4 I" d" C7 {! |& t" [3 |5 M% ?2 ]2 v
  /* USER CODE BEGIN 2 */
- }  N! ~4 r% N& @+ m    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);. E5 S" `! U* H' n9 Z# K- D( E  w
    HAL_TIM_Base_Start_IT(&htim2);
/ |# ^+ I- ?: u/ [, T  /* USER CODE END 2 */8 N& ]$ U5 u# ?5 [

, l( P! Z) Y& A$ u& }7 i  /* USER CODE BEGIN 3 */6 h( I& T& C/ \" ^
  /* Infinite loop */
+ v1 T4 ~. {1 S, y+ K- e5 r& F  while (1)
; Q8 B. ?# Y0 D$ ~2 b  {
; |2 J; N9 v2 J) \        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);( @! d. o  ^+ ^3 D% \! [/ M( b
        VisualScopeAngleOutput();
9 i( Q- x  N3 C8 _9 w( [, @4 J        HAL_Delay(100);( h' G: A) t. ^& ]
  }
/ H+ I2 S% b4 `& u% O1 w+ s# D  /* USER CODE END 3 */- d; O: G. h( p" \( C

" Y+ N! v* t! f, ~  o' @}- [. Z$ ^  ]) y2 K4 e
3 u+ u: w/ u  D; G0 S
/** System Clock Configuration
7 K( A2 b* G  o: V  W; F*/
1 o/ v# I& b8 ], U* g; y6 }% rvoid SystemClock_Config(void)' {; f; c9 v. ^( l5 ^) i
{- m1 s8 s, K' t2 j$ \7 U

! i5 `- V' L5 ]( |  `6 m* s  RCC_ClkInitTypeDef RCC_ClkInitStruct;5 Q* i* {, e, q# T. S! Q
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
2 }8 `  v8 U. B/ A( _  RCC_OscInitTypeDef RCC_OscInitStruct;5 U  l* l8 o1 f: l; L  A- v$ z4 |& P
/ }) v3 |5 b5 v- {2 E1 _2 v' h
  __PWR_CLK_ENABLE();( O. }& u- w* D' D5 V
' t2 ~/ U" m$ p+ i( M* n
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
4 [5 A8 C* _4 p. s
) m" v! }9 T$ ?4 n% b: B  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;0 k: u! T1 @* e, r: j
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;$ t$ J: j# a( u) R. h
  RCC_OscInitStruct.HSICalibrationValue = 16;+ [3 U  p/ `& ~
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
5 U; I2 K6 s. \& v  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;- {3 a9 H/ j9 Q, _* x  R- I& L
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
5 ~7 ?+ e/ `' w  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;6 s# p" E, i+ l9 G: E5 `
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
* M5 ~0 K/ Q/ j7 u# c# I  c7 r1 f7 M( k, b
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;$ Q8 ?$ {* p/ U5 m% G/ f
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
/ p9 q4 I8 ?5 f, ]! H# }  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
. Y7 U9 Q4 j% |0 f  K) O# Z  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;; o' I% P( Y" S/ G0 F& a! X8 I" B
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;+ p! X2 C# L' X1 n1 ]) S
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
3 ]9 ^$ f9 j  U5 Y! w9 N% A3 o' {2 a9 r
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;% E* J/ w/ b. {5 D1 f
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;& u' m9 e/ E4 `/ h, W: M0 F
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
/ Q  Q1 L7 _! J3 _, E9 ^2 \
% C! z0 {. z% y5 q( g  __SYSCFG_CLK_ENABLE();
4 t8 H& K4 `" A& F3 T/ T1 n* h7 x, y8 `! P
}" u- }5 J3 ?( v5 h  Y; ?
: z- F; }/ N+ k3 y' t
/* USER CODE BEGIN 4 */  B- f$ z: C9 k# g; g
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart): p; P  W% h5 K( K, d
{
0 E; a5 L* H% q8 h2 F' G6 U    if(huart->Instance == USART2)
/ a# b( Z6 e% Q& v  B# C! a    {
7 P" g# a# ~6 j        memcpy(txBuffer,rxBuffer,RXSIZE);6 ^9 l5 X8 x' S
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
. }" t# m' p9 k3 I: e& X0 g        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
& B7 I  s8 A8 C* N% T    }
/ w) M1 {+ {; p6 I/ W}' p: d8 ]0 v$ k$ A3 N8 _! u. _( B
7 g5 P# R! b3 I* ?
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)' J* ]% z4 y3 X5 U4 Q) R
{# _2 g+ M( J4 S% m" M9 D
   
) J- j& D. g5 s6 l" s}2 f9 m8 g5 {; K; Q6 {& `7 B  j7 K

3 U- _* }7 B9 L% G: @void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  a4 u6 z- ?2 G! f8 p2 E{  s9 Z$ a0 N& d2 {& q
    int32_t GyroValue;
. ~+ S2 w3 o0 V8 w/ ]7 z( R" t- |   9 ?" x; S7 H6 u$ O3 y
    Calc_AngleAccel();
* V+ l& V0 W  `    GyroValue = Calc_AngleGyro();
- r! V! G9 Q/ s    ComplementFilter(GyroValue);
% y: Y1 f" `- v- I}
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:00
$ n# J( i$ _" Y  e0 w9 T$ J8 j. M- |楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

* ~+ ?$ x/ y2 x  {2 p4 I8 u" z8 U使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
* y% G* u, L6 n( C- {楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

6 n: L% _7 F; a" O6 r  J6 R* e" Q如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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' J/ V- D1 h8 q
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

$ V) k4 s( A8 A) m7 b! A, `6 ?, f好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
: o7 R3 x8 {. N6 B# x请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:089 R6 H+ Y" A6 a
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?* |% [) @, [$ ]$ s2 `+ o
请问应该注意什么地 ...

- ], O2 i6 U( w! d我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版