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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
  b4 `8 D- W: ?# f-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
' J4 v1 S, |) a: _& Dmain.c+ v  P/ y# j9 d) D
#include "stm32l0xx_hal.h"
7 t9 b& c2 z; X! Z  h6 e#include "dma.h"
) v% t9 l! Y* O. ^#include "i2c.h"
. @9 o; m, E  r8 b- G  |#include "tim.h"
7 D, u& L1 W6 G% g" }4 }# F#include "usart.h"4 \8 D2 U3 g3 f9 u0 J
#include "gpio.h": a: Q9 Q# l/ C. o/ S( s1 z8 {
#include "mpu6050.h"
2 w$ w" U! F, I( Y1 ~) @#include "visualscope.h"# h* x6 L3 w/ L, D3 ]8 }

8 R$ T4 W: A! H. a4 [  \#include <string.h>
  y: G& M5 S( Y+ u( `  Z1 e#include <math.h>
. g$ Q% ?# N0 v( b  `& K
5 u: _6 `* J0 E; N8 z% R( }/* Private variables ---------------------------------------------------------*/
  P  l: l5 {* J9 @- B+ L#define RXSIZE 8
5 u; |- Q. L( h#define TXSIZE 8: _! Z, ?6 o( s7 Q) e
uint8_t rxBuffer[RXSIZE];$ b2 v: e# w) B# z
uint8_t txBuffer[TXSIZE];
8 g9 S' L- L+ l5 N# |; j2 _& T: q9 O' g' `. h2 ~) I7 p
float Angle_accel = 0;
) G4 y2 a' u7 L# {. Q3 n4 ^) {0 wfloat Angle_gyro = 0;
% ^/ E$ P6 ?& a; k, @$ d" Cfloat Angle_comp = 0;
' G4 W& [0 b+ r4 m5 ~uint8_t outAngleData[10];$ B+ r; {( x- G% f5 E3 m/ B/ w$ ~
/* USER CODE BEGIN 0 */
" ]1 F2 b+ h! T, r$ ~2 k" S4 ]! m/ u" i3 n  e' c' S
/*---------------------------------------------------------------------------------------------------------*/9 B3 E9 n: K' w; X
/*  重力加速度算出的角度                                                                                       */0 V+ i" S% n0 p$ d) b. q
/*---------------------------------------------------------------------------------------------------------*/' y9 t2 P+ T" g& O4 G" M/ g
int32_t Calc_AngleAccel()
) J5 d, @! i- k0 `' G9 o' O{1 Y8 I- K+ e9 a; h
    int32_t value = 0;8 y/ a* L5 {+ t! G' b$ J" d" o# w
   
( z. M" p% N0 S1 U: K4 q    value = GetAccelValue('x');1 m. A: P" }/ r4 d# \+ C7 ^# m* O
    if(value > 16384)6 N% X5 i4 m% s/ W9 j* E# H
        Angle_accel = -(asin(1) * 180 / 3.1415296);
  _( N# q; X# x  `5 F; J. j0 @! S* k    else& G6 k  A4 ]' |2 N
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
& y' k2 L, Y( j. H   
% k& V! @5 k$ h. c) l' k0 Q    return value;
. [: \5 c6 q2 o( C/ h4 T+ F" |}" l# r% F) O4 Q

7 g* q2 k3 t5 Z$ }0 V+ L/*---------------------------------------------------------------------------------------------------------*/
3 a' H6 y+ q- @: E: B/*   角速度算出来的角度(积分)                                                                                     */" `' Q# ]+ H3 E9 S
/*---------------------------------------------------------------------------------------------------------*/
3 t- ~: i7 e9 Mint32_t Calc_AngleGyro()4 Y8 [, w" ?6 @* {0 Z. A% R
{
0 z' V( F4 {& j9 b$ |% J6 ?    int32_t value = 0;/ D) G  ]) r7 C: ^9 x- K2 Y
, S% _; ?+ h4 G; {0 r' f# m
    value = GetGyroValue('y');: T# c2 Z1 n2 ~7 _3 u$ |* i
    Angle_gyro += (value / 16.384 * 0.01);
4 M7 }. }( U6 D4 ^0 C8 d+ i; Y- Z   
8 G% d# O% S8 X5 _* o1 Y. b3 ^/ n' {    return value;, K3 g; o+ _( V/ P( c- a
}( s" W" `; U4 Y' }" G& y0 Z2 x

+ p, M/ i# b) }% B/*---------------------------------------------------------------------------------------------------------*/  s9 a& q1 s8 V
/*   互补滤波求角度                                                                                     */8 M' j) ^2 [3 T% A3 w
/*---------------------------------------------------------------------------------------------------------*/2 T6 z- @) G0 {$ l/ ?  Y5 w
float ComplementFilter(int32_t simpleGyro)
, l4 }7 A6 g1 Z{% @' U, `* s; g9 L# h2 V' K
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;+ ?. {4 ]5 t& |7 j
    3 V. h: [7 m9 v+ b
    return Angle_comp;9 A4 f% J3 k% {, j0 Y0 D
}- z( A: ^' U! j% m  m( M' ^

. v% H; Q. z0 Z6 N/*---------------------------------------------------------------------------------------------------------*/
4 I7 d# ^4 a$ i; E' A- E/*   输出角度至上位机                                                                                     */; N0 z3 u8 v: t1 K
/*---------------------------------------------------------------------------------------------------------*/& Z+ e7 T% W( R, g- O
void VisualScopeAngleOutput()
" s- Y* v: S' m( A{$ R2 v( S9 ~# H" u# ~
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;: S$ j$ S! C  E! y' R% B- S
    uint16_t crcValue;; `8 @8 B$ u' n
    , d& X( n7 o6 d, D: ]
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
3 X7 e- e0 V8 w/ j    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);1 U. u! ]" |6 Y1 g* G
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
; M) M9 |" v, a- u   
$ L- w1 F  x+ v: K8 k    outAngleData[0] = AngleValue_Accel & 0xFF;$ v( R' ^2 n' Q, }6 l
    outAngleData[1] = AngleValue_Accel >> 8;: }: X6 B; N6 J  D2 b4 ^
    outAngleData[2] = AngleValue_Gyro & 0xFF;
+ n2 [* |  n) s( K3 I    outAngleData[3] = AngleValue_Gyro >> 8;0 F9 _; Q, t5 N* m7 T
    outAngleData[4] = AngleValue_Comp & 0xFF;
4 ~& z9 j3 c9 A7 q9 P* e" Y( n    outAngleData[5] = AngleValue_Comp >> 8;
/ {, \5 `' X% N* P8 I: L( d    //计算CRC$ u/ W* l, W- O, \" Q
    crcValue =  CRC_CHECK(outAngleData,8);+ i' q/ ]+ n' f( S8 e: h
    outAngleData[8] = crcValue & 0xFF;
  Q/ Z0 |+ z0 Q: U4 [' W/ e    outAngleData[9] = crcValue >> 8;- V0 V  W3 t7 J( M: g
    //发送至上位机# O* W& s+ L) b: N
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));5 e8 e1 v! e3 d: P4 D
}( U! t6 f8 e- a- j; L
/* USER CODE END 0 */
! c- e- x7 f) H' v
7 ?2 Q# g+ D, g' {) Z! C+ a/* Private function prototypes -----------------------------------------------*/9 e$ o+ f/ g2 n/ R7 G9 f' A7 \
void SystemClock_Config(void);' U  a7 F/ E) C+ k
( v0 @6 U* g4 J& ^. Y5 [
* d" Y' @' [6 G% F" k
硬件连接图:
1 y6 N! U5 U3 G1 L% a 1.jpg
4 G% G: r1 u) p9 _% P1 _6 ~波形图:: O8 i7 X) ?  h9 u+ a! g
2.jpg
1 ]4 R7 B* {1 H3 m- c+ P最后加一个视频:
0 T' F1 P2 B2 Q/ G. ?STM32L053 演示
" [/ }0 L# E% {2 D7 A+ |# b: r' |
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C, T: t0 J' ^3 d% |* _( a( q9 C
#include "i2c.h"2 z9 E& R8 e& u' `, h
. r  p  \( B+ f- E
#include "gpio.h"
; ^& C( r+ W6 s% `8 d! b- n. w$ t
6 y' t9 b, Q: ?! A1 B! |2 s3 H/* USER CODE BEGIN 0 */! \- {3 F, D9 G8 i

, K* N. A% F$ g6 [/ L/* USER CODE END 0 */
( ^4 e3 x7 e4 D3 l4 Y; H1 ?# h4 V3 L! M$ A5 C+ `
I2C_HandleTypeDef hi2cx;
0 Z6 m: o) A3 c# y" M! C0 o# Q/ L* ~
/* I2C1 init function *// j2 z( |" X3 A; O+ ~% {
void MX_I2C1_Init(void)
9 Z$ V. `3 p; R/ Y! V9 r. @{
  d) i4 i6 f; V2 Z1 c8 l( S! @) {2 M6 `
  hi2cx.Instance = I2C1;' d) R( _. X6 v
  hi2cx.Init.Timing = 0x20D22930;
  Z7 b& O. V: X: j' G' P# q. t  g  hi2cx.Init.OwnAddress1 = 0;
3 R0 E' e9 b0 [* g1 `' x: }9 u  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
- o1 c- o- I7 A) u0 A0 S- E1 e  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
/ M7 n0 q/ u  e3 b7 d( ^7 ?  hi2cx.Init.OwnAddress2 = 0;; v6 C! M4 t- V' _  _! c
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
1 x! |$ C! t& E1 h& Y  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;. L% o  [; L, f/ f3 d1 \
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
" g9 V7 E# E* j$ s: P8 ~/ Y. Z: f: [/ Y  HAL_I2C_Init(&hi2cx);
) ?$ p9 k$ Y$ t% v4 @0 {9 R# C7 a; v) G1 y- G2 F
    /**Configure Analogue filter
$ ^8 Z+ z" {& `5 E- r- K    */
* b! _* h. y, w7 f; R  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
& T+ m) `% I$ e( [) E7 n/ m! {" [& [' U9 |; m2 R; I( K+ X4 u
}
7 E: E) F. K. Q3 u$ W. _3 V; Y+ i) ?" s$ P
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)- |2 X! G7 L5 ^# `
{8 p2 u* b0 M; H% k( P8 z* l

! V: t; r4 K7 G& N& V. v0 V4 s  GPIO_InitTypeDef GPIO_InitStruct;
$ e4 b8 y- L2 ?, r: D7 u  if(hi2c->Instance==I2C1)
( _# |9 [+ e4 o/ \  {  e5 |( A0 @' ^: B9 e8 Y
    /* Peripheral clock enable */1 ~! E+ ~! J6 P& n
    __I2C1_CLK_ENABLE();$ B+ S" t0 @/ c# X
  
& K/ S# j! v/ ~! V; J/ L    /**I2C1 GPIO Configuration   / U2 I- T8 v$ K: g9 u; W5 y
    PB6     ------> I2C1_SCL
1 n0 @# R* p5 q* x    PB7     ------> I2C1_SDA
, t0 N- S' E" t2 y& b% N. Y* \    */
8 l: s$ G$ Z6 k. J& B# H    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
8 C2 y9 J1 o4 p1 c. M* m    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;3 f: s$ {, x5 w# Z* \0 |
    GPIO_InitStruct.Pull = GPIO_NOPULL;( Y1 h; x# m; n; _* m
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
2 i- A$ W' O9 _( |$ `    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;8 d( y' O/ x8 [& w
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);) |8 X( x5 [6 b6 a

: F  ~$ c7 t9 h/ R% h9 |; o  }
4 o: G0 d- Z+ E}( d* N% V* I$ I; ^( M6 }7 b* M+ ^

! g% h5 I1 c$ B$ A3 _void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)8 H) D. _8 d6 a4 [
{
: b$ t6 [$ _. u3 Y0 I% ]$ U$ Y
! C, s* p8 C  q% x  if(hi2c->Instance==I2C1)2 `, m2 c4 ?* ?) r% G) l
  {) }- u9 J2 z0 S) y; Q) Q' \7 s
    /* Peripheral clock disable */. G# T, @: y/ c6 N1 M* d% Z$ I; S
    __I2C1_CLK_DISABLE();
& n4 o9 o# @2 |# J  ) j/ Z+ a6 G8 Z, E
    /**I2C1 GPIO Configuration   
- ^, r% O: @: j- g/ [4 a    PB6     ------> I2C1_SCL( E! C, w2 P  m3 ^
    PB7     ------> I2C1_SDA/ {8 b% k" F3 G$ P
    */: Z0 K' W. k# H0 F" [, P! y
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
# i  c# i" T" g' Z, g* D/ b- `* @) o) ?
  }3 O; V& E3 E! R: j, I5 o
}& o* Y3 k8 F* k, A
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ w3 B, Q4 Z( P" B
usart.c9 g* `5 d6 _+ k) Y9 Z- p
#include "usart.h"8 i# w3 v4 X* f5 b  M0 v
+ M) v  o+ q2 s/ V4 }% _, r4 X
#include "gpio.h"
( z: b9 Q* G% J2 [. ~#include "dma.h"
: K& u' C0 p) e2 @! x6 J) A
; y  ~6 a" R/ n# T# Y; T% M% ^/* USER CODE BEGIN 0 */4 u; X' r0 `1 m5 ~
; z- j6 I2 u" W! }
/* USER CODE END 0 */( |+ L) z6 u% v
6 T( z. Y: h& k
UART_HandleTypeDef huart2;) e' l. T1 F- z
DMA_HandleTypeDef hdma_usart2_rx;
- ~! [+ z( v7 C$ w& oDMA_HandleTypeDef hdma_usart2_tx;
' I( Z1 h2 @) j
! _1 a. ~" f0 _$ V# K5 C1 E/* USART2 init function */
! Z, R) I0 ]' S" u9 B& I% w
' G2 o+ b" c: Q" k/ J+ @1 n3 ]void MX_USART2_UART_Init(void)
/ H/ W0 _3 f8 r2 d9 f/ b{
3 q9 G& I- i6 L2 D' n
  ^' ?& I& M7 i5 l# @9 A3 {  huart2.Instance = USART2;
6 Q2 ^- Y% U, f8 M  e' G2 @( J  huart2.Init.BaudRate = 9600;
, N' ~% m( Y9 x+ ~  ~  huart2.Init.WordLength = UART_WORDLENGTH_8B;
4 E! r/ p3 f6 p2 B- Q  huart2.Init.StopBits = UART_STOPBITS_1;
2 @) V; h& ^% X$ b  huart2.Init.Parity = UART_PARITY_NONE;
" I. ~- x0 Q& ~. M+ y  huart2.Init.Mode = UART_MODE_TX_RX;
% B9 A( n8 t0 ~: ]( p  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;- ^. \0 t% V7 ~' N
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
0 _% M9 ?3 g( n( h4 x  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
7 m6 p% k* K" Q8 j! n. R0 G  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
& w( R! D# a$ }4 A6 S& I  HAL_UART_Init(&huart2);# c( c- m7 Z' Y

. ]6 V/ B$ m0 o8 ]  p2 K7 c}
/ D2 z) {0 `) T8 A5 g
9 e8 c( P! I7 @9 t, ^void HAL_UART_MspInit(UART_HandleTypeDef* huart)5 y$ v9 n: C& K; P. Q% p: Q
{7 v, E0 ^1 T! q" W8 C
8 C" t4 Z; z& O
  GPIO_InitTypeDef GPIO_InitStruct;/ H4 A5 R6 {8 e- G# |
  if(huart->Instance==USART2)
2 K* t1 W: R1 W9 [1 @  {
, o" [% q# Q9 `( X! e) ]  g    /* Peripheral clock enable */8 }+ x) B  M' u
    __USART2_CLK_ENABLE();
0 Q5 [/ j( W- G1 l" Y- @; T' r  
, Q' S: p& Z, }- n    /**USART2 GPIO Configuration   * Z# I5 S4 D2 t1 J$ W
    PA2     ------> USART2_TX- g4 f" I" K/ r
    PA3     ------> USART2_RX# W; d. d9 x5 \- {+ w
    */
# C- g% l- }! B; l& Q/ o4 a    GPIO_InitStruct.Pin = GPIO_PIN_2;
- r. B! r! O  m. N    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;% R0 N* w- ~# v& d
    GPIO_InitStruct.Pull = GPIO_NOPULL;- ~# g2 O3 ?+ r$ o7 ^- v. ?4 n
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;# t. Q8 T' P3 W. A
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;1 f7 N  d( e( H5 n
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);% o, a; [+ c& Q$ S( z2 k( G
: S! {, d4 }  W3 f) k7 N/ o
    GPIO_InitStruct.Pin = GPIO_PIN_3;' P0 q! U8 G8 I- B/ e' a3 C
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  H. [' j$ N# P( f8 C
    GPIO_InitStruct.Pull = GPIO_NOPULL;
, j2 G5 t: O+ N5 t' d9 p) a! W    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;/ _4 P, U8 M* q3 d7 K) c7 N& {1 i
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;% I( l6 M7 Q8 J* a7 P
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
! M* n: t9 d$ P7 k- o( H1 ~
3 ]: {% P0 R7 ^9 c    /* Peripheral DMA init*/
; {6 z* ~' U3 p3 f% Z6 Q  " Q5 z% t  B% C; X. U" |
    hdma_usart2_rx.Instance = DMA1_Channel5;+ i. |: G+ `. d
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;" u5 Q7 p+ ]- ]( d! I7 k6 v# K
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;* U$ z2 }- D5 ?& ]$ c
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;3 z& d. U4 U/ @# x7 C: |$ A2 d
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
2 F8 H' V) n& Q3 o    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
1 ^. p) j- G& c& \    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- F$ x1 b* O* q0 O
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;: o8 \0 Z% B4 m$ }. k
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;# h- t3 n5 X* ~  Y
    HAL_DMA_Init(&hdma_usart2_rx);$ R8 t; W$ P: W
: v$ b& @& s6 O3 ?$ n$ X) e3 Z
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);7 T9 M5 H, P" b1 q4 t- C4 X

6 F  {# D0 s0 Z  D" x% b3 {! @2 a    hdma_usart2_tx.Instance = DMA1_Channel4;- Y) w6 I* p3 i8 Y8 A2 z* h/ c5 p
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
2 h, Y8 J2 }4 S& R! w    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;9 X3 |3 g' r1 m5 p, y: N
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;9 V: k7 H) D" ?' Y
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;0 Y4 C- i* r+ q1 u* X! p( s/ y9 B
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
: p8 s9 ?8 H! P& L    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;1 O4 u% L9 m( F& p0 b0 L9 H
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;3 i$ T# W$ B5 i1 N" I
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;+ D, _7 x1 _- z; O. F% d6 e, e$ V
    HAL_DMA_Init(&hdma_usart2_tx);2 ^  |: q) g3 ^! |6 R
4 D, D# {. |. S7 i" l0 v
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);  ^' X% m8 K: d2 k6 Q- t7 h

0 o: W  u5 }0 u8 E  }. \) T8 X0 V2 ^
}
4 V  _+ k  `, x. x3 @/ ^
8 p5 T0 {" k9 I/ A# Q$ t7 p$ L0 r1 ~# Xvoid HAL_UART_MspDeInit(UART_HandleTypeDef* huart): I* ~; q- _( G- s
{5 \) W( O. n5 t# L
" k3 \$ i1 v. q. v4 |
  if(huart->Instance==USART2)! s- Y0 F  W) f* @
  {/ C' v* B3 X7 n+ T8 Y
    /* Peripheral clock disable */9 d* K9 E/ T* Y5 B6 W
    __USART2_CLK_DISABLE();7 R' Z8 n: m3 x) D9 b% U  t7 \
  5 B( @) z" B1 }3 t& E9 t
    /**USART2 GPIO Configuration   
  x7 l4 ^6 w; R  s8 U    PA2     ------> USART2_TX
3 b- X1 \  S- O0 L9 a    PA3     ------> USART2_RX( [7 d$ p5 H1 Y3 \8 I# ?
    */
; V3 Z6 @+ B3 A/ {    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);5 w3 ]4 h2 k9 u6 b7 i% t5 ^
. h- V* U" b/ l4 \
    /* Peripheral DMA DeInit*/
/ t/ ?. n  ]  L4 g    HAL_DMA_DeInit(huart->hdmarx);
$ p$ M% }8 V& C# b4 x/ s7 c    HAL_DMA_DeInit(huart->hdmatx);
+ m; [" N2 }7 J) T  }! Y: p; G' K6 F! z/ G0 t
}
1 r$ t; C. e; J& t& P) _# @8 e------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
& T. L) q$ l- W9 d  _5 V& nmpu6050.c: h+ b$ T0 A. t
#include "stm32l0xx_hal.h": A7 B4 Q0 Y! C2 v; {2 W. V8 Y) X
#include "MPU6050.h"- \8 ~5 N; ~" d) T$ F

0 @: q* H/ Z! o7 g3 L) U//各坐标轴上静止偏差(重力,角速度). ?' z/ ]' q; `+ G. [
int16_t offsetAccelX = -195;/ a# U5 C- L5 \2 V4 q
int16_t offsetAccelY = 560;
5 S8 e# M8 K5 U: ~/ U8 j, m2 F/ Y! _) Fint16_t offsetAccelZ = -169;
  N# r( j/ V9 F4 T. J' Y# Z
; t( ]+ s0 p& E# }1 c. j+ j, Bint16_t offsetGyroX = 12;
7 T4 q# w/ z/ xint16_t offsetGyroY = 33;
0 h5 o  E1 k. d5 R7 L2 c7 Mint16_t offsetGyroZ = 4;
7 r+ [4 b0 b* {/ i! W7 D/ o/ f: D5 L1 N# Q! ~0 n
extern I2C_HandleTypeDef hi2cx;' n; |/ F6 l4 R9 U

/ J/ D% L# I0 f5 h1 X1 _. I//**************************************/ f9 O0 n9 W0 i6 Z+ N
//向I2C设备写入一个字节数据* ~$ t. H4 U8 R& r8 O
//**************************************: L7 k0 |' P9 O4 N: s" h
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)6 \, f% c) {5 l6 l9 f! C
{7 s- I( _$ S) }& _- T4 D
    uint8_t rxData[2] = {REG_Address,REG_data};
8 Y- ]+ t3 O& y) h" ?* M$ m6 K  S    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)" q8 |: I1 T7 [3 y! }( P4 r
    {
  R- z- h& {% {4 R. p7 _        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
7 ]# M# J1 s+ H$ n        {}
' A+ W0 L# i9 _& \    }
9 _) K( C8 G, j: B3 ~. \: q% H( ~}9 R9 v/ F! q" r9 v* @
//**************************************
7 W7 G; l; |' M2 i% R6 z//从I2C设备读取一个字节数据
  _# d  M$ B" B2 G//**************************************
% D$ B; p5 p1 w3 H* F) Kuint8_t Single_ReadI2C(uint8_t REG_Address)5 i+ S+ v" q* U& m9 i
{, w# x& ^/ x  t8 S$ s
    uint8_t REG_data;
" X+ i& L1 p9 n, L% s( |/ s    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
" ]! z; m. \6 S8 i    {% H, J+ p8 B. M: l# ^$ {0 }
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF). M* X6 V* S3 H0 E; Y
        {}9 |! r& G% j: W
    }
8 ~3 Q$ T3 Y3 A2 U, a6 N1 D5 H   
" u3 c7 E" z) x- l# _    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
4 {. h7 l* o% i3 b3 A9 I1 `" S    {% ?0 A: l% M; F9 H. G
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
7 t* O! x- v9 z' ~' J+ K        {}
# P# E3 A8 U6 \3 R% B    }
# w# N, C3 M  M* h4 D( @# u    return REG_data;
/ E! T, z5 Z+ ?$ V) V}6 p" I9 ~" r9 A! m
//**************************************
/ ^, l5 d9 o# x% _, o( [+ I# ~//初始化MPU60504 b: F0 C2 J6 [1 k
//**************************************
7 Y' K: x) x% j4 r9 v4 [7 Cvoid InitMPU6050()
  j4 \2 a' \; A1 x8 J6 H, Q0 V# U{
/ h  M& R1 M, j+ U# a    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
$ o( R- N, s; P8 U! }& I* l5 k7 p4 q7 E) j% x3 H: v4 W
    Single_WriteI2C(SMPLRT_DIV, 0x07);* f9 _' R$ Z+ V+ @: F) q

" g7 `# `3 y: _% q% l4 y    Single_WriteI2C(CONFIG, 0x06);
9 g2 H! ^- V! y& _9 i4 v5 T6 J  l' |  {: m; d9 t, T5 }4 M+ ^
    Single_WriteI2C(GYRO_CONFIG, 0x18);
! O! u; x! y) a3 d/ Y8 X: b) {7 ]& Z) `3 g% t7 {  R( q: y4 l
    Single_WriteI2C(ACCEL_CONFIG, 0x01);: p4 F' `' F* g) R8 f
}6 k$ J: L6 I  D
//**************************************
* K4 x* T' s$ a& v//合成数据
" H" F: h/ d- s- [# i! V//**************************************
) K8 X+ X6 |1 v/ wint16_t GetMPUOutValue(uint8_t REG_Address)
  ]" k' i7 e% ?{) y. w* w1 P* Y  j# C+ f
    int16_t result;
2 c  s/ o7 }* G( H4 D+ v    uint8_t H,L;, c& R6 d0 N: }) ]& g2 l* E3 r
    H=Single_ReadI2C(REG_Address);
4 d$ x, e! B( Y1 i% h) C    L=Single_ReadI2C(REG_Address+1);
' L" H2 q# B: Y. a8 m    result = (H<<8)+L;: j4 [* Z* h) M* m4 T. d, d
    return result;   //合成数据
3 G7 q1 I# g9 k2 [: U" ]. i8 m}
3 N6 D* `. w; X% C- a7 c# m4 J7 p$ ~9 o
//**************************************8 `' T. B* \6 u
//取某一轴上的加速度数据; t; {/ H3 ~0 i& v* c
//**************************************
7 b( q( s% N, s# Eint16_t GetAccelValue(char axis)
3 a; E" @# ]* O{
( }. \& j3 R4 L1 S% I    int16_t result = 0;
+ \3 a: N7 |2 O    switch(axis)  q) Z! b% k; [2 V+ s0 O0 j
    {# Y0 B2 ]: }' y# X4 K' G& p& K
        case 'x':, T, m. a5 @% c' R4 P
        case 'X':
: B6 c2 j) j  X: k5 ~2 T        {# w4 t6 Q: m9 k3 Z. e8 \
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;2 Z2 E+ @% Q' c- n+ c6 v" y3 [
        }+ ?/ M' A6 _4 b9 }
        break;
! G$ J$ D9 e" ]* Z, X( V9 X        case 'y':7 j4 n7 w7 \' u, `
        case 'Y':( o5 h1 Y' n" E  ^6 B
        {( Y! ?# i# R. n; i0 W3 B3 u
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
3 _3 A2 e; h* }$ i9 A        }  R- J8 Y! T/ Y7 |1 t
        break;
( h  ~4 t9 c+ E2 h; H0 I$ X        case 'z':
" A, Z5 r4 X! x% G6 G        case 'Z':
' s- X5 `4 ]+ w6 W        {% o; {1 B7 W2 S' \7 }& ?
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;$ P% d1 U2 {' b9 {+ i9 P
        }- V$ R8 x. h6 j* t( M
        break;
0 A: y3 \' _* \/ E% [    }
' k: ]: o4 F7 @6 u    return result;. v7 g* P+ r5 m
}
9 L8 k9 Y6 I3 ^  |% L- E, \3 i/ c% t0 l6 H' h6 L; x; g- x( L
//**************************************7 z. B; ~1 @* I. ], Q* W; h9 x5 |* o8 Q
//取某一轴上的角速度数据
8 f4 b! c- l! T0 i( C//**************************************% w! r) u6 l* l9 A4 y
int16_t GetGyroValue(char axis)
; G6 A$ P% T0 W5 P' i{
( Q  [9 m6 k1 f! q% _* A9 T    int16_t result = 0;. K0 s& _0 {+ A
    switch(axis)
' Q  j/ A7 `% G    {1 a! X- L/ b* e# ^- ]) C
        case 'x':1 Y& g# r. E5 O( B7 {3 H2 R
        case 'X':
4 Y% S: U3 V; v# W        {
6 o  w* o  L2 B1 V) T% M            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
: x# O. I) o% s3 l: L5 J        }
+ T4 ^6 F4 E7 z' l        break;/ @! ^/ m7 i9 b, M/ J
        case 'y':
& k$ |4 D  M6 ]& b  f6 }        case 'Y':
" P' M4 M# ^1 a; n        {
0 I' j/ a* y+ O            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;9 ~+ i% k4 ?/ o1 L6 b
        }6 M" y( X$ I! A, F" r4 O
        break;, O5 |) Q+ l% d
        case 'z':' _$ E  U. j; y
        case 'Z':
! A# `. Y8 ?. h7 K- s        {* |5 w, B8 W6 p8 t9 c2 _+ X/ y
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
' U; d7 l( Q  o        }! @# F  D: f  @; ?" B
        break;
: @8 G' Q8 U; ]& c: c    }7 W$ d1 G/ X/ H( u
    return result;, c2 v2 s& R: V- S4 g
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)3 ^4 ^3 j( Q4 u6 v" A9 r, S! ~
{% E9 S0 e0 b1 U( E- f

5 x1 d9 s- [9 E( {* F" K  /* USER CODE BEGIN 1 *// k% q5 Y: D  `9 o7 |

% ^: ^$ M, M% L) s  e* w: l  /* USER CODE END 1 */
4 ?+ X+ ?3 s  Z5 d
9 r, m" N' N2 M, J1 w. a7 F  /* MCU Configuration----------------------------------------------------------*/
( l+ ~! U  l. M2 i, ~. l+ u8 N+ V1 c* {" ~. T# i  D- \
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
( J3 n( j! z" X3 i  HAL_Init();
* x2 ~5 {5 H2 t
3 L: r* A- a0 N% T, e, _* Y  /* Configure the system clock */8 u( b0 M0 B) G) \1 s2 K
  SystemClock_Config();3 G, F) t+ d8 [4 o7 m
! H# Q' v8 i) t4 c" a
  /* System interrupt init*/3 D  f6 Y8 j, f$ I9 K4 {( o$ H
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);. y* ?, D- L3 I$ p
" n8 g9 t- d( D# u1 E# F
  /* Initialize all configured peripherals */
3 V1 r5 F; t2 N  R6 l, G. u3 N  MX_GPIO_Init();! H+ N* e/ K2 @: N; J- }* ?6 Q
  MX_DMA_Init();
6 q0 R! q8 }# U# s- s    MX_I2C1_Init();% ^" ~, d( g# c: U; M. H8 T
    MX_TIM2_Init();  K# T+ c! v- P5 d# h8 \6 l; V# }2 }
  MX_USART2_UART_Init();1 j1 a# q, q7 f3 N8 W
    InitMPU6050();. b, S0 b- e- i( o0 H" F2 ^1 {
/ W, Q, I$ i! ^' @  ^
  /* USER CODE BEGIN 2 */
# R- A) g) I; l$ W/ u    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
/ S5 Z4 u# V% y# D! A2 G    HAL_TIM_Base_Start_IT(&htim2);
" o0 w) t& I. `( E2 S2 X  @  /* USER CODE END 2 */; [4 z$ a7 K* D: n" S4 \
& I& G$ ~4 ]& ^
  /* USER CODE BEGIN 3 */
) ]) q( |/ n$ {" F  /* Infinite loop */! y' ?- L3 U) n. H: d# t
  while (1)
7 t' c3 S: h2 w' {  e$ z! k4 X) T- Z  {
4 z/ {; i4 O. O4 Q- i1 F        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
" V9 o* Y0 V6 G0 k* E8 F1 Z; a        VisualScopeAngleOutput();
; ~2 Z5 \' n2 f# s. t        HAL_Delay(100);1 Y$ @! |7 m) v6 o5 _: d
  }6 H2 L8 o/ r0 ]' @5 f" J/ P
  /* USER CODE END 3 */5 B: X/ F: O# S/ ]+ G! C% s
8 t2 A' V! O* i$ s$ L4 w. O
}: f% ~( c$ z  C) H

8 u* K' ~$ V+ ]% C5 Y8 C- g& S/** System Clock Configuration4 E" S; Y1 _% g  d$ k0 |
*/1 _  G) f: x! e; D2 O0 k
void SystemClock_Config(void)9 C0 B" @. ?6 j1 e
{0 H  p, x9 `( [. G7 J

1 i2 q( @1 v- e# G0 I1 j  RCC_ClkInitTypeDef RCC_ClkInitStruct;0 g: K( m0 i% h/ a% z9 T
  RCC_PeriphCLKInitTypeDef PeriphClkInit;( P! k0 h3 |- ?
  RCC_OscInitTypeDef RCC_OscInitStruct;$ g; P8 \! t) ~  \; B2 G
  Y2 [) t) `7 W. U6 ~
  __PWR_CLK_ENABLE();
/ m7 ^; s7 y" p' K: A
& ]8 G* k3 U$ W, X  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);% @# }" ]9 G% m4 c4 |: {: m

7 S* p0 m. W' `8 M  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;0 Q7 l5 ]* ?/ X5 @8 j' e  f% K
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;; c. ~! z3 o& b0 P: Q# F
  RCC_OscInitStruct.HSICalibrationValue = 16;
9 ^8 ^' I  z. L! H0 f4 _  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
: z7 A8 K+ U: J* z  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
' z$ k" Q, ?: u' l& O  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
8 `4 U& z. `: _; g! M$ Y  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
, J3 N& p- r$ T, @- V# `) X. X& A  HAL_RCC_OscConfig(&RCC_OscInitStruct);) L7 B' ?3 O8 ?8 h! A

  i, U; e1 Q, z/ a1 G  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;8 q3 Y4 `) U, o: k
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;4 H5 z5 B' C, r' t% H6 Y2 E; C% s# l
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;0 @* C/ Q9 N* C+ f( d
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;( \6 c7 Z, O! e; n7 p! V2 M
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
6 Y) w: m( S0 `5 |  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);( ]+ N+ w2 W7 u) g9 e
8 G; z9 ]5 e; [0 S% M
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  U& m# N. S3 W. l  w4 h  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
+ k4 b2 }- C  Y1 ^  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);" v: O3 Q* e' H+ i- A) m
$ d4 V- q. I9 X* G. M. {
  __SYSCFG_CLK_ENABLE();; w+ v5 P% t2 g: }/ i+ `

1 H2 T% h$ B; v5 x}
8 t+ |$ q0 o  z/ c: j+ z
* q+ v* ]2 c/ r5 p* F/ D! m3 }" z7 i/* USER CODE BEGIN 4 */) \: K2 A5 C3 L  h' s8 J; S; l
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
) s! t7 M( a9 {' X2 r- [{
/ C/ L% T3 [7 l2 B+ m    if(huart->Instance == USART2)& q+ z. _% U- x& ^) u
    {# S% F$ F3 F% a- K) a5 g5 m& K
        memcpy(txBuffer,rxBuffer,RXSIZE);
; K5 a1 c( o8 Y6 m- U8 U        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);/ r& c2 q- P% j& M; a5 H2 ~+ A6 L$ q
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);0 U  t7 z, q* l) k
    }0 N6 ?" k( F# ^7 X6 ?
}1 L: T" p# _9 \1 f
7 ^3 I; T- q! B" U1 |+ H
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)( V0 r7 i( _6 x  o$ }
{+ |  r6 o7 i: S; H
   ' x; Q/ @. x" @/ D( a$ D. p+ ?$ H* E
}
3 Y* P: N& X  a  \
8 q( k! ]$ f% K, @7 g* Y& o) Ovoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
( l3 p% E* D4 n9 q! Q9 \7 G{
2 @) H, A+ Y. ]8 ~    int32_t GyroValue;
, o0 k! h8 n& t7 F1 L' ]- I) a   8 V: o0 y# r2 b
    Calc_AngleAccel();  Z8 n: K* v( C3 K, E8 `3 H
    GyroValue = Calc_AngleGyro();
, b# f+ @7 [) g9 O. G2 s6 x2 m    ComplementFilter(GyroValue);) K$ }: l& S, T8 Z' F* i2 D# c/ i- 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
* t/ k  R& `0 Z& Z% K4 h, ~, s* n6 e楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
' B% `5 z& n# \' M; s( v
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
9 p4 }! R- d4 N楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
. H/ T3 I6 X4 W0 ~4 K
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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:217 w5 l. L. O' [$ k* D2 o% K. I
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

2 T+ N  J8 O# z6 [好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
5 M/ D: e8 E' O0 q请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
( S3 b! e8 ?: ~3 B楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
' G! {- Y2 V! u% N" z请问应该注意什么地 ...
! V: n/ r4 H1 t8 D, h
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版