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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:& U- ~$ K7 A' I
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
% F2 V( z0 R- T7 Q* ]! `main.c
. h" {& H0 Y4 _6 a) e#include "stm32l0xx_hal.h"
# M( l2 f; O9 Y8 A, N( A#include "dma.h"
$ G* B6 n) j# H* O#include "i2c.h"  y) M% M4 k$ y0 O' ]5 B4 B
#include "tim.h"
1 `: ?' P5 k( x+ W8 [* r' m, @#include "usart.h"! a3 ^4 r8 o' E; b
#include "gpio.h"
6 ^0 x, c$ R7 i7 `#include "mpu6050.h"
2 O- W( |1 `+ J8 `#include "visualscope.h"
% i3 E1 n: J; ~2 q% K  r* I7 G" C. m1 n4 Z
#include <string.h>0 I8 }4 ^0 Z" ?+ D
#include <math.h>& B3 o, [. m; a& v& J
* D( O& j% o/ a/ H  Q# d1 k
/* Private variables ---------------------------------------------------------*/
- U2 P% P& a5 \7 N#define RXSIZE 8
: d7 d- S5 p! W4 v& k2 O% N#define TXSIZE 81 g7 l& j; q, N" `. |# P0 c
uint8_t rxBuffer[RXSIZE];
* c3 q7 S8 f, Y& p: @uint8_t txBuffer[TXSIZE];
4 F0 J- h( L) @5 t- l% j1 a+ g+ k4 W4 c, s5 h( R& Y
float Angle_accel = 0;8 X8 J( G% F8 `/ j% E: K9 b
float Angle_gyro = 0;
3 Y. X) M, o# C8 w6 s& Ffloat Angle_comp = 0;& Y5 @: D8 K& G# g' {
uint8_t outAngleData[10];
( @/ P+ f. m$ p0 w/ q0 M/* USER CODE BEGIN 0 */" p) |( d. m. _# H* }

- R  r4 k& @+ k4 S0 ^/*---------------------------------------------------------------------------------------------------------*/2 V- n: Y- w) u$ c  _
/*  重力加速度算出的角度                                                                                       */' T+ y6 `; a: r3 v- m, a) _1 c+ o
/*---------------------------------------------------------------------------------------------------------*/
# o/ R7 l8 O* c2 S- I/ \int32_t Calc_AngleAccel()
' X% i/ f& {) T9 ~2 \/ T# Y{: W5 k" _9 ]/ B& b. s
    int32_t value = 0;
4 o& P/ g  }* J2 e: h   
3 ]! F9 g) n7 x: U5 I* Z4 @    value = GetAccelValue('x');
( C6 ?! Y8 B) j* G: a# z    if(value > 16384)
) q* b( s4 x* `6 _* R# t        Angle_accel = -(asin(1) * 180 / 3.1415296);
( G* ~/ l" h4 ^' \+ K7 w9 q    else1 g9 C8 S( D+ ?4 F; ]
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
) E; D" ~7 G5 N- g4 u  d  Z. d( G   
8 V2 u' E7 Q) b7 X- M) u    return value;$ x8 R1 @- L, l' M2 O
}: @* U7 a, z1 m- y

- D) U1 i* ]# Q+ S. P$ [# L/*---------------------------------------------------------------------------------------------------------*/
$ Y2 V, b4 T# b9 n* G; ?/*   角速度算出来的角度(积分)                                                                                     */+ I4 R& Q- k" D+ M( r
/*---------------------------------------------------------------------------------------------------------*/" {$ S- r- P% Z/ M+ k% L* c6 w
int32_t Calc_AngleGyro()
3 c9 c% Z$ W# \# }" H5 u9 g: M4 F{
" A8 W' j& M( z3 T* T3 L    int32_t value = 0;
" A  x( w* v: E- K  E4 f: y9 s7 g4 c% a6 T: B$ N6 G
    value = GetGyroValue('y');
; _7 h# C2 c4 z" u5 t) a0 o    Angle_gyro += (value / 16.384 * 0.01);
* r/ _' ^$ y' L  t2 O   
' I2 R4 |% N' Y$ `    return value;% R( {- b0 @3 {  _
}
8 Z. [: `& Q9 K. p8 Y; x
# P& X6 a" ~  M6 s8 L/*---------------------------------------------------------------------------------------------------------*/) Z$ i5 Z! C; t( |: S3 P& I
/*   互补滤波求角度                                                                                     */5 k# p( h  [/ D5 ~
/*---------------------------------------------------------------------------------------------------------*/2 }$ T6 N: _9 _; Q
float ComplementFilter(int32_t simpleGyro)6 f, J; ]6 e/ @
{% q+ j+ g- _; o/ `( S) M! v
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
4 a9 x# }- R/ e( v3 `1 {2 V    3 J4 j; N9 G0 J& F+ D
    return Angle_comp;' n& ?* U2 o, g% G2 `: H3 z, U
}
$ t+ [2 N! b. O, R& q  [7 A+ ~$ f, D5 `2 r, a
/*---------------------------------------------------------------------------------------------------------*/9 b! {. k7 [/ M* A- [3 z' d! L
/*   输出角度至上位机                                                                                     */2 ~, [% u" P! U3 h' }0 a
/*---------------------------------------------------------------------------------------------------------*/  i* B- K: i& |
void VisualScopeAngleOutput()* C8 v1 W8 b1 D/ p5 ?
{
/ b; J& _7 r6 m( o- x- x7 M    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;
8 m- a; z' C+ {; l, R* e    uint16_t crcValue;
- [0 m. D. i# Q* e2 Z% d# s    + v: ~  i8 B8 A+ c8 h; M
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);/ c1 P4 [9 [5 ?* P8 E
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
' t9 ?- d" j& ?+ ?" _' _, D    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
7 m8 `0 p- W1 G$ s' f5 Z* R5 |1 v* ]8 a    * f' K4 i$ P+ l# I4 s! Y: f
    outAngleData[0] = AngleValue_Accel & 0xFF;
# f7 t0 B4 {* k    outAngleData[1] = AngleValue_Accel >> 8;) ]8 p: R2 o7 d1 P
    outAngleData[2] = AngleValue_Gyro & 0xFF;4 ^* {7 [: L6 {- b7 Q9 d, t
    outAngleData[3] = AngleValue_Gyro >> 8;
& v" C$ S. g( R! L  v) W2 _    outAngleData[4] = AngleValue_Comp & 0xFF;' v% a4 t. G, [0 a( C' ?
    outAngleData[5] = AngleValue_Comp >> 8;
3 |5 D9 M8 N# U/ i# ]" D    //计算CRC/ g; M1 M# m; M
    crcValue =  CRC_CHECK(outAngleData,8);6 z# [2 ^% v0 u8 K+ @
    outAngleData[8] = crcValue & 0xFF;7 x, n; X% g& _9 j8 O1 x4 c. l, w
    outAngleData[9] = crcValue >> 8;3 |. J  [0 K( W
    //发送至上位机" R' L& `+ W# M+ d+ ?" _
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
" W6 y2 E5 h  L( s5 T}% ~2 F6 w8 x$ w3 L* c+ n; V
/* USER CODE END 0 */% P& [% p1 b# i  p- `

! |. S( [; E* B( L, j  e7 P( n' }3 ^/* Private function prototypes -----------------------------------------------*/7 Q9 a1 [0 `& K6 E1 r* m; w/ j
void SystemClock_Config(void);
. A$ h7 i4 P8 q
  Z& O: ?& S2 a! r2 ]: I5 P0 Z3 I/ h8 K# ?* ~! Z- N
硬件连接图:
/ ~) O9 K+ ~2 G; u9 ] 1.jpg
2 H0 d; H4 ?: j& }* _( T" H波形图:
7 ]" d6 y8 C. p/ L: L 2.jpg 6 T* C7 G8 N; ]+ v0 `1 }
最后加一个视频:
; X4 L- J, y4 e+ k! HSTM32L053 演示
! w4 V! E0 [0 G- ?1 v# c9 W! |: i
赞 1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
. u9 `+ P6 y: P1 j/ A- g3 i/ |! z) |#include "i2c.h"! c9 s/ m! D* u; Q& `8 s8 r8 G
0 ?5 T/ y, a  r3 r# s! f
#include "gpio.h"
: a- {5 k# J/ x6 p! K2 y1 d! a2 X' t- a3 g4 u
/* USER CODE BEGIN 0 */" |' q% l3 T0 J2 {0 ]  F, c

" v- D, G! J) [% Y/* USER CODE END 0 */# V9 {. ]2 y7 K' [
  |# D3 Q9 T2 B
I2C_HandleTypeDef hi2cx;
2 z+ \* }- `, r" f% S
1 D7 F, o  K+ G' }3 p' K3 n/* I2C1 init function */2 x7 ^# ]! F# X& y5 q+ A( Q
void MX_I2C1_Init(void): S- M" C' @: l! f. l
{
* _* o1 \1 p" A0 k7 ~
) I3 m$ {4 u: W3 l- u  hi2cx.Instance = I2C1;
5 n' g" d% h( N* n& w+ m3 Z  hi2cx.Init.Timing = 0x20D22930;/ f6 S" B9 W" J. }2 y7 u- Y
  hi2cx.Init.OwnAddress1 = 0;
' t4 R6 t+ l9 H& h1 m. U4 r  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
) C* T) E8 [+ c1 W. ?; G1 [0 ]  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;: w2 y( ~* `* _4 L/ J, r
  hi2cx.Init.OwnAddress2 = 0;3 I* i+ u5 R7 s& l! w* D; e6 p: o
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
- Y% [1 p8 V. [) L: J  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
# N8 I. ]8 N9 S1 ?2 ]1 ^8 R  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;3 o% v4 O$ m" m0 E, l% G
  HAL_I2C_Init(&hi2cx);
  e6 Y5 Y+ i! e1 R8 r- {0 W) S1 j0 i. h2 k7 q4 N* k
    /**Configure Analogue filter
/ Y- p3 l: o( T; B+ p, v  [* i, E    */7 z6 N! ?6 s( t5 j  O% j; B& q
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
" R" `4 r! y* b' _. t' B" B( x) {& w6 @+ F" [, Q, \: p
}& s! }4 v' p+ u: U. l; m
( N7 c' x, }% p
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
" v+ a5 z: s& m5 u# ?{- a7 a0 M. t) }/ n/ ]2 q! |3 b

) G3 U0 W3 p- [" m7 m( S# q6 u  GPIO_InitTypeDef GPIO_InitStruct;
& y- g: I0 H& U) c  Y0 R6 d  if(hi2c->Instance==I2C1)9 p# s1 o$ F4 [1 \: _# v
  {
$ _1 e& L3 p- c; |) [) f    /* Peripheral clock enable */
% I; @8 y3 T$ C4 V  r# {! o, J8 W    __I2C1_CLK_ENABLE();
; M: r) S5 ^2 w9 W, A) @  + c/ Q* G3 x% y& X7 H9 Q" e" ?
    /**I2C1 GPIO Configuration   5 p1 A! R4 q5 `- A# ?' z
    PB6     ------> I2C1_SCL! j5 l( o. G( f4 i, [! b
    PB7     ------> I2C1_SDA" Z, b# G( W0 f# \# S
    */3 ^8 u, w$ i7 G: `% n* Y3 o
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;: {: |/ }0 J8 I9 `1 o7 E
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
% R$ ]3 O& U  B" _' h) m+ ?    GPIO_InitStruct.Pull = GPIO_NOPULL;
+ N! O* `& T. V7 G& F& Q    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;2 B" F( r) H; X9 j( o
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
: `* t% T7 N; w/ c$ t6 I6 O    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
8 \! Y2 L* m% X+ p0 S! x* G0 R6 l( D! s. L
  }
$ b' c6 g4 w% \3 A! h7 R}: h6 ?0 L: h/ H* d
0 f# V9 k  n7 `* d
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)6 e, Q$ G) x' D* O  h: F1 a
{
- D, N! ^4 s5 [0 k& r7 t
; c9 a, }0 A/ B, ~8 m# e  if(hi2c->Instance==I2C1)9 h, A3 T" P% i7 p' v& k" W  I; z
  {
$ X, }1 e5 I, @2 n& g    /* Peripheral clock disable */6 v% H( |1 l% G4 T
    __I2C1_CLK_DISABLE();' p* w0 n) v6 h/ d7 L) X
  
' x. ?1 C/ G( ~/ D    /**I2C1 GPIO Configuration     F1 T' [. Z6 J- H0 z  a/ i
    PB6     ------> I2C1_SCL
" O: o: w+ u$ _, J9 x( h3 X    PB7     ------> I2C1_SDA$ N. ?2 S# t, k/ I% p* t
    */( [/ R8 m0 x2 R! O# z- f( s
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);  a  j% p7 _7 ~/ V7 z& [6 M
8 S# G+ g0 V: ^9 n- F
  }" g6 }2 ~# }. }9 Z) U& L
}6 d' s4 p$ ?0 d* u9 O, \2 u8 {
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
9 ]6 w8 M8 r7 _: g! Ousart.c5 v6 d( ?' y# D6 ~6 ]" Z* {/ y
#include "usart.h"
* G/ Q$ w4 W  S  f+ f( W3 O/ h( x0 F# a0 f# L
#include "gpio.h"
: T, P1 R3 O. ?! L4 h8 X' p# J#include "dma.h". o5 y; N2 s7 T  R
# v; b2 L. |2 U" k7 h* b9 W: X; V6 s
/* USER CODE BEGIN 0 */  u2 {' [3 j& ]. ]- {
8 a6 D! e* Q5 E6 v  ?  o
/* USER CODE END 0 */6 U/ i7 m, P4 E+ h

/ l. @+ y' K  YUART_HandleTypeDef huart2;1 C" L" R6 L& Z& ]5 `" }; P, n
DMA_HandleTypeDef hdma_usart2_rx;  x; f9 k$ O% a) P
DMA_HandleTypeDef hdma_usart2_tx;, E7 e: e7 X7 Y" L
4 I' O4 R& _5 Z) P' B* x
/* USART2 init function */
7 N5 O' Y6 R/ U6 w4 Z% J9 N# `1 W2 Y
void MX_USART2_UART_Init(void)
5 F# i' H" ^: O! T7 I0 u{2 U+ Q* M6 G/ Z. t) J& Z# p5 N' c
5 g4 h3 ?5 f4 w6 D2 P/ n/ I& f
  huart2.Instance = USART2;7 e/ ]' l' F' i; \+ P
  huart2.Init.BaudRate = 9600;, |+ a5 R. S% U
  huart2.Init.WordLength = UART_WORDLENGTH_8B;, H& C: h3 A9 Z
  huart2.Init.StopBits = UART_STOPBITS_1;
# h: B$ b0 @& v# x8 l' v  huart2.Init.Parity = UART_PARITY_NONE;) |4 J5 S- N& ?
  huart2.Init.Mode = UART_MODE_TX_RX;0 x4 z  k6 ?, |
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;( t$ j0 r2 Y0 v6 C/ ^1 |* A" w
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  f' @; E- U( g7 y7 ^) U  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;, Y/ A" p# H1 B8 @4 n  D1 ?
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;- l, H' O- [4 W( U3 K9 g
  HAL_UART_Init(&huart2);/ |$ {1 W. }3 ^1 l' V4 T: _
0 a) U! A0 g9 O! r( e
}
" B4 z, b* M, ]9 o+ T  q( y9 o
' b3 l) Q% |; x: V: U7 S, C. Gvoid HAL_UART_MspInit(UART_HandleTypeDef* huart)6 E  C, p/ P( o" Y
{
0 Z" ?& F: K4 ?. s6 e/ e; w) ~# w" _) d. Y
  GPIO_InitTypeDef GPIO_InitStruct;
9 f' M0 ]: W( q- A( J  if(huart->Instance==USART2)9 g) ?9 r4 _) @: Z& ?/ O
  {
' A3 e8 B* P% l2 `2 p6 R0 n    /* Peripheral clock enable */
  J6 t: I$ y2 i/ ^9 R% V$ p    __USART2_CLK_ENABLE();
* i8 X: L: ?# N4 ~5 P$ t; P* F) w  * X1 W% u, \5 _+ k  K0 q( u1 ?1 C- h
    /**USART2 GPIO Configuration   % J; D' \' H4 e
    PA2     ------> USART2_TX
  P/ B- d3 U1 Z  j6 ~4 s    PA3     ------> USART2_RX+ G( X! H1 G# k' A) R3 l0 K
    */
5 B2 I6 ]- w7 b" y& h3 u) ?    GPIO_InitStruct.Pin = GPIO_PIN_2;$ A2 R. r! g; r+ Y% ^0 A- Y
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1 N9 k% R9 h1 R& `4 h    GPIO_InitStruct.Pull = GPIO_NOPULL;6 W8 G7 @+ B, \& F" E! ?
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
! \! |7 V: v; x) K    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;4 k8 r. ]! b  a+ W% B  s  w$ a' k
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
9 J7 w. U. d# c
# t+ [" i8 H& R# R    GPIO_InitStruct.Pin = GPIO_PIN_3;1 {: N# U5 {2 m' F% V+ O7 r
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;& j1 f8 o. _. k; U6 t7 [
    GPIO_InitStruct.Pull = GPIO_NOPULL;
7 K& q5 r: m8 d, j3 i7 ~    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
# ?/ A( B$ l9 o0 p0 o    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
3 E$ R" W4 N3 M% ?: E; o' p    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);) |: c( h! V9 I8 \  y

6 k: i) l. _2 V  U    /* Peripheral DMA init*/
2 s0 E$ e8 h- m; G$ F& c  
/ J$ @& p: L7 A, A  J2 {8 B    hdma_usart2_rx.Instance = DMA1_Channel5;) P# W- }- J' l2 x* L
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;0 A- l  P7 O* u/ |0 C
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
7 `& n$ t8 ~) H( L7 L% B* E: M8 W    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
) U9 H/ H, s5 J9 r% F' h7 r    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
! b" I+ W$ [  n' X8 H9 x3 F4 J    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
8 U* s* U9 J* n& d8 o, Y' G    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
) U5 }8 h7 Q5 p2 T9 J) W+ t! ~    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
* T1 \9 A" S) F4 A3 l" k; m    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;! O5 S/ l6 C+ `% V% T8 s
    HAL_DMA_Init(&hdma_usart2_rx);
" B, y1 w* v6 c6 j' t# y
4 ~) T, V+ G1 k3 O6 T    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
, b& U* q" e- d) J/ l  q! U2 M! |% J2 A4 s/ a; N
    hdma_usart2_tx.Instance = DMA1_Channel4;
# n- G0 k; ]- h    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;7 g7 I% G5 F( N- M- u+ L! f7 @
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;$ j, g, p+ h# c( P, t8 P3 y
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
, E$ R. T5 g/ E# J, q& w    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
8 ^/ G$ @% Q5 w: d    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;8 M# }$ Q+ W, k4 \( q* R
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
) y7 Q0 m) ?- z' `    hdma_usart2_tx.Init.Mode = DMA_NORMAL;3 ]' n. M/ f- ~% q- ^, M6 U9 O
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;7 k& K  H; B' h0 a3 m) V
    HAL_DMA_Init(&hdma_usart2_tx);& P! i! x& Y' z. `2 K

1 Y0 s& ^: h, }: y/ P    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);) j3 y! ?2 l" t4 A$ s

- k, {- {% x# F$ H3 O9 @; W6 x  }, ~4 Z' V3 _& T, h0 j0 P
}
3 X- x5 o' d( T1 `  [: T) d7 d5 t$ T1 f6 z# Z5 ]2 O5 B( W
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
  R, [8 p- l' c. z% y{
3 ?% e( Z; n6 Y/ j  c( X: u
; M, v$ j8 Y/ D5 G  @1 S  if(huart->Instance==USART2)
" i% k0 T7 d. Y1 l: w  {6 D1 c9 r5 K: U  b! R
    /* Peripheral clock disable *// a& V- r* ^" K9 L; Q/ D; P/ [" M  q9 B
    __USART2_CLK_DISABLE();
* n, o; X8 {0 E  1 C5 z5 r. ^: [; C2 {! ~  S
    /**USART2 GPIO Configuration   
7 j5 }! e, x3 ?    PA2     ------> USART2_TX& |* x0 ^5 y$ G4 T; f
    PA3     ------> USART2_RX
6 Y) U+ |2 w1 R, h* D    */5 a8 w7 f* {. `, p! G
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
# Q% z/ x, E# L! q, t' [) u
4 J9 {, N4 s- C" D& B6 ^8 i3 ?    /* Peripheral DMA DeInit*/
) W  j4 l5 H/ t0 r; J/ S! k0 G* q    HAL_DMA_DeInit(huart->hdmarx);
/ h! Q6 H+ j# T    HAL_DMA_DeInit(huart->hdmatx);# T! F0 g9 V% Q# k8 q. k. q7 w
  }
! n! [: ^2 T% F1 @' G' e3 l}  i' n. T4 |$ l
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------( ~) L  V4 X% ]2 f. i6 }
mpu6050.c
2 f/ r4 o( z# d6 Z7 o% c#include "stm32l0xx_hal.h"
7 `5 v& V% t3 C2 U9 l, [# l#include "MPU6050.h"8 M& D4 M8 R, ^' \1 c

4 c1 l5 x8 v  z  m* ]# E) ^9 o8 i//各坐标轴上静止偏差(重力,角速度)
- s7 y+ }# }+ G# yint16_t offsetAccelX = -195;
! M. O1 i1 s7 l$ F' w7 ?int16_t offsetAccelY = 560;
" a% Q2 `  A) v& I6 I( i1 n( Qint16_t offsetAccelZ = -169;8 v3 J  w2 @1 |( l, y; q

: o# {8 y( _; o7 _" @; s4 nint16_t offsetGyroX = 12;' @* L/ N+ F; O7 p/ H# J" o
int16_t offsetGyroY = 33;2 O1 G$ S5 N0 r2 i% g
int16_t offsetGyroZ = 4;, H' ?: \) m/ V( t
. t! O. K2 Y4 ~
extern I2C_HandleTypeDef hi2cx;
' |9 v6 v$ q: k' W9 f) D6 _/ K) T0 c2 J0 k7 p, @- L
//**************************************
" _+ H  v, q  ~% L& l/ C" n  J//向I2C设备写入一个字节数据. m7 z- K' g; H
//**************************************/ g, ?  P+ V, U  |/ {' c- T; _
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
5 h3 _! T7 f0 {% ]8 e$ I{  \5 v3 R/ ?7 w
    uint8_t rxData[2] = {REG_Address,REG_data};
8 _! @& `% j# F7 ~- e1 H  u: ?    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)4 u6 ?3 a4 d8 o' _
    {" J% g! \; I' ]- l4 |
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
2 w/ X  g  i% v        {}
/ r* W4 f+ b" V$ g7 ]' D4 l3 O0 ]    }
" r/ X+ F8 c0 w0 H* t1 ^# Z}6 W* V* [% b! z: }
//**************************************5 f, n1 m* Z. `0 \/ Q7 L( E0 y1 _
//从I2C设备读取一个字节数据/ j5 h- q- O; U& L+ t$ q3 o  m
//**************************************, I/ r2 X3 f# w* s2 r; L
uint8_t Single_ReadI2C(uint8_t REG_Address), Q4 {0 B5 r! \) P; l
{
" N1 ~# S- Y2 @    uint8_t REG_data;
4 y- Z3 U% \, e$ x8 R0 i, p9 R    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)  g( V3 O+ D2 R8 Z% h. T+ M
    {& ?# G2 k, s; X3 @7 @- |
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)# \1 \% u9 y" `! M; d& R* K
        {}  t6 N9 \5 P, b$ s
    }
$ a& L, a( `& C' q8 Q& A% d5 u) S   
+ h1 N% h% w; w5 N$ g2 ^; o  k0 R    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
1 D7 s) ?0 m! B' \3 l( B, X    {
  U. i6 P2 L+ _        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)5 |0 _. Z: k1 O! U
        {}0 b: `' v0 r0 B6 b) @) }( w& U1 g
    }2 u8 R- t; G/ E/ r0 t2 n
    return REG_data;
* N; j# w9 }+ m+ P5 Z! Z, N9 l6 c}
4 }$ ?+ L$ Z4 J, {* N//**************************************
" D% o. E! l% l  J) T: C//初始化MPU6050
) r- f  k+ D9 w" ?0 {9 U1 I//**************************************
! @, @1 \# j$ Z/ Z) x" hvoid InitMPU6050()' P1 _' l7 Y" X6 J8 U. p
{
; s$ l1 S: i: e! S    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
! ?* x$ Q1 \1 K4 ]5 E5 C* h; ?/ m1 e# J2 B2 }
    Single_WriteI2C(SMPLRT_DIV, 0x07);1 A1 L1 F" G* I( }( @

, \3 z' m: O- F# f7 O8 ^2 j    Single_WriteI2C(CONFIG, 0x06);
% J" U+ x. A- P- q' Q) ?7 N
1 {) ^! k! k3 o- e) d+ p% K    Single_WriteI2C(GYRO_CONFIG, 0x18);
- ~& b% U/ d& [7 b; G1 k' g6 c/ }& T( k9 W8 G
    Single_WriteI2C(ACCEL_CONFIG, 0x01);3 s  J$ u" O! T$ M" P% \, i9 `
}. C; a3 _% d8 ~. |0 c" b; ]- k
//**************************************' I/ k" g& X' [4 D9 |( g
//合成数据3 }+ [) V  ?/ H5 N' Z9 j3 }
//**************************************# ]4 X% ?7 X5 K+ b
int16_t GetMPUOutValue(uint8_t REG_Address)
3 ~2 _  V9 F% ]# a" m8 q3 T$ o( {  W{
8 H% `/ u3 M7 t  W) q1 {( u( O    int16_t result;% E- z, l) t/ y% z
    uint8_t H,L;. G8 j2 X6 ~- Q
    H=Single_ReadI2C(REG_Address);! P# [$ C5 q- U6 h- ^$ x9 }* i6 o
    L=Single_ReadI2C(REG_Address+1);
5 Q$ ^9 p  n" R- E: ?8 P    result = (H<<8)+L;
" F+ s/ f* u, U6 ]. @# u  S+ w' Y    return result;   //合成数据
6 _) n0 Z! u; i' A}
1 j* Z: \9 w2 z! p8 t! N2 s0 _! [! E8 S, n! a
//**************************************
: s, M  |4 R- e- {//取某一轴上的加速度数据
& @4 f* T- [5 M1 ?% d//**************************************9 g6 F2 ]- g' l$ |* W$ E( v
int16_t GetAccelValue(char axis)! G1 Z/ H/ g7 N' }+ z
{
' u3 c1 ?+ f% `! M- u8 R1 V    int16_t result = 0;4 c) E/ l# e) s/ W4 o0 B% V
    switch(axis)
5 d7 V5 k3 S9 {6 a" l    {
3 L4 N: R5 n, [* [        case 'x':! d# H5 U- {9 y! q; O7 `
        case 'X':; T# r4 Y2 C9 H
        {8 h$ {, [" F4 a* i# i
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
2 k) Q0 `& B1 t0 {2 V7 O9 r        }* K5 Y/ a4 Y- a
        break;, c* ~9 |  r: L9 T& x4 a
        case 'y':5 y" V9 G3 C  L
        case 'Y':
* ]' j# l7 w3 }; l+ `        {
2 U+ J6 |# p7 [- k1 q) t" R5 d            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
' X' i3 U$ l; [8 J; s6 R" D( m        }. e- x/ a4 y- K* W: _
        break;
" M2 p0 L  h$ Q        case 'z':
# ^- K9 [: i- X% u% X/ h( Z/ G5 D        case 'Z':
4 I& W' ~2 ?, P! A# D# E9 x        {6 q7 v; r" O& U
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
" D( D! ]5 O$ i1 l* I2 ^6 I  N        }
, i) h* M0 O/ c( I        break;( G, K7 s& }$ {
    }4 ^  C6 l2 R. ]* \0 F
    return result;
7 G9 a5 Q# c0 u. H& J9 ^}
5 f  A/ ]. C. B4 V, a; E, ^  v
8 G; e! Q2 L! D) c  q//**************************************
1 ]; _% h* ]" E3 c//取某一轴上的角速度数据/ l0 n+ ^7 c6 r, D# b+ D
//**************************************2 O4 ^4 U5 m4 g5 q3 H, o
int16_t GetGyroValue(char axis)+ }$ E- j6 `2 s: ?; D* B0 S
{
0 F3 h- X# N9 S6 ~    int16_t result = 0;
; e0 p8 j+ {  G, K2 q: N    switch(axis)
+ f. R7 R/ U6 @' `: O$ R    {$ B/ H# I, i9 a5 Q/ M
        case 'x':
9 b2 B' D# d+ S        case 'X':
9 ]& F( U  c7 P        {9 [% H1 s" t6 `  n: f2 t4 g) h
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
( u3 @5 I5 I; W* H        }
% }" |6 x- g' l4 n        break;
- X( X9 H% @7 ^: _1 N) N; ~        case 'y':
# q0 ^- [3 B4 l0 f& H$ h. H        case 'Y':
5 f  L8 t7 B9 Y- a% q        {
, O0 f+ D6 _+ n; `* `* D/ x            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;0 @! i+ g6 V3 j8 H# o% N! n3 f
        }
5 }; w7 T, ^/ R( f" x$ C        break;
; @1 [2 _5 P3 Z! z( g  O7 h/ a        case 'z':
; M- S8 P0 l+ C9 U/ C2 e        case 'Z':
" P1 ~, h& _+ s$ b8 a) s        {& B( I9 r' Z) m# z6 B
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
2 u+ u. q4 @2 R0 @8 B/ e        }, E  J4 Z4 o: D- ]- E
        break;; L" w# I3 ]2 ~: a
    }
2 Y; o. v. R# c8 ^1 E    return result;
2 @5 O/ h1 d( c: P+ `2 |1 F1 H}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)6 z! E- |! A2 P. ^6 u. F7 C  I" }9 ^
{4 H( ~0 ?# R/ P% ?

8 F2 V3 s2 h4 M* H/ e9 V# s/ K  /* USER CODE BEGIN 1 */
3 Q8 J) G- |% X8 b. D6 g5 D' Q) o4 I) m
  /* USER CODE END 1 */
7 `, U. b4 z+ z8 v3 l3 [$ x1 T* C) b8 o5 Y6 C2 Q6 M
  /* MCU Configuration----------------------------------------------------------*/6 s0 D5 R+ R3 z% y' T4 O. Q: S5 f1 i' r
! W6 e. k$ w8 B
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+ @& B) P$ z4 X# r3 N  HAL_Init();* m! @; d! B/ p% a, o( [# L0 _

! f/ U. ?' M) _  /* Configure the system clock */
1 x3 P$ K- h' M  SystemClock_Config();
5 Q3 M3 d4 v$ c5 i8 e, k7 a# x" \* L) \8 L' l$ Y9 W% P5 ^
  /* System interrupt init*/. O( {5 h1 Y; I* ~0 @1 L
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);' w6 |2 }% {0 H% d+ Z& Z% d, Y

4 K' k, [/ q) D+ w) x3 J  /* Initialize all configured peripherals */8 o) \& c: x  K/ @
  MX_GPIO_Init();' E* E1 |! f3 ?8 A
  MX_DMA_Init();3 K0 W) }6 J/ r0 A
    MX_I2C1_Init();3 O- J  ?' z; [. Z8 }( ]% C; e- u
    MX_TIM2_Init();
; z  M3 L/ b7 s7 F! j7 {  MX_USART2_UART_Init();% @$ L% k4 {' q: n7 L! k: P
    InitMPU6050();+ t+ e2 r$ Q" ?. C& n: m+ T& ?9 |
; ?( W5 d& Z. A- s, Q; v, _- O2 t
  /* USER CODE BEGIN 2 */) m% c, F5 ]# z3 M# w4 f7 o
    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);& F9 g8 U, B$ F, }, q- y6 A% U
    HAL_TIM_Base_Start_IT(&htim2);
0 `3 Y6 h  m: T9 {' |  /* USER CODE END 2 */
" `) t# p& k) y" i9 Y: J
7 }1 z2 c( P: O5 l; A  /* USER CODE BEGIN 3 */) \$ i* A* X' B8 |4 i* b( d4 M
  /* Infinite loop */' M4 z* L3 f( S  x7 X0 j1 V
  while (1)
1 i! ]' Y- E; [% I  {
+ w0 P+ w9 ]4 w        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);, y6 k% x5 x& n* |) B, `, D
        VisualScopeAngleOutput();. U8 e8 I: }1 ~. H& Z8 i6 @9 P
        HAL_Delay(100);; r/ d, F5 I3 A5 o% I3 k) V
  }+ R  o% \5 q6 ~
  /* USER CODE END 3 */  o3 R& g* A, u, d; }/ f3 S

1 }8 J4 L+ W) i0 s7 e  L+ i; i: x) c}  _2 E( D. m8 F/ V  d( P5 r

9 s( W4 N; @# q# t! d  _2 Y/** System Clock Configuration. t4 ?: U, b, d! V# O% q
*/) Y1 A( {  O+ V' ~3 B0 M; ?
void SystemClock_Config(void)* A, L8 X2 ^/ Z% R8 a
{
7 p7 M& A& P+ N# S! n6 s+ A$ B$ A9 |% J8 W9 i. r  ~4 `0 q
  RCC_ClkInitTypeDef RCC_ClkInitStruct;7 Q+ R# B( `0 c; L$ Z+ p0 M# \- J) Z5 n
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
, |4 U$ O  {% Q  RCC_OscInitTypeDef RCC_OscInitStruct;- J/ f' _& R) v+ Z& X% @

, T" d# m, I) D6 i5 N  __PWR_CLK_ENABLE();8 G9 o) p+ y4 D& w# k) r
$ z! H: |. s0 o
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
9 u. I. i+ N7 E5 g1 G8 S' I) P- H" [
" @, K; @/ x) I& I6 j9 u- u, t  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;( M$ ~0 Q% U4 s+ M! e+ N5 Q
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;, c) V/ y" F8 s" ]8 ^/ H
  RCC_OscInitStruct.HSICalibrationValue = 16;
  E8 o  _' d. P6 ?  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
% l5 h# s8 Z2 y; x# a+ |  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
7 o0 T! }7 M0 f4 G+ M" Q! t  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
! O. d4 `9 A7 H0 `, R  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
. b' A1 [7 q* D: L" X0 b  HAL_RCC_OscConfig(&RCC_OscInitStruct);
: U5 S+ b# E) H% S: L; P# |1 K2 G+ C! Z+ o( S
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
3 X0 D9 u3 |3 E. U/ Y5 G, D* K8 {  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
) d+ v$ v8 }! F/ i) b) T6 F  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
/ h' I# I/ ]6 P$ T& v0 p  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
# ?  s; l4 y5 p# r/ g6 a3 h( L" ^6 |  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
8 I* S, `; L, N  n8 \  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
" L+ c" m0 M$ @% y# D$ A. \  [$ [! \. b2 K/ S5 D
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;4 z# {% G/ B7 j- n
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
9 z1 w  T. P" w  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);0 r: z: }  E# v5 H, [- @
% P! [/ @8 k+ h1 ]) i! e
  __SYSCFG_CLK_ENABLE();5 _" V% \/ d* J' b
0 z# l: [0 f* ?8 ]/ P# n
}
9 m8 a, R4 ^% _: e! b( n
. K. x/ M1 a8 W) o! `/* USER CODE BEGIN 4 */
- c8 k4 Z: d: Svoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
# E( e3 P$ b0 C* g{+ A+ T0 l* T2 I* I8 F6 H4 s
    if(huart->Instance == USART2)
$ w$ C0 \$ |, ?    {
# f* ?( ?2 Y0 J8 p: k/ ?( {, e+ D% X        memcpy(txBuffer,rxBuffer,RXSIZE);
; P- O6 @% _4 E& O- X        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
4 l8 ?% e8 x) x, \" q8 u        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
$ B. N4 M& E2 q  N( a) f& {8 N+ z    }* H9 Y, O. g  n% Y" n) G- h
}7 U% Y8 v$ ^0 E# ], [0 I" E
  c- R1 \, v& g. \- V9 N/ ^/ l
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
. W# a7 S: J) Y9 E2 f  N{. X6 `9 W; U) k. D
   
4 e2 Q& Y6 c5 _* o}
$ b( K( b( J. I( w- l
" q* m. E% c$ q, x1 \% wvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
3 U6 h1 @$ a, n3 M  }+ B  d{" B  L+ K2 [1 [$ i* |# o! @# m
    int32_t GyroValue;
# i# Q' L: b* v* r# Q4 r% [0 l6 A   
. i; l, s8 N! m* G1 U    Calc_AngleAccel();
+ X, l; Z' w3 N; n0 A; y. {    GyroValue = Calc_AngleGyro();
4 z- Y$ l) m1 z5 a- I    ComplementFilter(GyroValue);, T3 O/ @% q  e% J7 {. a! o
}
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
. b; c7 x: O% v* s楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

. ~4 I  ^; T& S; L使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00  b1 j, U2 D3 X9 `5 R9 N
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

+ k3 l% v5 p) A  M* z; z如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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$ j9 W. i6 l; u! v8 B9 N* A# T
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

" T" a" L( Y3 [, g好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?/ }/ V  B* |2 J2 V2 c3 `; |
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:086 \# W/ n6 h. d, c# I# w& P
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
& P; j9 r6 C' J  c( E5 t请问应该注意什么地 ...
" T& `+ [8 {9 @2 X0 P# E+ f
我使用是没有问题的呀。

所属标签

相似技术帖

官网相关资源

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