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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:  M* p- T2 z* B4 y2 S& I/ Z: ^, m
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
. }/ h9 R7 s5 ~5 b& I+ g* p0 fmain.c
$ L4 L  c5 K7 n# D#include "stm32l0xx_hal.h"
4 P1 x, K4 f8 Y' m3 e8 L+ R#include "dma.h"
5 t& {5 _8 D* S( [6 n4 U7 i. ?#include "i2c.h"
# F+ U9 Z! g) @; u; [3 N/ M" |1 F#include "tim.h"5 Y$ r- g( i& d$ X7 q+ v
#include "usart.h"# `+ D0 S/ d3 A7 m, f0 E* Y9 I
#include "gpio.h"
4 P4 c& _1 y/ ~7 ?#include "mpu6050.h"
' y9 s1 e( r+ [. p* k. H#include "visualscope.h"
1 x: T1 ^6 `' M! k
: h5 h$ _+ b8 }4 M9 Q#include <string.h>
' O5 r/ o9 s* M+ p/ n#include <math.h>- @7 T& B$ d( j8 J+ |
  X6 k, h) R+ @5 D4 I
/* Private variables ---------------------------------------------------------*/( K6 {, y8 B7 u
#define RXSIZE 8$ {5 c$ [* a2 D0 Z) u& A. q6 Y
#define TXSIZE 8% r1 Z- T. F) {7 h6 |5 a" x1 t
uint8_t rxBuffer[RXSIZE];
% W* k$ }6 O8 U- q# @  F. v) vuint8_t txBuffer[TXSIZE];. b( F/ Z* U5 v3 J+ v+ M/ M

& O4 |2 W  u& a6 e3 {# |5 ^float Angle_accel = 0;+ Z# O& j9 r# b4 q* e# o
float Angle_gyro = 0;
" f# t% U* S' {3 g! Dfloat Angle_comp = 0;
* R% s; G7 b- N7 w) luint8_t outAngleData[10];
4 ~: h& R  q! E# g& o/* USER CODE BEGIN 0 */" E! u9 |/ `+ n& K
0 q) r* T: K0 K! I
/*---------------------------------------------------------------------------------------------------------*/
9 ?, I1 {( z* k: j7 A4 [# m+ G: B  [/*  重力加速度算出的角度                                                                                       */$ i+ k/ a) s$ y0 ?( P8 i/ s( ?
/*---------------------------------------------------------------------------------------------------------*/9 ]) r2 ?) N# P* o$ R$ |
int32_t Calc_AngleAccel()
" h* i) n3 o4 \4 w+ S# h{
  m8 A; @" T# W% I# O; G    int32_t value = 0;+ W4 v7 w  O5 e4 u4 s
    ( Q) j0 n9 {7 g3 g5 n" U
    value = GetAccelValue('x');
+ G6 F  N3 L: B/ ~7 [    if(value > 16384)
: ?& `) r$ C" ?& @! }& {$ Q        Angle_accel = -(asin(1) * 180 / 3.1415296);
' Z! R' |% B/ x( N    else# b8 L/ O% @' x: g
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
; S" e- h7 S6 |    8 e& ?! f: e7 }. Z4 p
    return value;* [. e% {  G: F/ A
}
5 `9 I' \* J8 I) e1 p9 l1 T8 I1 ^) m7 q. e8 A
/*---------------------------------------------------------------------------------------------------------*/; R9 h/ W8 _" a; A' \
/*   角速度算出来的角度(积分)                                                                                     */
# \- R) i2 u! t3 @4 k7 ?. w/*---------------------------------------------------------------------------------------------------------*/
& F  @. R( q- ~9 `" n* x2 wint32_t Calc_AngleGyro()0 }" y! B9 p% G, _
{
0 m- \( V/ H+ @+ H7 w4 q" S) r$ ?7 g    int32_t value = 0;
) h: S- w7 B, g) V) b! `5 Q$ d( M
% x, O  B1 X6 R0 v) A) `: |/ ~    value = GetGyroValue('y');
8 p5 ?) |" H4 b, k3 Q; K    Angle_gyro += (value / 16.384 * 0.01);
/ i- r1 Z1 _0 n5 x( ?4 w    4 L. O2 F8 |2 y
    return value;
) C. H1 \% m4 w3 u3 ?}
& |& \4 G" q$ o. T1 d
4 t( v! A( G: ^5 A4 N8 m2 ^" |/*---------------------------------------------------------------------------------------------------------*/5 W2 {* E7 [4 d5 @0 ^5 ]/ D- ]8 r
/*   互补滤波求角度                                                                                     */
1 T' x# J+ M  t* m  L1 ^/*---------------------------------------------------------------------------------------------------------*/
3 E8 U. `4 ?$ r: {% M2 gfloat ComplementFilter(int32_t simpleGyro)& A* f) Y" l& Q" b6 ?  Y, X" }
{
: [# o9 ^; _0 d  E  s& `6 j    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
6 E0 h' C0 q8 ]$ ?   
5 |% r$ J1 S- m" q    return Angle_comp;
# N: i' h1 [# O4 y}
* [+ g; V: `0 B
/ \9 Y. ^/ C# s/*---------------------------------------------------------------------------------------------------------*/4 F8 b) i: t: ^( L  I, N& r
/*   输出角度至上位机                                                                                     */" j9 R% B* @* j9 t
/*---------------------------------------------------------------------------------------------------------*/) b% J  M: x  `3 q. \" Z, m) u
void VisualScopeAngleOutput()
% F9 B7 S) W$ w. I  s. P6 f5 n{4 D* N: n: S6 V$ s
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;! D( n. h- j; e! _, Z
    uint16_t crcValue;
5 D4 O' m0 X7 B8 Y9 e8 @% Z0 x1 K    - t* F/ l" p% i
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
( S: C5 U5 q% A* P. }    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);! W+ K0 u3 }- G9 F8 G
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
) ?$ ?8 P0 c+ l6 |8 n3 f   
' m! W  @2 S5 r9 T3 s- R8 `    outAngleData[0] = AngleValue_Accel & 0xFF;
; [* n" U# A  L- Y4 J) _    outAngleData[1] = AngleValue_Accel >> 8;
% j$ v. ~4 K9 q% F8 T    outAngleData[2] = AngleValue_Gyro & 0xFF;
  O1 X4 j0 y+ f5 `7 n2 n    outAngleData[3] = AngleValue_Gyro >> 8;. G- s2 I% i5 B7 w. R  s6 t
    outAngleData[4] = AngleValue_Comp & 0xFF;
, K* Q1 r+ ~# P0 [* _    outAngleData[5] = AngleValue_Comp >> 8;
; Y% x* ?9 c+ j    //计算CRC" \4 ], L4 b' t. K' B" ?7 r+ |5 _
    crcValue =  CRC_CHECK(outAngleData,8);. x% ~$ f3 _9 j1 j4 F1 T/ n. [4 {
    outAngleData[8] = crcValue & 0xFF;
* a# n! A( m# \0 p4 o    outAngleData[9] = crcValue >> 8;
; A6 Z9 C$ X6 s- E, ^. N    //发送至上位机
( H' U! v8 e" F( _5 j$ u6 o    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
; u2 [/ r9 e, ~' n& n- b}' g/ w4 Y# w+ k# @
/* USER CODE END 0 */* G+ R9 h' f9 u$ ~7 S- h
) q3 g" U; m0 v
/* Private function prototypes -----------------------------------------------*/
( j+ G0 T+ E3 x( H& m: ~void SystemClock_Config(void);- M+ z7 I6 b' f2 U  g- D8 E
( Y5 S! f( q5 h! k  q  B

' h7 r* K$ \" j9 @" B, k硬件连接图:
! E  g  B4 \! P9 L 1.jpg
. {/ z* P- o  Y( A0 ?波形图:% _* f! ]# k2 O( d; B
2.jpg
/ A  ~3 e9 l3 E+ @最后加一个视频:  O3 ?$ J* @, h% [' s" P$ q
STM32L053 演示
; ~1 Q) y- R; Q' r9 C
赞 1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C5 L  D: L, n9 d! [+ Q
#include "i2c.h"* w, L0 }8 O: j  r7 j* P2 \
5 e" T8 @6 _; I* h
#include "gpio.h"( B& ~# `7 z- H5 s) e

3 U0 B2 W5 J, H  [/* USER CODE BEGIN 0 */
# \! `. \1 U1 L+ {
8 K  W; k3 D7 w$ q) `/* USER CODE END 0 */
  ]* T6 e# f; T' n; x1 {) S; m9 g% f  w# `
I2C_HandleTypeDef hi2cx;
3 x, F- }8 K  w3 ?1 |
  ]5 M$ f3 Q1 g3 ~8 d4 K/* I2C1 init function */
  R8 T5 M- `& e- H. f# |void MX_I2C1_Init(void)
' b+ V" U  ^3 W" p, m2 u{
2 e: M- u' ^! ~" @! {2 p( N# C2 u  z! V' y, m4 }$ |
  hi2cx.Instance = I2C1;
& M. ?- |& G( [) ]+ ^7 R  hi2cx.Init.Timing = 0x20D22930;4 o" n$ A+ {; P
  hi2cx.Init.OwnAddress1 = 0;
0 _) a5 O, i: |1 @4 k# Q9 [  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;0 _5 X  T: m/ a. }; V* L+ l
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;9 n: S1 F0 T: c
  hi2cx.Init.OwnAddress2 = 0;
' l6 w& p. Y+ a! f& U4 j  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;3 b+ u. v6 M" |$ f. t5 @' k& ^/ a
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
- }) S: o' b8 O9 q  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;! f4 ?# _+ Y1 U8 g4 s% ]/ L7 \
  HAL_I2C_Init(&hi2cx);
8 L4 i# k- E2 N  F
0 ^) N: q8 V( Q# W/ I    /**Configure Analogue filter
) n$ k& J2 Y$ \2 o    */& {% N5 v- P( W" \* j) c1 _5 k
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
2 `! K, o# X2 v1 f) @2 \% S$ c$ ?
4 D( J" K$ P) A}* U' ?; z2 d" G" a% q
( n# ~- G# j+ C- F+ T' N7 b
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c). r9 D7 \$ X! X- _
{: }5 |# h: f' T2 Y

' d) e( A1 R% D( s* c  GPIO_InitTypeDef GPIO_InitStruct;
$ T0 J. ^. M, C/ l* n  if(hi2c->Instance==I2C1)1 j* S8 W% @* b# R1 U/ C& a
  {
+ ]9 Y: M9 o% }& u) }! C. d    /* Peripheral clock enable */& ?9 I0 U3 x  S6 ~
    __I2C1_CLK_ENABLE();0 Q$ ?7 B) E( I, Y3 F
  5 L' [2 r5 O* [- G" V+ O& q: f  q, l
    /**I2C1 GPIO Configuration   
  j" M, i- _3 O$ @    PB6     ------> I2C1_SCL
* {5 L. h& N: ]2 u) c" V    PB7     ------> I2C1_SDA2 Q% |/ F! x6 K4 L* c7 S$ a
    */
6 l; a+ _: u. C' D    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;" [6 X# K+ x1 B% @6 }, W9 M
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
# r5 z4 B7 j' o9 B. W; }    GPIO_InitStruct.Pull = GPIO_NOPULL;/ o( S  a7 b5 x; A9 N$ F
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
' e' B2 ^5 b1 @  M% O" O" j* U( T    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;/ G. s+ b2 [5 Z: A
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);0 u# H' \( @% o
/ a8 b7 O7 o5 y) v) f6 v
  }: |, ~  Y4 A0 x! e9 d& }
}
1 T7 c8 R) }- u* [2 P
! V% ?3 H) F% A8 n1 p! lvoid HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
% M: I& V: c$ `  \7 g2 ]8 D" M{
6 `* f; H1 |* ]5 U5 g2 ]- I2 C
9 Q) o" s  W8 p* B1 ?5 A& K# I) @0 V  if(hi2c->Instance==I2C1)
% d* m) ^$ W4 h4 O. j: `  {
* S( P5 [# H& E$ j    /* Peripheral clock disable */
/ P4 C" Q# U* ~; }" f    __I2C1_CLK_DISABLE();' C7 L5 ]- z  h3 J/ n
  / N4 o. I, X: @3 m
    /**I2C1 GPIO Configuration   
; R4 P. b3 ?( x% D$ h    PB6     ------> I2C1_SCL- z, ~4 w  J$ N, y8 U" b
    PB7     ------> I2C1_SDA- U& P  H9 e4 L0 \( s
    */. Q: e$ v6 h7 i8 Q+ h2 M2 M8 B
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);$ R; W3 j  r) U% e* ]

: Z: _, S- R+ \  }* _1 ^3 I. W# \9 u8 L
}
$ x) @6 ]; D+ c. _------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
7 P, n6 r9 J0 u6 Uusart.c- v) K7 G* d- c- {
#include "usart.h"
/ O/ a5 x6 ?6 U3 _6 I# L6 L$ F. e5 |% Q1 n" o3 s+ m- L
#include "gpio.h"3 V9 q6 M# Q$ P6 [) y
#include "dma.h"
9 c6 ]4 v5 m' r6 u3 r
3 F4 k8 |& b/ y/* USER CODE BEGIN 0 */
( s8 P' Z& E# v) u5 y
) f/ a0 s; S& y/* USER CODE END 0 */
7 C: _" _. Y: I. ?: }1 Y' I$ c, P" k, `$ g
UART_HandleTypeDef huart2;
; c- e9 I$ M" i8 L1 y  t5 {DMA_HandleTypeDef hdma_usart2_rx;
$ `* J" I+ `5 K9 Z6 c! ~+ ~DMA_HandleTypeDef hdma_usart2_tx;5 h3 n; G- J$ H9 }5 k; m

