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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:. T! m4 @7 ?" m4 K1 f% I
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
; Y+ B2 S- L) i0 M/ A1 fmain.c& S/ n3 P+ x8 ^9 f  t
#include "stm32l0xx_hal.h"+ \* }' ~* A( ]# g% e9 s* T8 k8 q
#include "dma.h"
7 K0 h+ C; S( F9 ]#include "i2c.h"7 K2 j* s' Q; t. _
#include "tim.h"
/ l" H# ]* [9 F0 D4 M" D1 x2 c#include "usart.h"
, A0 D$ T; A! ]8 V- S7 i; S#include "gpio.h"6 p8 v  A6 j- j
#include "mpu6050.h"
* }/ U3 ~8 R) h+ D5 s#include "visualscope.h"* j! i8 v3 }% D1 b$ _7 o

: z6 Q, ]/ ?+ ]0 U1 {. n$ p- g#include <string.h>
& H7 @3 O* m" c6 ^; E  ]# O& q#include <math.h>* t( c5 Q6 [7 {/ R$ c

4 z& h; u- x. p2 C6 z/* Private variables ---------------------------------------------------------*/, R( a% U8 }& `8 u' y" J$ W
#define RXSIZE 8) w3 w3 k/ U& i, `
#define TXSIZE 8
& \( D. ?* b$ c1 X" B2 J6 l$ suint8_t rxBuffer[RXSIZE];
% v" M9 }2 v$ {! a% Fuint8_t txBuffer[TXSIZE];* F- |  u! S; x3 r; l, B

! W" V( s9 Y) Jfloat Angle_accel = 0;" |# {4 F+ y+ K7 z
float Angle_gyro = 0;, U/ z4 Z# b5 I4 Q& `, _
float Angle_comp = 0;- Q! Q/ j$ \, j
uint8_t outAngleData[10];
& L( Z  U* Q3 `  v- ]7 @6 q/* USER CODE BEGIN 0 */
1 x6 i' c- W; i1 z9 j8 Q
3 D( G( T+ O* b8 N" E- z. |/*---------------------------------------------------------------------------------------------------------*/
1 K, m# ]' [2 z$ z/*  重力加速度算出的角度                                                                                       */0 {# y  s; F; ?1 n! a7 x
/*---------------------------------------------------------------------------------------------------------*/
+ c" z0 P! a' ^2 e' Y, _int32_t Calc_AngleAccel()5 M& i+ J8 x$ o
{
, Q+ W3 Q* b9 a    int32_t value = 0;
/ e. [# x" @& a) w& W! m   
' V! w& U( Q" ?$ N! ]7 \% `    value = GetAccelValue('x');3 q7 E2 n  J+ y" K
    if(value > 16384)- Q- A  q9 }! {' g7 }: {9 x2 n5 B
        Angle_accel = -(asin(1) * 180 / 3.1415296);
$ }7 v6 R* c, j4 ~$ X- j) |    else% l  c! {8 b9 r+ Y& X, P2 w
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
& W0 z6 s/ l  ]) u4 S. I% y    ! j8 T/ c: n, [6 Z
    return value;: i( x- O- [: e  D- m& L
}
) |' o& ?& n! d
0 [+ ^5 [1 S0 T9 X" \5 u" k/*---------------------------------------------------------------------------------------------------------*/; R  Z' ]! o" E* c+ r" e# b- b
/*   角速度算出来的角度(积分)                                                                                     */
- W& V( v. D: u/ m6 }1 ?/*---------------------------------------------------------------------------------------------------------*/
, p( B- ~2 o2 Y* \int32_t Calc_AngleGyro()+ }$ _: p9 ]( t. A" }' z
{' p- D: }8 J' u7 M' q7 `* A( z
    int32_t value = 0;
$ u: l# u5 \* n  X& R5 V
+ l. r- V' x) g    value = GetGyroValue('y');" t+ H2 B' _/ S6 M5 M$ F* A4 Z
    Angle_gyro += (value / 16.384 * 0.01);
6 g+ i( F( B: e4 F# `$ V    " d% w3 Q5 ^% O" R
    return value;% R; G# X9 g( _, @3 i( ]
}
8 l" z; G- \& @# T: a( K% `, d; T
/*---------------------------------------------------------------------------------------------------------*/  ?( C6 |( z0 z7 _; s2 D
/*   互补滤波求角度                                                                                     */9 F1 `( _) j! B. X
/*---------------------------------------------------------------------------------------------------------*/
0 O  I  L1 u% r* gfloat ComplementFilter(int32_t simpleGyro)! x+ w  W% J# N2 M; r6 c. g" N& ?
{
% u7 a  `. R; h- B+ G) j    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
% z+ Q) B7 S/ c    9 N' B2 B4 r: d1 G, Z' O: b7 A
    return Angle_comp;. `; f' Z) l2 H+ c0 o9 O
}
6 m; F+ e7 _& i2 K0 h8 q$ s# Z, j  I% B0 j' m2 D6 w/ [5 l
/*---------------------------------------------------------------------------------------------------------*/
, P2 b/ Q' Y7 h/*   输出角度至上位机                                                                                     */( |- o7 D$ L' Z$ k- e4 Z
/*---------------------------------------------------------------------------------------------------------*/
, F+ t; z# u& \: {. Jvoid VisualScopeAngleOutput(). d" P" j. w, b; }2 l0 c
{1 B6 V# g  b* l$ e8 J6 j2 ^2 g
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;  Y+ C* l( U/ W# a$ R7 _5 Q
    uint16_t crcValue;
% w9 ^! a7 h; H0 M* e) ~: s* A   
' {9 s0 k3 N* T  C7 x( p    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
+ F* a2 _0 T* e7 H    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);5 k( r! ^4 B/ Z
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);, m, {+ ^/ P" j' w
    - m6 D1 `# w) I( E* u' R+ X
    outAngleData[0] = AngleValue_Accel & 0xFF;4 i) T8 g9 a+ ^3 [
    outAngleData[1] = AngleValue_Accel >> 8;. Y* @3 L" w* c& p, P
    outAngleData[2] = AngleValue_Gyro & 0xFF;
/ |& Z& y5 @" {% m4 X. {    outAngleData[3] = AngleValue_Gyro >> 8;9 |9 H5 P  H, g0 y+ D* `* k" H- J4 P3 W
    outAngleData[4] = AngleValue_Comp & 0xFF;
& \# ?1 C' x4 {: y/ o& \# `    outAngleData[5] = AngleValue_Comp >> 8;
. n$ W3 o3 n" [/ p* P0 a    //计算CRC6 @0 o4 h7 t5 j5 {- D6 Y$ w; H
    crcValue =  CRC_CHECK(outAngleData,8);
# y- j4 E. X9 ?3 ~& c  |    outAngleData[8] = crcValue & 0xFF;
: y; v" G$ `1 J( o/ F# r2 i    outAngleData[9] = crcValue >> 8;
. u$ ?5 O. D# w& q  O8 C9 `* M    //发送至上位机
# ^6 z1 O3 \4 G/ L. T( Y& H    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
% Z  q6 U" ~& @# D' A3 ^2 z}
7 D2 Z1 O  W" s2 O' [4 R- H/* USER CODE END 0 */4 V5 j) @# |$ j5 a
) O6 g' b7 R, N( i7 l
/* Private function prototypes -----------------------------------------------*/
0 W7 i8 ]; l! a. l' q7 C# Y. Mvoid SystemClock_Config(void);6 W" e/ {1 n0 C# |8 _
2 i& E, \/ Q6 P" m
& ?' q. i$ @  x; Y- ~) i4 C3 ]0 F
硬件连接图:
; y: S. }5 F1 [# k 1.jpg
6 {5 r( \+ w7 M$ V! Y波形图:
- [1 ^. s+ F- G& l 2.jpg ' ?" W8 `, S0 L) s/ C
最后加一个视频:& v- w  D" E/ y: g" X% q8 ~" X
STM32L053 演示
1 \& _' e$ q2 O7 a1 F
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
" Z' `/ o9 Z; N#include "i2c.h"
7 _& u6 f" `8 f
( w& E3 r7 J6 T#include "gpio.h"! u# w+ Y6 ^- h$ q+ Z% S

0 [7 T7 j" u- O/* USER CODE BEGIN 0 */2 k+ F0 S' M# l% y6 z+ `
6 Q; C3 ^- C" A$ h: M" Q
/* USER CODE END 0 */( F/ O( c5 o/ m2 m

, [7 W7 B1 @4 O2 I# `I2C_HandleTypeDef hi2cx;1 N) M0 @; O/ _
; [6 u3 R8 F! F) r3 }0 I8 P
/* I2C1 init function */+ ?7 \! U4 Y8 X5 w$ c+ ^
void MX_I2C1_Init(void)
7 E2 {9 \: Q" ]. j7 T. I% A. ^0 l{
$ W& m9 g- k- [  e% Y5 x4 t, ]+ \- F6 d
  hi2cx.Instance = I2C1;
6 p) _" L! w/ Z2 c  hi2cx.Init.Timing = 0x20D22930;
3 ]3 _5 r( ?- T- s  M, f, H, K  hi2cx.Init.OwnAddress1 = 0;
) S; t" G5 D+ a. F. Z  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
- q$ g( W- S! L3 v2 b9 |, V  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;. j8 }+ R1 r6 @) ]/ G
  hi2cx.Init.OwnAddress2 = 0;8 F; J5 ~5 P5 T1 N) m
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
; V2 z- D# q& U- V$ O  f  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
3 g# E) J) P. `3 }) i* u  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;% t. ~1 A9 c, p1 b: S4 }
  HAL_I2C_Init(&hi2cx);
9 p( k  G1 D' I$ h1 j- w6 {' m: k: a& f  M# H- u8 N) F
    /**Configure Analogue filter
2 o# j& R" {5 F8 w( d7 Y    */
6 Y& g4 u- _' V: N  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
& s' f: m1 U8 f3 ^" p& G
3 N" X& P. v/ k7 P}5 Q' S$ y, o7 f7 _' ^+ Y

6 T# X  o+ q; U0 U2 g1 T  ovoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
, d+ O& i3 _  B, y0 F{
, I0 Q1 M) P; ^5 D& C
( @: @8 R5 c& K( D) ?  GPIO_InitTypeDef GPIO_InitStruct;
/ X! K/ K2 k, S8 K6 W- |6 [  if(hi2c->Instance==I2C1)
4 F5 Z) D1 r0 H  {. Y% |; y: N# @/ Y
    /* Peripheral clock enable */4 Y- R- M- Y/ r& W& g
    __I2C1_CLK_ENABLE();
# [; ^$ m' ~/ v, C4 {! d9 A  
0 r2 D1 Z/ P; D9 A8 F- l    /**I2C1 GPIO Configuration   4 ^* n. e5 u7 n$ f$ v1 G- Y
    PB6     ------> I2C1_SCL
( ~9 ^' E8 v' E( A" v. P  I    PB7     ------> I2C1_SDA
0 F+ ]7 \8 W8 J; S    */
0 {3 J2 Q4 b" A% k, o    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;5 D2 f9 h5 p, I9 b( Y3 [; `
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;) a% N: I) Y# l; S1 n
    GPIO_InitStruct.Pull = GPIO_NOPULL;: j/ j0 D- \; Z! E/ T" K
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
# z3 g% `* L/ E) Z    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
. o) M; M( G7 N    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
) G1 X; [4 F4 H" T* W1 x- f6 H1 d  i/ W$ w/ d/ W% i. y% _
  }
  D# J. B  ^7 F. X7 s' k$ Z}4 o. l0 g( c. ~5 z' j" \
- G9 S" |' \# P' P/ z
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c); }' @6 i/ I+ B2 t) L
{
6 {1 c, P( V6 q+ T8 ~- ^# r: Y6 Z5 r, u1 l! K; L! E2 e6 ^. ?, N$ p3 w
  if(hi2c->Instance==I2C1)0 e$ b, n8 O) S" c
  {+ O! |6 |% y% S& Q/ X6 n
    /* Peripheral clock disable */2 [4 ^+ F5 p1 b! S# q% w+ X
    __I2C1_CLK_DISABLE();
' G8 ~' z: ~0 o9 p) S  # `7 q0 h  N8 p' W# m5 i
    /**I2C1 GPIO Configuration   . d* Q! m# S% n  X
    PB6     ------> I2C1_SCL
" A" e+ x7 c: K: v$ x    PB7     ------> I2C1_SDA
. }0 F1 @, q/ w- c    */
0 M3 \1 @  {  D2 U- Z8 A' z( C% S; w    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);$ Z8 Z. J2 b# m/ {4 p

- `$ f  f6 x3 s/ Q/ ]) G  }$ p9 w/ F$ d" t
}. V+ s( M8 R$ S: L/ F$ u
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------+ d' i" v! ]  b+ X7 V0 c) h
usart.c
3 W& N) S' S, R#include "usart.h"
( I4 A! v) D% n/ A4 c/ H+ O1 C$ @
& h/ n0 W* x: d0 ]: e& f- b#include "gpio.h"
6 M$ ^0 n0 u% K8 W4 \7 w#include "dma.h"
, x0 Z( R+ l9 I$ S7 Z# w5 J& j& r
' o$ ^9 b  Y) h/ d/* USER CODE BEGIN 0 */
: G" Y, v, E2 }4 a7 l% ~% U
$ _+ ^" _) u  F8 o/* USER CODE END 0 */
7 u: I5 b" W5 [/ a! f9 C5 C" J# T# C9 X9 g1 F  @
UART_HandleTypeDef huart2;1 {" P" j( J0 N- `
DMA_HandleTypeDef hdma_usart2_rx;
' G" x5 L) C1 k& gDMA_HandleTypeDef hdma_usart2_tx;
: {3 T. U4 D4 i! l  S
! H1 j0 J' q7 [8 c) e2 _/* USART2 init function */8 c! n" v' J% q  E9 J

9 I0 L- k: T2 J2 E" jvoid MX_USART2_UART_Init(void)
# F8 a! B. @' {1 _7 Q8 |{8 z( E6 J! Y- u5 f4 D9 @% D
4 e  e$ G& c: W* M7 P  V' l
  huart2.Instance = USART2;/ u; w3 P% w4 }2 W% J$ {$ E
  huart2.Init.BaudRate = 9600;' Z  ?' I  j7 M/ ?# s$ f& o7 m
  huart2.Init.WordLength = UART_WORDLENGTH_8B;0 t: I8 l  v! v* i0 k( _0 W
  huart2.Init.StopBits = UART_STOPBITS_1;
5 z0 q/ g9 s( F  r  huart2.Init.Parity = UART_PARITY_NONE;$ x$ U  C# H6 t; ?4 p
  huart2.Init.Mode = UART_MODE_TX_RX;6 c7 P9 H* M# u  _. s
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;7 R1 U- i/ h, U- |" H2 T7 _! d
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  y& k( h+ F4 L: E  E5 d  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  j, T4 D7 y7 s( u% g/ L  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- k5 K, O$ h( f) d2 N  HAL_UART_Init(&huart2);
2 E) c6 E! ~+ m0 Z
/ O# J2 n# p; l0 B- w# `- I/ P}
6 ?+ J5 w" n& Y0 n6 G7 R* p/ y) n9 g# u7 C. S' d5 H: s! P
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+ f# x4 f. W) Q" m{+ m9 n2 h5 w8 M
+ u( E0 `0 k2 {" G; V2 y" Q
  GPIO_InitTypeDef GPIO_InitStruct;# {. z- n1 |! C: T2 L
  if(huart->Instance==USART2); L: x% D& `& H9 n
  {+ ]( I! F% C7 D8 h2 T4 p: W
    /* Peripheral clock enable */; Q4 Y3 ^" q5 O% Z& r9 d/ r
    __USART2_CLK_ENABLE();
, A$ B% W% O: [6 A  6 i, ~5 Z( A/ \  a, R  G
    /**USART2 GPIO Configuration   
% g" s* }. T' Y9 ^9 x  h  Y' Y    PA2     ------> USART2_TX0 C4 S) m2 t) o5 A% ^4 U0 t/ R
    PA3     ------> USART2_RX0 h$ @- W2 y8 S% n
    */
& u' z7 z  B2 z0 y2 u" t    GPIO_InitStruct.Pin = GPIO_PIN_2;
' @: i& _3 r3 B0 b1 x6 I' N    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- L; z3 K, o# ~: S) k8 Q  l; w: {. Q    GPIO_InitStruct.Pull = GPIO_NOPULL;
2 a6 F7 N" }; \0 q9 Z    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
1 Q# S- E- O8 X7 {, o    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
) @4 [% M& c6 R( M. R% N6 m1 l6 x    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
, g" B- m, A# b* P" x, n* q4 V" o+ C- ]4 T
    GPIO_InitStruct.Pin = GPIO_PIN_3;. Q  U1 p# o3 S* `" y$ I
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
; K6 z# R" f' M8 b    GPIO_InitStruct.Pull = GPIO_NOPULL;
+ T5 M* ]5 P* [; _    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
9 ~1 m. G; q( Q1 p5 M    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
, S, X6 Z/ k# g3 E1 g    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);1 r) T7 v" v) G5 ]
  A9 Y9 P2 A8 F/ G* L% j
    /* Peripheral DMA init*/
: t) [, W" W; ^- {2 M0 z; }# F  
9 P& q8 k6 {& V: j& y$ \+ e    hdma_usart2_rx.Instance = DMA1_Channel5;
3 e8 @5 N& r; U* m, X5 o/ P    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
4 n6 p$ q$ Z. k0 Z! w    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;  s! [) _' D: b' M
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;" [7 `5 X* o6 P8 B3 u, D
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
5 V8 L  X3 O  P: H    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ h/ `5 S( e+ }3 b& @& T5 p    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
( y, c% T3 {: s; E9 U    hdma_usart2_rx.Init.Mode = DMA_NORMAL;% y/ }5 [3 b6 ]& q/ H! z1 n6 D
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;+ @" |0 D" n2 ]+ n( u- G+ z) w1 u
    HAL_DMA_Init(&hdma_usart2_rx);8 `# N" M0 {6 E. V% d

; S, ~/ P' D9 c6 S    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
4 u+ `+ [4 U/ `: m
/ `/ H2 x# T. w* d    hdma_usart2_tx.Instance = DMA1_Channel4;
1 k- s# A8 M; T    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;$ G( i# o, S% Y! {& p5 d
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;1 W* ^# D2 G  o7 ~4 g3 y% t0 X( ^
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;  `1 ]. d/ P( s( C
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;- X5 z+ w6 a( e& |% p' N
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
) J4 k& {: j0 S8 h2 ]    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;6 X: j2 r) {5 V' f
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;) r6 x7 [0 @& ~+ A$ C
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
1 n$ F2 l) k* I/ _    HAL_DMA_Init(&hdma_usart2_tx);
6 d  A1 ~* f! a+ P9 X1 V4 e6 R/ d7 S0 j1 t1 S( q. p, Q1 w
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);7 K3 h# K/ V# X6 ^; h# ^

( B6 T4 D& k. w4 L- V  }, n( C5 ?  {' s
}
0 g/ }( M4 G+ S; l( T1 L( ?/ S$ I$ Y) c6 i. r' A4 N" Y# E
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)4 R% k' L) e4 w: ]  y1 O! n
{
& x1 }7 X! u- C7 M# y7 s1 S8 E5 v6 o) D
  if(huart->Instance==USART2)3 l! l- i0 A. l& S
  {
$ `. L; \4 e2 B5 F    /* Peripheral clock disable */
* Z5 F, T3 N; r; O0 ?* w5 U6 V. ?. a    __USART2_CLK_DISABLE();
6 j  l; [: g9 @  
# d) r5 O6 Z6 [+ c% A% B7 k0 a    /**USART2 GPIO Configuration   3 b+ }# W+ m( i) J; U9 O0 g
    PA2     ------> USART2_TX% y. u1 D9 P$ c9 z. u% N
    PA3     ------> USART2_RX9 n# j; p. `; x3 j& v
    */
$ R/ L( E+ k* h, L5 V7 B8 a    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
! n2 X+ {8 O/ c' G; _, J5 W2 c4 y# i8 R
    /* Peripheral DMA DeInit*/( z5 z2 ^# I7 s1 Y- ?. q7 N: B! _) K
    HAL_DMA_DeInit(huart->hdmarx);
& K- t: P! T+ u, Y! E    HAL_DMA_DeInit(huart->hdmatx);
$ j$ Q( f+ A8 N: Y  }
: n* ^  u, p2 L; p- H}
$ o0 i+ l# H$ F- D------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
' T, l; ?, d+ c$ x) W* m3 Z8 Pmpu6050.c6 G" P: t# J1 c+ e
#include "stm32l0xx_hal.h"3 z$ H5 P0 N9 L+ K" t( H/ M) K
#include "MPU6050.h"
7 V8 x. E6 O- Y' ]3 ]9 t# x) X& N) w
//各坐标轴上静止偏差(重力,角速度)
( l# s5 B4 y# p, k6 T8 M8 i# `int16_t offsetAccelX = -195;
/ a$ s( y5 s3 l4 mint16_t offsetAccelY = 560;; R/ @2 m$ N$ X+ c/ d6 v
int16_t offsetAccelZ = -169;
2 g$ P9 F- ^  K( t6 H6 _8 t: a
. L5 s2 V" G9 Yint16_t offsetGyroX = 12;$ S5 a+ u, ]" |" @
int16_t offsetGyroY = 33;. a. Y8 ~: ]# F
int16_t offsetGyroZ = 4;$ W; I: J( P. i$ E

. M' R; y" b9 ^3 j. p/ M6 t7 pextern I2C_HandleTypeDef hi2cx;
3 S1 t. s% V1 l6 N3 o% E- B, ?0 b' q. ?; ^3 t! W- i, a5 o: |
//*************************************** ?9 G# t( j; B
//向I2C设备写入一个字节数据+ |' g% S) L0 E* f6 \
//**************************************$ v8 l$ o; h  Z+ e5 c1 B
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
- @! f1 h) Q$ ^- m{* R& y' _9 Q+ {/ ?! \
    uint8_t rxData[2] = {REG_Address,REG_data};1 x. \7 t0 n9 d
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
5 x# x3 J* x  T: `6 L    {
6 D& z& y6 j" Y; t; f        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
! j+ X+ z2 u! ^. e% A% d1 x        {}
4 O1 T0 _9 s% S8 i4 b- Z% D    }, z% E7 f% I* @1 r4 f
}$ j* ^' s3 w/ [2 ?. u) }
//**************************************0 j# ~3 ]; ^& V2 L' Q' N4 C' ~
//从I2C设备读取一个字节数据
. ]: @3 S1 h9 y# _& {5 U//**************************************
; z. B2 ^) H2 f7 P" Luint8_t Single_ReadI2C(uint8_t REG_Address)
/ n6 ?) {$ e3 X1 Z; g( x{
( a* M. I' {" U7 {) C    uint8_t REG_data;; d  N! K: |7 J% o
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
, t7 K# J6 e# n1 n; O    {
9 d: d4 s, G  ]5 ?  |& ]        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
! h. H: b( U0 N1 I" F! Z        {}
. v6 S9 E2 {3 \- n( Z  _) J7 F* f7 G1 a    }
. u5 J0 v7 @; S) E' |   
6 P- e0 ^! u* m2 O4 q5 h    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK); A; }$ [- B% [
    {
: ]. M; k- ~5 A$ E        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
) o9 I; _6 G% e  j4 x        {}
6 }$ c* U$ _7 @# w" v    }, `  r) X! K9 H9 h- q6 q* x
    return REG_data;
- ]5 m' Y1 J! ^3 @3 _}
% u  P' e% w; i( S% ?//**************************************, C8 _3 r! g; O0 ?6 U7 r
//初始化MPU6050
2 |, Z3 u' U# x3 i//**************************************
0 z% T: a9 f7 `( G* [void InitMPU6050()
" i# y: t/ K# {6 i4 L- w. b{
: i' M; f! r8 L# ~  s    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
4 E7 T1 ]0 q2 L" H% Y
; b4 Z0 n8 L0 U  b5 s' X6 }2 o+ }    Single_WriteI2C(SMPLRT_DIV, 0x07);
% F' o8 O3 x7 Q+ W- @6 c7 \3 R& p3 b) p, x4 T: ]  i
    Single_WriteI2C(CONFIG, 0x06);( D1 G0 K7 h5 u/ b, l( n# d* `6 M1 T% M
) T- u/ b7 Y9 e; \' h& N" I& a
    Single_WriteI2C(GYRO_CONFIG, 0x18);# r( s/ W7 }  p
/ D4 q; i- J; Q2 K9 ^5 C) t! n
    Single_WriteI2C(ACCEL_CONFIG, 0x01);# Q; b, D5 i6 t  G0 z/ ^3 T7 F/ P
}) V# D' M' Z0 ^$ v
//**************************************7 P0 H/ O7 p4 @
//合成数据
7 n2 s. U6 E& R1 w1 r( P8 v3 M7 O" N$ q//**************************************
: Z% s" w6 A2 Hint16_t GetMPUOutValue(uint8_t REG_Address)
9 i; S) ~* J; J6 r6 T{& N: c. c3 j- v
    int16_t result;
" W' h7 ?1 h2 B7 @  S    uint8_t H,L;
0 @! y0 D+ H, S; A) n0 g$ [    H=Single_ReadI2C(REG_Address);
% G& ^4 W+ X+ |    L=Single_ReadI2C(REG_Address+1);8 _) U' r$ E8 F% R6 a' G9 R/ _: b4 J
    result = (H<<8)+L;
1 S% a8 ]9 d  ]( L" a: q8 D+ y7 p4 c1 }4 |- Y    return result;   //合成数据$ {) b5 r% Y  W
}- Q7 Z) {& f5 d
/ `& h2 ^% ^( p
//**************************************
7 Y1 H7 Z, @! D9 A- n* @7 ^) X# d//取某一轴上的加速度数据+ \" n5 T. k3 c, w" v; a3 l6 x
//**************************************# _3 s3 i$ t( f" x
int16_t GetAccelValue(char axis)- P# |* I( I) k# V1 C: u
{$ i4 _% w& \9 }& J
    int16_t result = 0;% Z" u1 o+ o" M5 [8 S
    switch(axis)
  e* R8 Q! a& `: W$ J    {; ^3 S& S3 r7 s; w
        case 'x':' C. S0 I1 E, l1 J1 N; N
        case 'X':
. d' |# l  Y5 s2 \8 H4 |# \        {
* ?- b4 e( G1 c! h            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;' `" _& L2 M6 n; N8 i
        }
- p$ x% T  v. p/ v! x2 ~+ g        break;- \4 c4 X! L, _! P/ u! D" D* P
        case 'y':8 N) ~" b/ b: |2 T
        case 'Y':
5 @4 s/ i9 X3 K/ c6 W        {
, E- t9 I9 ^6 g2 s9 z  ~            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;; O% O3 B2 d5 T8 E0 I" {
        }/ ?$ u1 a+ }! T* ~
        break;
; w0 u! H( X7 z& h        case 'z':
7 M8 Q# J: I" ~! s' p7 ^  ~3 }4 `        case 'Z':) P0 a, X0 ]4 k" ~( U
        {
: Q! D2 i+ S: Q5 y; F            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;6 {' g3 r! z% R: `% `# Y' [0 \$ p
        }9 X0 X1 V7 Q2 A1 A7 f5 x
        break;% k1 K( Z7 j' Q4 d3 u
    }5 k7 U; @6 I' T3 j" K" U: i
    return result;
7 B) h0 p. |" z% }: u% v% P}& k. R, R( ~9 [6 d* q

3 C, W' _- w( ?//**************************************% ]/ R% `  b; h" q
//取某一轴上的角速度数据
$ h) ^6 D/ J/ p) L& B& f//**************************************
2 F4 o$ @  ^; `0 w2 p8 vint16_t GetGyroValue(char axis)
5 w  x8 H" w! _; N9 L4 _{6 b: Z% `& b' F! x
    int16_t result = 0;
7 _: H' `- ]  H    switch(axis)! f( e& M$ k1 B4 C! a
    {6 Y  N- l6 M! ?. W& @
        case 'x':# U0 m' e2 |# K. N% h9 A, k
        case 'X':3 |" E( Y. {- ~$ ?! n
        {% y7 [& w4 _( K% a
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
, z) T6 w! I3 g+ e& k6 J        }" @, t/ f, B( v! u- Y6 w$ [9 {' H6 [
        break;. y% |5 u4 l" N4 F) A
        case 'y':
; Q/ S- x0 X4 c5 q2 v( t% F        case 'Y':- w9 k6 K, A" Y. Q. o+ U
        {
# _5 C/ s/ M/ Z( A8 o            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
. c$ n" m8 d, F# @! B        }
  X/ T  k6 \/ P5 K        break;
( M$ \' P; B  T: {2 M1 k2 i        case 'z':5 `- h' I- D% W) C  o5 ~/ B6 R
        case 'Z':- u  e! H. ~) Y
        {7 \! ?" z" c3 d2 O1 i/ U6 g
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
6 x" S* K2 a7 g5 R        }/ ~: R3 b  ?3 X8 q% D
        break;4 O& t+ k1 X" P/ D- c( @$ S- W
    }
6 g& j. ?" u( |    return result;) }+ V( P# U. d: g8 H. p
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
6 l! b) X0 c0 h$ d: u# W) _{9 O$ O5 `6 D2 K" o) J
. I2 R) a& k) S3 s
  /* USER CODE BEGIN 1 */
" C) L" Y: U8 i" {9 j& m7 i' }, |
  /* USER CODE END 1 */' d6 t9 l9 m& i
3 c8 Y0 x/ U- V' J& h9 F" {/ }4 d
  /* MCU Configuration----------------------------------------------------------*/
& F2 Y% Q) j. Y; |& L1 N. z. x2 U5 p! u
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */4 t1 T( Q7 G; ]0 V+ F: l( i
  HAL_Init();# H- D. T+ d' q/ c; R4 ^, W' L, ~9 r

5 b. v0 P) S5 j# B, m  /* Configure the system clock */
: T! f5 E1 Z" I0 e. ]  SystemClock_Config();
1 Z: F0 B% [0 i! l2 U( ~. ^( m; \, N1 ~1 S0 W
  /* System interrupt init*/
8 [  w8 a; V* R  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);! K; N( B' j0 s8 b' ^6 }) t0 R# T9 r

/ T8 F6 W  C7 L, L# R  \; x' i  /* Initialize all configured peripherals */
2 [( R0 |$ ?: t% K9 d3 Z9 D4 E  MX_GPIO_Init();
2 a7 s9 {6 V! I% L  o- ?  MX_DMA_Init();
1 j' z7 ^* W" z1 ^/ T: e/ E    MX_I2C1_Init();/ R5 W$ B1 }1 \+ ~' S% a& o
    MX_TIM2_Init();
4 l) z% k$ Y+ i* k  J7 J( [  MX_USART2_UART_Init();; V+ C( q& V  y% K
    InitMPU6050();
+ U% G  E4 z/ ~) ^! ~9 `) |
6 e, J8 s0 h$ e. {# Z' ~7 K  /* USER CODE BEGIN 2 */4 I5 X& m8 b) p) n+ E5 o
    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
7 _2 T+ Z  L# Y, @* u! n    HAL_TIM_Base_Start_IT(&htim2);
7 L( ^% {; U  U  R  G2 J$ Y3 m  /* USER CODE END 2 */0 M& j0 E" l( \/ s2 G* \8 l. x

' _. V6 ?4 X4 t3 n7 j' a1 k  /* USER CODE BEGIN 3 */. Q& {$ @# A. |5 z' f) }
  /* Infinite loop */
1 I9 R, R: y4 K, ~2 L7 L* B  while (1)
2 x: Q. e) I1 d* p* b  {) H  ^! x! I% ^+ K5 V9 B9 D8 ~) Y( _
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);+ L2 F) @) G/ W$ o. F+ ]- T5 X
        VisualScopeAngleOutput();
. \( ~* n7 f, c' J        HAL_Delay(100);
' b, @& f1 `5 s  }( |* }/ J& v  y6 L
  /* USER CODE END 3 */
; E% `) ]1 S- c( x& U9 s! o. M+ f7 L% a
}6 L- n) [# o5 ^% J* v9 ^3 m

/ x1 g- f2 s2 g% Y/** System Clock Configuration
* T" z" L, E! @! x$ A*// ]! t- d' g  Z. ^; {, Z
void SystemClock_Config(void)2 v+ I9 J5 G- t) F
{$ [. E" {; A' G- m6 j- D

" \0 L( D" }# k+ @" V7 [  ~2 o  RCC_ClkInitTypeDef RCC_ClkInitStruct;
9 A7 p& X( e. b0 I' q; E; ?6 `5 D  RCC_PeriphCLKInitTypeDef PeriphClkInit;. x3 O1 Y: i& \8 G1 w: H: M  g" K
  RCC_OscInitTypeDef RCC_OscInitStruct;
" i# `5 \8 T; S. h
, a+ ^) }" R" I. S  __PWR_CLK_ENABLE();
* p" y, u6 X8 m& o8 d& z  E  v1 N$ ~0 n, s5 t! E/ O
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);! r$ h- l3 b4 ~: m* k

+ x& b( @1 t' h* A& ^5 u) T9 P  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
3 e+ P/ R9 u4 f  j  RCC_OscInitStruct.HSIState = RCC_HSI_ON;8 `6 C8 m0 ]9 ?
  RCC_OscInitStruct.HSICalibrationValue = 16;/ q2 @6 p8 f! o* t! L
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;2 P# E; J, |, V+ G
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;; ]9 _9 v2 i# n! N7 c5 }! r7 b" J
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
' [; \9 A. @. S$ A  r. X  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;4 s" c8 Q: A) l
  HAL_RCC_OscConfig(&RCC_OscInitStruct);5 c+ f5 J0 N* k8 w- J& }
  L  S$ Q' P5 T7 T, E( r7 Y2 K
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
0 s: d/ S+ }- T  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;9 Q3 m& O- x. g" D7 R- ]  a
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;! _# _9 w  P4 O
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;5 _, b; s4 f( |  [- s# I: w- S" E
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;' _% c& P, U: {4 E7 L, W$ J. R/ z
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
# Y1 d; \% @9 J" Q, V, ?" B8 Y. n0 }
: e# x5 b# ]! A" t  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;4 y# W4 g9 M- j$ b7 h
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;% o; E( w# m( D
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
$ A( J- I" s' N! o! x$ Z) p# C
( B& p) I: q0 U  __SYSCFG_CLK_ENABLE();! X, B! n$ C( c) |( B8 T

% G- k& P: O: B0 j}
/ `- m4 I- S: @: d/ w  l  ^7 T1 e) ^0 @# |2 y( f* K/ E
/* USER CODE BEGIN 4 */- l/ ^1 {" r( R% O' a% N0 Z
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)9 W2 o: h8 g8 |! q3 `. u6 W+ ~. U
{
& ~, B3 ~* Q7 ?) V; @0 _    if(huart->Instance == USART2)" d% ~) s) ]7 m# X( A
    {
, y: E6 |" h  d! |+ N# G' y        memcpy(txBuffer,rxBuffer,RXSIZE);
+ G3 \9 E3 c/ b        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
9 w$ n; C, I3 O% V7 U        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
' x) ?" I; ?, ^! T$ C: V! R% m    }
: q$ r' x6 t, @; \/ T; _}
, B: P$ x2 y2 k/ N( p: l* [% T4 R- ^$ F* _& I& w
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)9 [$ \1 u( E" Q6 T1 U: _
{
2 L% M8 k4 G" w2 b  A3 K* t/ x   
7 q& M/ k" w, U5 s/ H4 n}
- I* d( Y  o; V( {. N6 r4 o
% W; T. y& l4 F, Y6 {void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# V  O" d( L2 t5 H4 C1 A1 o
{( d! C4 T# j3 H4 h% t0 p
    int32_t GyroValue;
) O8 {8 l0 F4 A# J! t& n: s   
, m! V3 J- X1 z9 w0 o5 P    Calc_AngleAccel();
4 u6 i6 e" |+ x1 h+ P. a    GyroValue = Calc_AngleGyro();6 t# N9 W) S$ V
    ComplementFilter(GyroValue);
% t2 o. b) A7 q( j7 o/ R- J/ D}
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 h% N/ @. w% n4 s- s9 J( T# P
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
. z+ ^; e/ j& M8 P9 l$ }
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:009 [4 k2 H# J; G7 q/ c
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
( v! \7 d9 J! `/ |6 @# a
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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:215 x* u) h6 d$ |' \+ o3 p
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

5 a1 ]7 _( A5 E7 B* ?% l) _好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?: O2 Z0 r* G& h# r
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08- F: C% C" Q+ h+ ~
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?" I7 i7 W. N+ t0 A- L+ d
请问应该注意什么地 ...

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