6 N6 i* N. _. M- T6 g/* USART2 init function */6 p" B8 _8 V2 }! B

' @5 p2 n' I& u7 \void MX_USART2_UART_Init(void)
6 ^( C4 e' c4 ^- {1 t% d4 K' Y0 P, Z$ v{! m, n7 T  ?9 \: k9 `
. X7 Y+ d6 q3 |
  huart2.Instance = USART2;6 |; |/ H% {) X) y, L
  huart2.Init.BaudRate = 9600;, }+ X7 m; h1 N0 U% v/ H& h7 V
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
8 p- F; ~6 X, h  huart2.Init.StopBits = UART_STOPBITS_1;
" m3 J; {* N: X4 r  huart2.Init.Parity = UART_PARITY_NONE;
# B+ _) |7 K" ?& A$ U9 B  huart2.Init.Mode = UART_MODE_TX_RX;1 @1 Q. C8 i+ c+ \- d- _  t% d
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
! T& Y- p' s5 R& M" a6 W" X( G  huart2.Init.OverSampling = UART_OVERSAMPLING_16;; V6 i4 l9 f# K. i3 Y) ]
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;9 V" N2 s* n5 {/ P
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;! Q! ~4 [/ Q8 \1 a9 n, j( `4 n9 J
  HAL_UART_Init(&huart2);
+ N% y/ _! i/ |1 ~1 T
* Z+ t! s2 p" e1 ~. Z}( k# j$ ?, X2 v# N- e5 \4 @

1 n$ O  }# O# }0 M- B6 X  c: j2 X: a9 rvoid HAL_UART_MspInit(UART_HandleTypeDef* huart)' R* J$ U' B3 a
{
) m9 Z% y- k4 c7 s4 G/ \' O: S' j- l) E
  GPIO_InitTypeDef GPIO_InitStruct;  r+ X$ \+ P6 c" o+ O
  if(huart->Instance==USART2)% [3 i" P2 [. c4 b. h# F5 g
  {1 D/ @* Q2 [, @; H
    /* Peripheral clock enable */
6 x7 Q: }1 G- @: n1 T    __USART2_CLK_ENABLE();( _1 {' ~+ P  E
  
$ l/ T. W) B3 u( q5 s. }    /**USART2 GPIO Configuration   
0 E3 F5 _* T: }# t) v4 }0 l, E    PA2     ------> USART2_TX+ y% ?  N3 s) @" m0 j1 a
    PA3     ------> USART2_RX( h: n- [3 C3 W' e
    */3 f' ?) I/ h5 U
    GPIO_InitStruct.Pin = GPIO_PIN_2;5 f0 g. M) \2 `: j
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
0 x3 k$ \3 o/ h6 P7 K    GPIO_InitStruct.Pull = GPIO_NOPULL;5 X8 K& _3 l& ]! B. b
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;$ U8 c7 H% ?$ H4 x2 S- C4 F, p
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
' M% e% F3 l$ Q    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
4 t) d) d9 l! [" u- z3 H+ D
' V6 N  `0 g9 [# i7 j    GPIO_InitStruct.Pin = GPIO_PIN_3;
; k) s: w0 d4 L' b) D7 t0 T! p8 ?. I    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;( H& `. M% {7 y  D' i( y
    GPIO_InitStruct.Pull = GPIO_NOPULL;
' A2 s0 M8 K+ ]  A    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;+ @5 L% n  V2 y/ c. e6 n
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
9 ]$ Z+ X- S, R+ ^" Q$ C& d# S    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);! q; _. H( s' h' ^2 `$ _
5 a' D& c( N) I4 k( P" u. h
    /* Peripheral DMA init*/3 @2 n, w7 l8 \: f( `8 w
  
4 R% w& i& d) Q) e  ~    hdma_usart2_rx.Instance = DMA1_Channel5;
4 \9 G) l$ S. m2 {, z5 l    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;# h+ G! X8 [" ]
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;. N' h% `* M/ B5 {
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;8 C3 o1 E5 r) X. J. h
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;. T0 Q7 ]$ b$ _, b; f
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;$ U9 Q' n" v, l" C7 M6 S; ]5 a( B5 D
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;3 B$ P7 c- S2 l1 L6 Q
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;! |- F. |' v* {! ?9 R
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
4 D5 v0 v3 C9 f0 r; B    HAL_DMA_Init(&hdma_usart2_rx);
1 h% o! A) _7 G' c) f: w; L( B/ W0 b6 z% L) n. Z  _( D  }
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: `4 q( G" O4 L: h4 j* p
# |' b) _, G/ \, {" G
    hdma_usart2_tx.Instance = DMA1_Channel4;
$ b* q$ j3 t4 `1 j+ W3 G$ H5 M    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;9 c: M: X* o( L7 k/ U  v% z$ b% a
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ r) f4 Q- Y7 q7 U    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;$ c2 C2 d( H3 J/ s
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;3 i0 Y* Z9 ]% |" U
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;4 @6 c/ w. Q4 |" n
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;4 U  C+ r3 @% t3 C) D
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;4 @! p0 _# Y, @. i8 x1 q
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;! \) _% t8 C& T: a
    HAL_DMA_Init(&hdma_usart2_tx);9 H3 S, Y5 ^, Y" t- p$ d1 ?
9 x* R2 D! ]' P$ K2 y
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
( u6 j$ ]6 D8 C! W5 [3 {2 ^& A- F$ F! g: d9 z6 F1 d; I3 B3 o  L3 z
  }+ F/ r4 V7 _8 l+ |8 N$ j' e
}8 ?8 B$ a5 x1 k2 |
3 u8 r  R& h0 o+ m% w  ^4 a$ n
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+ z' D, E. F: O/ ?3 Z  l2 a* o; x{
( _6 |. g& f2 Q- e2 D
& e8 l$ k$ ~7 N+ g$ z( `# e3 n  P  if(huart->Instance==USART2)0 f+ _- b- u5 Z7 \& \
  {- a( e5 m% O( s9 \% o
    /* Peripheral clock disable */
, \% R7 ?5 D/ g5 L  k    __USART2_CLK_DISABLE();
" n/ \+ T) m. T# ?; [  % }# e7 y" F, R
    /**USART2 GPIO Configuration   
' A: e/ V; A: q    PA2     ------> USART2_TX
3 _& g  Y: F/ N! Y  b  U    PA3     ------> USART2_RX3 n8 K  R" I3 x' L( E
    */) S5 N2 ?0 G3 D, J& Y7 d
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);$ R6 O2 `& j& R3 l' a9 ]) Y# N
9 w' g  p' H' B& I# {  U
    /* Peripheral DMA DeInit*/8 m( |; Q% j$ }1 v, B0 P; j* y
    HAL_DMA_DeInit(huart->hdmarx);
  W3 B. c/ c1 p0 |3 N    HAL_DMA_DeInit(huart->hdmatx);
. P4 e7 _& ~; ~7 s3 T# I7 I  }% F9 K% H! b+ a$ C
}: f' E# `) b; }" ^1 @+ X% i
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------, u: B: ^' Z( `
mpu6050.c2 z1 _+ L0 C" R' y' a
#include "stm32l0xx_hal.h"' [2 j# T* Y. H9 J5 Z
#include "MPU6050.h"
9 B( ^; S5 J# {/ k% B
& ]) t0 O4 ^9 D//各坐标轴上静止偏差(重力,角速度)
! L" {2 O7 f6 g! ]4 ~int16_t offsetAccelX = -195;1 a% ~' T, M* b) i( h0 m9 z
int16_t offsetAccelY = 560;
4 z5 ~5 f8 u- _3 p" G& r$ Wint16_t offsetAccelZ = -169;
; n: o1 G" H. h- C9 U
% E* K- t, F. G4 _9 {+ x2 I# {1 V  Rint16_t offsetGyroX = 12;* V  Z" ]% {7 V9 G# {4 H( a$ f
int16_t offsetGyroY = 33;
: x: F1 p$ A2 }7 `int16_t offsetGyroZ = 4;
" R7 w  X& T6 u; Q, k4 g7 A8 a7 M
! L7 |2 ?  ^% ?% J& _2 a1 Oextern I2C_HandleTypeDef hi2cx;$ t7 F0 ~( b9 C3 s4 t$ I

# S+ M2 G, O1 _//**************************************
, v6 E1 r  Z" b. k7 C6 P0 j//向I2C设备写入一个字节数据) X& K. h7 W7 d3 v7 O
//**************************************& _6 g( v3 W& _& k) N6 p7 n* ]* a( z
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
" R- Y4 K9 N1 U1 `$ N# P. X5 p6 W9 f{4 l+ ?/ U& Y2 i0 Y( a" W2 T2 F
    uint8_t rxData[2] = {REG_Address,REG_data};
2 R3 a! z0 k6 g1 N+ }    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)" \/ A8 b2 }& ~6 X; d- ?& y# V
    {
' |4 O- B! T: S        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
8 }+ q: T) a, D7 p% G' A1 z        {}
7 q$ J0 W  r9 G! z    }, D% P2 g( _, O7 p# E
}
6 X+ N8 X# E' p; y  f6 E  n//**************************************; }' k- t% Z/ [2 N- j3 v
//从I2C设备读取一个字节数据
1 X, ?0 [) ^- @0 W4 V5 [% ?//**************************************# F- O9 l/ d, k8 J' d
uint8_t Single_ReadI2C(uint8_t REG_Address)
2 U: K  P! B) Q) @5 {& T{3 @0 q, X5 _; n( R/ C$ e* _
    uint8_t REG_data;( K0 Z+ R8 z/ i
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
: O7 j4 l: J6 N' R+ T- u  j    {
+ I# V0 Z  I& I# W. h        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
6 x4 V: P4 k# @  G3 E" t        {}& P' P! m. ]1 G' Y; h/ m8 C
    }
2 v. d, Z5 O1 l, G# E8 {2 W4 g2 n/ V   $ G. S4 f6 f) l% G0 f  r
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)3 `4 D3 a$ J  w% ^% D
    {* U8 X! _/ W# e* ~* _4 J  ]
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
/ k1 U, y3 e3 g  m& C( L( v        {}
- S8 H2 H" v0 c9 d' F    }. F- }) ?8 K0 e
    return REG_data;
; L/ f4 b% @5 R) i6 u3 H4 k}
: t7 F6 Z9 \+ [6 l//**************************************8 J0 K! @: p7 {% _. a/ ^( B
//初始化MPU60500 `& `) `9 x% B. I* r; D: p' W5 x
//**************************************
# @5 m6 m& L# ?* _: V( @+ k; z5 K1 ?void InitMPU6050()
+ @4 O/ b( m0 K- L) C{" X7 A$ z' s1 B
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态6 f7 H2 ^: y$ E
' p# ~- C0 u4 w- @6 h! @
    Single_WriteI2C(SMPLRT_DIV, 0x07);
: g& f) q3 v7 a- G! M4 H/ r8 l! `9 F2 j
7 y* i4 f9 {3 d1 ], B2 h  Y    Single_WriteI2C(CONFIG, 0x06);
% I1 r8 d4 v; J+ m  d8 H$ A7 {2 P" h( P/ l4 E# T' c
    Single_WriteI2C(GYRO_CONFIG, 0x18);
  m) s! A% S% [5 A3 r
9 I+ Y* N# V' k2 H$ ~5 y    Single_WriteI2C(ACCEL_CONFIG, 0x01);
. P; R3 g/ u0 K# ~}
0 ^# b4 Q( h6 v0 K4 `//**************************************
' t0 ?- W- T: U! l/ B, E* n% c# s//合成数据
6 \' |5 L: A& {//**************************************
( |. N( m2 b2 O  Hint16_t GetMPUOutValue(uint8_t REG_Address)9 i$ T1 B8 A; N5 y1 T$ B
{2 U+ z1 u, V2 @6 c# y; p
    int16_t result;. D$ x" d4 u' y  V  c+ O& t
    uint8_t H,L;
0 e% K% V# m% ]/ B8 K5 I- f    H=Single_ReadI2C(REG_Address);! L! ^5 ]+ V/ B+ H# g' R
    L=Single_ReadI2C(REG_Address+1);
6 K& t# R/ m( m6 D+ G4 @    result = (H<<8)+L;) g2 S7 d5 v  v5 C& k
    return result;   //合成数据: n' H4 ]' U2 d0 k( k5 @( a
}
1 ~1 b4 `5 P+ f' N9 M% ~5 p$ d( Z3 }! `  _6 o5 A
//**************************************: G" Z8 |, S# z
//取某一轴上的加速度数据
( J2 K- [" F0 K! m- M  c  k0 S$ g# r//**************************************, {8 z6 _! s( c: Q" |
int16_t GetAccelValue(char axis)
6 f% ]0 d2 d- K5 n" b. Y; q{
3 F6 e! z# h. A    int16_t result = 0;
  p2 R' R, L  h  H    switch(axis)' B1 U- J0 e2 _" r6 a
    {4 O8 i* o+ z" N7 n, c; T# i
        case 'x':
6 a6 Z2 l/ r- x, m. T& e        case 'X':
& t% i( ]8 q3 ], e. d8 D$ O! Q+ J        {
: W2 ]8 L/ _  l            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;+ w+ Z9 z1 b" ~3 v
        }
! b$ m: Z; a* p9 W7 l% ^4 Z8 `        break;; ^' v: G& D- A6 w/ _' L
        case 'y':
: X/ D+ M+ g" ~" C; m( Q: u        case 'Y':
1 g) p$ S1 P5 S. J. u/ M        {7 T- e* T" t: l8 j) B0 Q2 f( F3 B
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;) y# y) d2 T) G# @2 T9 c  K
        }
0 A) f/ t, o& U9 m6 w        break;) S8 n4 x* m. T
        case 'z':; k" y. n: ]/ Z% V/ ]
        case 'Z':
' P5 K1 z3 _$ m4 ^3 e        {7 w% {! b, I5 `& a
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;& ]# Q0 w* W8 A6 ]; X5 A9 n
        }- X0 @# A, j/ v7 b2 A* D( @
        break;
4 m  N# O  j# N) K: [" l! C    }
, M9 p: a/ z; C, J# `& n    return result;) c0 W, l5 c) b5 C# A
}7 Z! r* x2 v/ c) f" e9 j- _2 o
* @3 N" i) h! m
//**************************************1 Q4 e0 _# T' {
//取某一轴上的角速度数据3 g/ A3 o) A6 @' }
//**************************************' N* u' _- ~8 @! a
int16_t GetGyroValue(char axis)  `. N( a3 c+ a
{4 C$ @0 Z4 _, o5 k1 T! m/ x; U
    int16_t result = 0;' S, h8 w# x2 I8 ~" m: c
    switch(axis)1 Q, x$ l- V; E: i( Q
    {
% |# P# o3 O0 Z' F& o, j1 x        case 'x':! Y: l4 f: W* {
        case 'X':7 ]( ]% D) t) e" g* L7 P
        {
- n+ |3 O8 P* Q# D            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
! D2 f0 j" ~* z# j( R        }1 ~. M4 X3 X- v3 V
        break;
5 B, k! h) o& v        case 'y':# m% b3 c) F+ I- s# C  d
        case 'Y':- E; L" W( u/ I0 u0 D$ B
        {8 a7 u' N/ `6 T$ r" b6 C2 U
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;, c  ]8 W1 _" i% v: W
        }  b. k# {0 G0 w* P* V4 H8 q
        break;
. w' @' F7 W5 N3 }: `' q, d        case 'z':
3 M6 q2 M2 {$ f7 I; C7 o9 A; `        case 'Z':
6 G$ a+ n3 R- I0 R& l. `* r        {
7 f; S% z' P1 J6 p            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;; {# g  i) h& a4 P- F
        }
( o4 n4 R' d1 {! p1 h        break;
* R5 S4 m3 ]% _' [# V    }
4 p( v+ _" I* F# Y( z% a, O' N; y, I    return result;$ U: G; U% [: \' [
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
! c& y. B) F  @3 r7 _- @{
: C. J: x( {( D) g( F9 Z5 g! W9 }' J: c* g
  /* USER CODE BEGIN 1 *// [6 {+ T7 Y. _0 V
6 h  `% |6 x" X9 H1 u2 v
  /* USER CODE END 1 */
$ W) e% t: B1 L7 [  [! f4 r% o, t* k: s2 g( s  @
  /* MCU Configuration----------------------------------------------------------*/7 o! [' z& ?2 }6 [/ m: G

  H' o& N/ D# {& X$ v* K- ^& ~, v  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
7 u0 q5 w9 A' S# |, o/ |  HAL_Init();
% i5 f1 U9 w  x* W  @) X
7 k! r9 \$ Z2 K& c/ L. Q1 w  /* Configure the system clock */
% l5 I" w9 S- I5 T8 X  G/ [  SystemClock_Config();
2 W/ y- |+ m9 ^( l! O+ _8 u
. ?! N4 l8 [, _! d  /* System interrupt init*/$ T* c+ y& I& h3 u: e
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
$ E1 ]$ a& ^; B- }* `" h! `  |
/ f- |% M) O2 ]0 p* y* V  /* Initialize all configured peripherals */
- ?* Q  l7 A3 O* [+ F- |  MX_GPIO_Init();
' j/ w3 o8 q/ `  MX_DMA_Init();
3 o% d; ]; }2 t+ ~$ ]+ W    MX_I2C1_Init();
8 T# v7 s' Z" Z/ j) X1 Q5 r    MX_TIM2_Init();
& G' W. m9 q" G  Q$ k: J$ N" C+ D  MX_USART2_UART_Init();
5 |5 t( U: e4 ?+ G, k7 r    InitMPU6050();
5 [$ G0 N7 z4 a( j
  e0 }# k2 L" s3 ^8 P3 G  /* USER CODE BEGIN 2 */
% E/ b. q3 E  A    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
! ^( E" m  V# R8 l( v7 E- a  U    HAL_TIM_Base_Start_IT(&htim2);* U- Z& _& F! \6 U
  /* USER CODE END 2 */+ y; R8 p) I; V2 C& H
+ O4 }2 J2 K  b. w8 v5 d+ {8 u+ ^
  /* USER CODE BEGIN 3 */
4 z+ l1 j5 `/ K" H4 a3 E  /* Infinite loop */
8 s7 X, @. n* U1 x  i, G; u  while (1)2 V% \* W; w4 g/ K1 ]
  {
# X$ u, i$ [6 n- m        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
8 y4 w/ d; K3 F; @        VisualScopeAngleOutput();
# l* ~5 }9 H0 g2 r# o9 O        HAL_Delay(100);
8 \& c$ j0 {. [* g3 I8 w  }
/ m3 u* S( |7 g0 n" m+ I! g; E  X  /* USER CODE END 3 */  R, S4 h/ {1 G( E: r

# {9 T' `( Z. n8 M6 D}' r2 I  c6 h9 i

0 K5 `1 a. j+ T: `! J/** System Clock Configuration
7 c: d, A+ s. B3 N+ p*// X' D5 p* t1 h; l# X4 X
void SystemClock_Config(void)
2 x+ }& u+ |, H# f) N1 p{: o) Y9 t9 x: @

* ?1 ?# Y. g! A" M$ X  RCC_ClkInitTypeDef RCC_ClkInitStruct;
' V& j, `9 {. G' K4 W1 B  RCC_PeriphCLKInitTypeDef PeriphClkInit;
3 Z9 P) b7 W9 _" ^  RCC_OscInitTypeDef RCC_OscInitStruct;
5 A# z: E$ U2 m/ J- T* g& b2 A0 n- _! T; h
  __PWR_CLK_ENABLE();* ?2 ~6 P- l' i

  n1 @) e  ]3 U9 u  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);0 j; ?. k6 s2 Y. U9 O1 f3 X7 R' l

: w: j8 W7 i9 l( h- Z4 e+ f  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;* ^4 t- i& w1 A$ Y4 [5 A/ V3 I
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;  O6 t! K: C8 i1 ~  n! b- y) U' A
  RCC_OscInitStruct.HSICalibrationValue = 16;3 F/ L6 j9 Q0 }, X8 C+ D; \) |3 f+ {
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
& T0 M- w' O6 n3 Y! y  C6 O* d8 z  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;5 e: o7 r! c9 K' W, S
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
' }! ?0 h. M  ]5 l0 X" l  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;' q! B  ]  K, W5 ~- d' |+ C" Q. D
  HAL_RCC_OscConfig(&RCC_OscInitStruct);. C3 H4 b. O! H
2 p+ T+ N% k, Q+ C% S; T
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
& x2 G& e2 U8 ?# f+ J3 a' ?: s" @  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
* r/ Z( O6 X# p& |/ v5 {8 T  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;% e# A2 @+ P5 Q% `
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
: g/ |; l  l% I+ c% N; B  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
4 ]( V/ @( y8 |5 L/ ?  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);$ j0 |7 x3 n& }- k

; n) q9 u/ n+ l3 p  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;- s4 A: I" b1 y) O( d  r4 d
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
1 Y' }9 ]4 a  Y2 s6 Y  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);( Q% q0 d+ W8 _, j  c& u% c  e
  e6 W* n* `3 t( H; J
  __SYSCFG_CLK_ENABLE();; ~, V2 C: k4 l1 b1 i9 C+ ]. w

* h6 y2 ^4 y) u* C; O1 x. L}
) y( y( ?+ M: ~! p  ~- ?- B$ V0 M1 q! b' J7 b" T9 H
/* USER CODE BEGIN 4 */# _0 n8 N$ E5 D0 m! I4 w
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart): ~( O" l6 A5 g
{
$ ^* ~: U" Q9 S9 _1 `* |    if(huart->Instance == USART2)
8 Q: y" ?5 @3 I2 ^4 o    {; U$ K' d$ C- S, ~
        memcpy(txBuffer,rxBuffer,RXSIZE);
( g: \2 A. n3 ?& @" z2 g        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);) E- N3 l5 T& r4 u
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);- d' B5 ~9 o$ B& T0 T8 s& x
    }7 k/ g1 X. l* T, g4 e: U- G
}
- R& r+ k4 u0 w) `* M- M3 P5 I, |- G* \* J7 A$ b2 c( K+ G
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)" G: j$ X+ N9 A9 S- A0 g$ M5 }
{
- o% }( b8 ?1 x% c( ^   ( A' K+ x6 y/ ]. U
}
+ |1 M1 B( d& ?, D  f  v3 V% y* |. y* U7 ~; Z9 I+ Y5 p- Q( O
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)  z5 w3 ^# f- c$ _
{
" `7 c) N4 b8 b% h6 J& V    int32_t GyroValue;5 {3 e1 G' K% z! e' ?! ?& p) w5 [
   7 N; Y  G- t2 U8 R
    Calc_AngleAccel();$ j- p( @  }/ i+ l
    GyroValue = Calc_AngleGyro();
! `( _5 {; f" H; n    ComplementFilter(GyroValue);
. q1 F$ {  e) a6 u- l* q}
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
) i8 C/ R& E- b( R, v& m) d0 H. Y" c* b楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

# F, X9 [+ H. m) f使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
. p; N7 U2 f3 T8 y* A9 P楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
7 g( g6 J! G% |) y5 N
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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
- G! t! `, D  n7 {: u, J0 n6 T如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

/ [; R0 }0 b7 p好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
  }- x4 W! K# K3 U* F请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
! {# q8 p4 d7 t' S3 b9 m/ a楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?$ i# Z& h& [" S
请问应该注意什么地 ...
) C0 v9 F# M3 Y. V
我使用是没有问题的呀。

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版