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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
6 A6 A9 u, f/ t  L$ }; N9 |-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
: _: w3 i, j9 s- zmain.c$ N5 K! Q' K  |
#include "stm32l0xx_hal.h"3 A' H, e/ z8 z
#include "dma.h"
% b7 j/ R8 X# x: H, }' F6 \#include "i2c.h"& C- v8 ?( h5 j6 G
#include "tim.h"/ ~  n% d. n8 `: ?2 w+ G
#include "usart.h"" m& `5 y" a1 i3 X, |1 r; i! [
#include "gpio.h"8 ]& z* F' d$ D4 Z5 f5 S7 f* r0 l6 R; y
#include "mpu6050.h"
: ^) {( D% K0 ?- U#include "visualscope.h"9 {7 Y' i* H0 k& J! W% v
! L8 _% p* z6 D/ x' T* U2 c
#include <string.h>
  _7 v. |: y( c9 V$ E9 }#include <math.h>" \9 C" y/ D8 q8 p9 {
! ^: X! ]( p* L4 A4 `, F
/* Private variables ---------------------------------------------------------*/4 D( Z7 a! S! d. ^6 `
#define RXSIZE 8+ i' r* J  U0 n5 e) E
#define TXSIZE 8) N! a/ |7 `5 h+ s
uint8_t rxBuffer[RXSIZE];( v* i& f$ l6 l' U& f4 ]& |$ h
uint8_t txBuffer[TXSIZE];4 z! [7 y3 B2 D4 }3 r) T
* U- B& p, B2 M% R1 G% n
float Angle_accel = 0;# h" _6 H) v4 h6 U' Q( s, e; K' p8 o% m- R
float Angle_gyro = 0;4 X8 S) B8 j+ b( Z' o
float Angle_comp = 0;
" H  O7 j# B* _- E" B/ C7 vuint8_t outAngleData[10];7 F$ B( {% U2 A7 P
/* USER CODE BEGIN 0 */9 X9 N3 m$ W, u2 N
8 Z& \1 {# c8 L2 @
/*---------------------------------------------------------------------------------------------------------*/6 Z+ A* g2 r! Z6 v% K4 o
/*  重力加速度算出的角度                                                                                       */
4 e- r3 T; s8 I/*---------------------------------------------------------------------------------------------------------*/" m1 ~0 [, ]0 Q( h- Z7 ~4 M
int32_t Calc_AngleAccel()3 s+ _/ \8 ~0 G! _) @6 o2 {: n9 z
{
2 j  f* A5 v  d    int32_t value = 0;
  e" p; D4 B9 }  [6 Q" {2 @    3 X. V% V6 u- F: P6 E" s$ \
    value = GetAccelValue('x');2 D9 p+ q/ w; v# w3 P" Q* _' a1 m0 ~
    if(value > 16384)
* Z( f/ r4 [4 H2 V7 Y        Angle_accel = -(asin(1) * 180 / 3.1415296);9 N+ N% [0 S, L4 c7 _
    else
  P2 K9 U9 t5 ?: L# g/ }        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);7 O$ `8 H: L, w. u
   
5 \, Z! u/ v7 y2 Z& N    return value;
8 a& @, W& t, P+ P% t" s4 ]" k% W}# O: Z1 O0 x: J8 d
- u8 e9 }/ W, X1 y
/*---------------------------------------------------------------------------------------------------------*/
; |" I8 X; \8 R; |+ \1 }+ Z/*   角速度算出来的角度(积分)                                                                                     */
) E3 q, g6 L3 }! N$ V7 P" }/*---------------------------------------------------------------------------------------------------------*/
+ a/ p  e; g7 ]int32_t Calc_AngleGyro()
' s( v% J3 h. c6 N5 Y$ l$ o+ N+ V{
' ^) m  o2 C# S+ Y. v    int32_t value = 0;$ C( k9 C4 m  Z! a' b

: e6 D& X: r9 N! ~, I& \1 N' d    value = GetGyroValue('y');
2 ~! j8 _) a) Z    Angle_gyro += (value / 16.384 * 0.01);
; Z' p+ k. Z1 k! e8 ^% H    - D! s, `( F# t3 s! C
    return value;
% D8 j( ]. k: l+ |# T}' \3 K- S+ K( S# h
+ V+ v1 e, {5 m% T
/*---------------------------------------------------------------------------------------------------------*/
" _# i) }2 }6 v9 T% {, v. q# [/*   互补滤波求角度                                                                                     */
) O# M9 ]  ?$ _/ m$ L% g) b1 |/*---------------------------------------------------------------------------------------------------------*/
% R: V$ m% V; P* ?$ [float ComplementFilter(int32_t simpleGyro)
# }# h6 D( I% P4 x{7 G/ d4 S) B7 B& R  K3 b
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;9 ]' [0 u: |2 H$ ?  Y+ d
   
/ {. S% c" B* W* V7 c1 C/ M- H    return Angle_comp;) F3 f# T( A0 R7 x3 D$ K5 O
}# h8 t2 l  j. `6 r& ?. f% F

1 Z1 W- C, i8 p2 X/*---------------------------------------------------------------------------------------------------------*/
, F* P& ?  B. @/*   输出角度至上位机                                                                                     */
/ c/ p3 I# q3 Y2 E/ S. x/*---------------------------------------------------------------------------------------------------------*/' t) o" |: ^3 n0 V/ q/ @; V
void VisualScopeAngleOutput()$ L) D! `' j$ j  \
{
. J0 {$ c* A) \    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;( E0 @, R. `, A( c1 q
    uint16_t crcValue;
, B( `) Y# N4 O2 v    # n" H$ @1 W9 }' a
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);( v4 |. U1 V4 R2 N
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);; f( e" ]9 n( ]: |4 Z6 u
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
) L* P6 N  D: s" D7 x! d( J: h   
5 x- d9 B0 X0 ~7 O/ I- o) n    outAngleData[0] = AngleValue_Accel & 0xFF;0 k& X& |( f3 j! q0 k1 w
    outAngleData[1] = AngleValue_Accel >> 8;
9 ~& p, S- l# r& r    outAngleData[2] = AngleValue_Gyro & 0xFF;
$ r$ M5 z- V4 c2 A4 {    outAngleData[3] = AngleValue_Gyro >> 8;
* u  C: D" I8 W; v5 y    outAngleData[4] = AngleValue_Comp & 0xFF;6 c, T% k* ^% k+ M( ^
    outAngleData[5] = AngleValue_Comp >> 8;
& w  L" r+ J' L) V7 `- G8 h; a    //计算CRC( V" K4 O: }% c# q) s
    crcValue =  CRC_CHECK(outAngleData,8);
0 F3 V8 U- G, x; Z    outAngleData[8] = crcValue & 0xFF;+ ?. }8 e0 Q% @$ Z  R+ e; F$ f
    outAngleData[9] = crcValue >> 8;9 s- h! |) L0 m" M8 x* N1 t
    //发送至上位机7 v/ L6 Y& C5 ~) t3 J( t* c
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
' G  d+ Q/ C/ M6 r1 v# T}
6 n$ q& V* {% l8 ^- ?/* USER CODE END 0 */9 S# U5 Q9 z( F+ ^
) ~2 t( {5 Y4 D1 R& N& |- H% q
/* Private function prototypes -----------------------------------------------*/# q: [0 g2 R" A0 R
void SystemClock_Config(void);
3 S" Y  e; C& x( F/ ]$ i& S& X  Z* E; E- D

7 t  d8 W* D% t+ G% _( N7 L% ^硬件连接图:
$ ~2 g% K3 Z2 [4 b$ r; r3 Q& U4 t 1.jpg
: V4 Z; Y+ ^5 w4 u' w" S! |波形图:6 E" J' c) f; z# v' E& G
2.jpg
1 o* ?3 k9 q: l3 z! h- x最后加一个视频:3 ?' \" c% f4 e  i
STM32L053 演示/ z* T" A6 j3 E" D' {0 o$ R5 w
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C! X. Z# e4 z$ G- H+ d7 b# r4 n! V- s
#include "i2c.h"
/ u! e; V- q/ q* @
5 E- C! R+ J3 K# ~% k#include "gpio.h"2 W6 s. X% g3 z7 L1 U

$ L4 R2 E/ j3 S. k9 g/* USER CODE BEGIN 0 */
% c0 E. L8 V3 T, C% B/ m3 r, e* @! m. o0 Z/ E
/* USER CODE END 0 */9 f/ ~- S7 o- ]. ?" X
' s) B; b0 S; e4 U5 d
I2C_HandleTypeDef hi2cx;
. B3 P1 ~  m1 i9 q0 N4 f) ]- Q% M) S: L/ {) r) L; Z
/* I2C1 init function */* [# Z0 |# _6 |! \4 ]$ ~4 Z
void MX_I2C1_Init(void)
+ _3 _& X+ _- I+ u% n{# J4 u0 I- a7 ^- E  a) A8 H

7 I' k% i  j* S  t4 u/ Z8 Z3 L  hi2cx.Instance = I2C1;
5 l0 W2 ~: F- P2 X0 e. s  hi2cx.Init.Timing = 0x20D22930;
+ R# z$ P+ n' ?& ^* @  hi2cx.Init.OwnAddress1 = 0;3 }8 W2 S/ N* L
  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
$ f) M) o5 V, I; [  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;, }) ?8 I, ~( C8 f1 O
  hi2cx.Init.OwnAddress2 = 0;
0 u. K. i6 K  u% ]9 p  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;/ h! W! v$ m' C" F( |. a5 H
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
: j. H5 q) E5 \+ q$ f9 [* x  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
6 R/ m1 r2 W* j  R' V& S0 V  HAL_I2C_Init(&hi2cx);( v; n* r8 `, l5 y/ M& l! d

8 b) G1 G- c! W% w    /**Configure Analogue filter! ?  c& A6 g3 F7 ?& G4 N! N
    */' X- p( K/ `  e  _+ M! z6 d
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);  s) x  ?7 @8 N4 E
( ~$ m# y2 h0 p& c# P. Z
}  b7 q( v% k0 U2 i9 M, f7 v
$ V3 h- i/ T' {5 J
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)5 N/ S5 @" q6 q* |$ L
{% R2 q% u7 `) }7 g- Q+ @4 y# J

3 M1 [- T: F- Z. S  GPIO_InitTypeDef GPIO_InitStruct;5 T, l5 q" K9 y3 ]1 Q1 z
  if(hi2c->Instance==I2C1)* E- H; B. Q6 F2 H7 a1 b; B
  {
# V+ `( I" v$ D( [4 S    /* Peripheral clock enable */; g) e$ T) a0 a# O& G1 T
    __I2C1_CLK_ENABLE();
9 }5 ]$ {5 ~+ V0 ^/ e9 [  % L5 m+ j3 N( Z" ]
    /**I2C1 GPIO Configuration   4 {- y7 m9 \  l% ^: y
    PB6     ------> I2C1_SCL
* i3 j6 L9 b5 Z: q8 e5 x    PB7     ------> I2C1_SDA( |7 j; P6 c) S, K* A5 w
    */
# \! Z/ t, R7 p    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
4 e/ u+ c$ O4 \2 R    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
" [. L8 l- Y: v9 e: c7 E4 a    GPIO_InitStruct.Pull = GPIO_NOPULL;
9 S; f0 C; [2 X8 l0 Q3 S    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;+ f, r4 s- l" p, L
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;) r  M" R( r  b7 d$ U! \
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
5 g7 \* \, Y( V$ ?4 c5 i/ b- S% x1 v: T5 B: H. g
  }
5 V/ B8 k) m" X' U5 f- b}: K9 l7 ^! Y/ G3 H

  ]) Z7 l, R* K& uvoid HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
3 }# M1 ]6 l5 o+ c7 z* Q{
1 Z: n8 I* c) {6 ]% y9 R# K8 V  M
- x' U$ j" r; O8 f9 Y  if(hi2c->Instance==I2C1)
! l- O( ^3 R1 D: A2 ^) a, U+ s  {0 d$ I5 t. D- b+ T
    /* Peripheral clock disable */6 @5 u  v# L1 s1 |1 I
    __I2C1_CLK_DISABLE();' H2 K5 f7 N5 F& }5 T
  
% O: B: L5 V  j$ x) R% G    /**I2C1 GPIO Configuration   
2 D% ~* v6 ?3 H: x# f    PB6     ------> I2C1_SCL
" M* d2 F0 w. v9 R% K$ x    PB7     ------> I2C1_SDA
  `/ V* d+ r) V7 J    */; `" R- ~, R( g, f: @
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
& y: f$ |$ E1 u4 t" ]% T9 ~8 p6 z. I8 ]  \
  }8 ~  n9 {/ K/ o, l( Z
}; u7 }9 n( w- r5 p  D3 C) P: M
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------6 ^9 |% }* K8 }, t0 _: @. S
usart.c$ \9 z* ^8 a9 u' U8 u7 H: F
#include "usart.h"% Q5 X% P& R+ a
0 N7 [5 }+ ?( G. g4 Y
#include "gpio.h"1 ]( B$ g& h3 u- ^+ O
#include "dma.h"
5 ?# \+ o2 q6 o6 q$ S
& z9 W2 S* k& ^7 @$ `* Q; r3 S/* USER CODE BEGIN 0 */
1 ]# q) P7 U7 c0 v0 @6 Z% \+ s5 _9 X4 ^4 U9 f4 V, {. S5 k5 r
/* USER CODE END 0 */
0 G3 y! ]1 I3 T* }- z! t+ V- E1 E7 P. N; x. J
UART_HandleTypeDef huart2;
" n& h4 ]8 M3 sDMA_HandleTypeDef hdma_usart2_rx;7 ?9 B* m& r' R3 }* o6 @
DMA_HandleTypeDef hdma_usart2_tx;) Y2 e. F$ A& Q  @6 T1 |" r
7 P& V# e( d. s6 b2 E2 G9 s0 W* h
/* USART2 init function */
8 E* H; N7 d! ?3 z/ e2 A& \) @3 ?- @+ L. A% U
void MX_USART2_UART_Init(void)
+ F( k( U0 n% P8 V{  A1 @" W1 I# _7 ^4 |

7 e/ w( A; M6 ~' m3 e  huart2.Instance = USART2;$ ?+ c+ ]3 @: p/ z
  huart2.Init.BaudRate = 9600;
; w; M1 R  j3 C+ A3 G  huart2.Init.WordLength = UART_WORDLENGTH_8B;
$ a9 i7 O' C$ p" M( C( f1 x9 _; u+ h  huart2.Init.StopBits = UART_STOPBITS_1;) q) Z9 P8 y4 U2 A1 K4 [
  huart2.Init.Parity = UART_PARITY_NONE;, P6 w  m# p2 U+ J
  huart2.Init.Mode = UART_MODE_TX_RX;
. U; K, A) `0 @6 b. L, g  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;* U0 i7 U" a; F6 F9 {( q2 y, ?
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;) Q& @% G4 W0 c+ {
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;8 W. h6 v8 L6 j- j/ K- k
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- j1 P" M- t) {( G  HAL_UART_Init(&huart2);
8 Q" O4 M% ]+ Y  d" H' a  U
$ Z0 e' [, C2 x  y$ u}
# c, E4 W- e  W. v& L
. t) b) S* G$ I, }# E7 kvoid HAL_UART_MspInit(UART_HandleTypeDef* huart)
& E& N! k; R7 P/ f{
6 H5 m' P$ f6 B/ Y& n8 t1 B$ H* M' e8 d
  GPIO_InitTypeDef GPIO_InitStruct;
+ ?; S9 |- ~+ S. J4 i  if(huart->Instance==USART2)
& b; @, ]1 Z4 ~' l- @- D  {& T2 Y0 N: R# U0 v5 N# g5 c
    /* Peripheral clock enable */; |7 {; [  D) e+ l  E
    __USART2_CLK_ENABLE();
- O$ j* h" ?# T* D2 j4 f  , [; t$ a3 u! v$ U( J! x
    /**USART2 GPIO Configuration   0 q  _. \/ N2 d3 m, s6 c2 @# {7 S( h
    PA2     ------> USART2_TX
. e7 Y3 I  O5 E4 v% h4 c% Y! b    PA3     ------> USART2_RX
6 ^9 p2 e! x8 Q& ?* f8 x2 B    */
# V6 x$ g) R, n% q) A3 |    GPIO_InitStruct.Pin = GPIO_PIN_2;* \; f7 R. w1 U  n: s
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;- l/ J; J, t" q1 j* |
    GPIO_InitStruct.Pull = GPIO_NOPULL;$ R& U8 V! I; ~3 R) _
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;6 Y6 S/ `9 y1 z( |" Y( [
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;! {4 S1 ?5 S) P
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  v) Q/ B4 l( @, Y) p
8 X6 R1 n4 ^9 _: v! w7 n    GPIO_InitStruct.Pin = GPIO_PIN_3;
9 _& U- A4 Z8 w4 O+ P    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;* U' f) v. m6 k, ]8 ~4 |
    GPIO_InitStruct.Pull = GPIO_NOPULL;  |/ I# V/ Q) j" Z! h
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;" M- g/ P2 }- m6 y7 n0 G+ v
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;% A) n7 ?/ Z/ m
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);. K/ s. P4 \' S* \8 [. Z
; J3 v7 c( q/ T  c4 K
    /* Peripheral DMA init*/6 p+ v; T( C  B4 b- R* \! d
  
, q2 x, ?  t, S: U$ a! o: M0 @    hdma_usart2_rx.Instance = DMA1_Channel5;
7 V5 k: y# G6 P8 ~0 j/ J    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
1 A' y/ f+ q7 j' K    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;6 V7 d( B; H& E, a* `% B
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;5 r# K, G. s; D0 _5 \( Z& q
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;8 g% I$ g+ Z" \$ S) t3 E+ G4 P: c
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
9 a% M8 C; K! b; v; K' w9 s( q    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;9 v+ q; @3 C: b# c
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;' o; _) E/ ^! M: l
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;, _& D3 a, H! e, q2 a
    HAL_DMA_Init(&hdma_usart2_rx);6 H% m4 {5 U4 h! o& E! ^
. b, b' ^! H* n% f' q5 u
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);& w; O# w! N( t/ y. a" u: @6 z3 W
- d8 d- a! _5 J6 O- K$ t8 }
    hdma_usart2_tx.Instance = DMA1_Channel4;  X, n8 f9 v6 L
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;) S  a" N- _0 t" F. x. k' ~
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
& m. c/ l$ c* l' Q* G3 p    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;; R. K5 F: F5 Y; `# \' J
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
' D) m- U: ^2 V. Y1 t/ ]    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
/ d. m# Q7 F+ |* g9 C    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- J# d1 ^# d) x# e' y; ^9 V
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;( ^% Q% B3 `- J
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
" w2 ?7 c/ N$ b0 h3 O* a; H    HAL_DMA_Init(&hdma_usart2_tx);
8 w/ ?% m+ b% \$ x2 s+ O% z! @% u; Z5 e/ A
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);" @- Y  v$ w$ s% g
$ u  d5 l8 m( X! }
  }( x0 v8 s/ t& q1 N. F# @+ x
}
3 C) `/ Z9 R3 \; }, l% I9 ?/ _* t7 t  v8 d! u5 y2 T
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)! h+ [: u  [+ q. f
{7 b  z4 _- e7 Y0 M  p. G) E5 b: l

3 V" \$ G1 h" ~. S( A  if(huart->Instance==USART2)
! W& j# `- q2 s5 E/ z+ Y- U! X  {) n4 u4 C3 M5 O. l+ b
    /* Peripheral clock disable */
# `! |4 s4 ~1 o9 I# n! E: h0 j    __USART2_CLK_DISABLE();
9 G) \, P4 ]. t' r  A5 C  , ^6 T5 e. G3 n1 G* c) J
    /**USART2 GPIO Configuration   ; n" B' z8 Q4 I
    PA2     ------> USART2_TX6 `  K1 [7 A& A: w$ Q
    PA3     ------> USART2_RX
3 S& a, Y3 B3 X6 K7 o; R3 F    */  ~  J1 E" W% g! r" e
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);9 j0 K# J4 ^. @5 h
/ o# l. m) c- ~: N
    /* Peripheral DMA DeInit*/
# E8 D0 H# b1 l) S% K    HAL_DMA_DeInit(huart->hdmarx);
5 W7 F% }+ C  G3 R    HAL_DMA_DeInit(huart->hdmatx);
. x" d  S- A/ u& J8 O  }
  U" R9 b0 Z+ p( D/ W7 q}
" c( M! I. o  X; ^------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------- J6 l* s0 f% d3 c
mpu6050.c4 j7 c0 X0 k$ b* O& F2 t! x
#include "stm32l0xx_hal.h"  ~6 G) z$ ~: ?
#include "MPU6050.h"
  n3 X0 M9 W3 T! t" j& ~( u# m! B) p1 R2 d* O* ?
//各坐标轴上静止偏差(重力,角速度)
% D, m; |6 r. q' M% o: K* D' C6 fint16_t offsetAccelX = -195;3 Y8 o/ D6 i( E1 A
int16_t offsetAccelY = 560;; b: ~0 l' }6 s4 I
int16_t offsetAccelZ = -169;7 ^6 y  o' \* A' F9 G

! j& u$ \/ Z3 Y* Jint16_t offsetGyroX = 12;
  S1 I. m" i/ I0 y6 I8 [int16_t offsetGyroY = 33;
# v0 t3 L) t4 k: I0 [int16_t offsetGyroZ = 4;
$ Y7 K# {; x' J% x* B0 S7 a2 u: T. @1 k% S; T
extern I2C_HandleTypeDef hi2cx;' X5 Y4 K2 G4 B- a8 c1 h
7 q( ^# T( Z% M% _, S6 Y& T
//**************************************
: B7 j3 Z' ]. {+ l* w% w8 n9 N4 G. q//向I2C设备写入一个字节数据7 X% H$ f: {; O$ D& `
//**************************************
% o( L  a" }: X+ y4 G+ x7 q1 [; Kvoid Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
+ h: u* a! E9 t6 D' b/ y{- E2 f6 h* y/ \
    uint8_t rxData[2] = {REG_Address,REG_data};
  L- S2 N+ \) r: U8 i0 u    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
0 A6 ~: J+ n0 {) t$ S    {* x  Z. a1 j- z0 z( y
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)1 N4 D; r' N7 _/ a; I: |6 Q* K
        {}6 z# g; g2 l, S& i, g
    }
$ Y: O% S+ P1 w; A# B/ F. K" G}
; Q2 S/ b+ D/ ]# V) P//**************************************4 c9 d. U/ T; L7 ^
//从I2C设备读取一个字节数据& j- G4 g+ D" ~* F7 G; [) Y, I
//**************************************, c4 X! ?' n$ M/ ~4 x  R$ L
uint8_t Single_ReadI2C(uint8_t REG_Address)9 U5 i) o' \2 j; S5 K' c/ u/ t( s
{" D. ?# p( V* B- v
    uint8_t REG_data;0 K  n' `* O0 M, Y/ [9 ^
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
* g) }+ ^3 m2 `2 V' R) R    {8 f5 |' Y& C. q1 h$ q4 Z
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
4 h( C1 j+ \' d4 y: g/ n        {}
, `) w* v5 b) ?; z- y) t    }
& i$ k6 a1 Q: p   $ i9 ^2 ]  N7 u
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)7 U2 W. D% d2 T) l
    {$ I% a& W  ]' F
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
8 t9 d# Y+ F  J* S& v" K6 Q        {}
$ ?0 c6 F% J1 U$ k    }
* \8 d- ]0 B* \! K) R    return REG_data;
! T9 A  t8 y6 F}2 Z  q3 O) w  g
//**************************************
1 M' I$ L1 l5 W, m- k% M//初始化MPU6050
; M( ?# J: s6 l) ]//**************************************" q$ ~9 }/ j4 E
void InitMPU6050()
: ?7 b$ L1 j9 A% F% g. v. e4 p# j; t{# e9 q3 ]5 d8 a" ~$ w$ R+ v
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
2 h) U" o3 T5 G$ d0 i
9 j$ ^8 O* {8 A    Single_WriteI2C(SMPLRT_DIV, 0x07);
- R5 z4 P  O0 Q, z( I' S" \/ R# ]1 h  o3 g
    Single_WriteI2C(CONFIG, 0x06);
; T4 B, ]$ z3 F& K0 M8 p- Q# F  V& i; v; {, ^; R
    Single_WriteI2C(GYRO_CONFIG, 0x18);
1 |  p$ o3 `' v0 _1 A+ A! j. @* s& J% m+ |; d- v) A
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
0 E4 W4 G5 x' K5 V* n6 `/ n- H}
. v. r) J2 t" U( E3 O0 l//**************************************3 b* x- h3 ?2 Z3 d
//合成数据0 @, F2 x/ D7 z
//**************************************# z0 |! V; F, J  ?, y3 I: Q$ w% S
int16_t GetMPUOutValue(uint8_t REG_Address), C# |# A: h. N2 k) F9 d
{
7 i* O8 I  @& r! L3 d6 H( g* X/ x- F    int16_t result;; d/ H' x4 K% r2 G
    uint8_t H,L;) O; x6 A: b$ Y3 M
    H=Single_ReadI2C(REG_Address);
7 {8 ?3 \* N! C* a" r0 V. U  i" s2 s0 M    L=Single_ReadI2C(REG_Address+1);) J  D5 s0 s4 Z+ _2 ~2 D* z
    result = (H<<8)+L;
! Z2 S* B+ O2 r3 G! ^    return result;   //合成数据& e8 L/ e9 V" @7 F: b5 T
}7 x2 k3 }; K5 a. r" T9 A7 {! {
! s7 d3 p8 {% {4 V& H
//**************************************; p+ I2 w% l7 a; N6 ~0 i
//取某一轴上的加速度数据: N0 G; e0 D. k3 q/ d# w& f
//**************************************% ?2 p- ^6 q4 ?% v6 p) l: c% K$ R
int16_t GetAccelValue(char axis)* p1 ~# ~+ A; N1 k5 t
{
# T3 i: |4 B/ g) z    int16_t result = 0;
' W4 i2 o% j7 f  m    switch(axis)
" ~0 o, U# `  f1 r7 R9 D+ Y    {
2 ~7 t3 w3 A" R        case 'x':7 C1 {9 L& Q; }+ i, x; u5 n2 t
        case 'X':5 A5 P0 X6 g" {9 C1 s0 x  X" w/ {
        {- m$ K* F; n0 ?$ _1 Q) ~
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;) ?+ R4 `+ l9 l' M' B
        }# T2 M  O" e5 s/ B
        break;& z5 T6 Y' L9 }  w6 a) Q' H/ _
        case 'y':
, Q- l1 k! V( ], o$ e        case 'Y':% z! h5 M/ H1 P. a1 G- O
        {  s- e, i# U+ o8 |3 Z* a9 O' l
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;* Z& g& @& Y* i6 Q. M
        }5 L! t6 K* H$ ]( @' ?
        break;
; m0 f0 }7 t+ {  n0 _3 T0 C        case 'z':
, a: i+ R8 S' D( g- D        case 'Z':% [; S$ M' W  f9 R9 f% M
        {/ k" n, f; K  q' Y) i
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;; |& q. t8 y. g2 V( W- P5 y
        }
& ?1 ]3 s7 C6 H1 C5 x& ~! B/ i        break;; Y* K. m" a+ A+ j4 f
    }$ ]4 B4 t( }5 A6 F7 d- ]
    return result;
) q* k1 B3 `  `6 b7 A) _5 B}
: K: ]% _) j5 |- b. G% z
# |3 P, I; j3 j! w' P% B$ ]) f+ X//**************************************
, e" \$ N1 x+ G* D( F0 I$ V: u//取某一轴上的角速度数据! @# t& y* c" ?; v
//**************************************
4 ^/ s, p: \4 l2 Gint16_t GetGyroValue(char axis)
  f8 n6 K# h& D( L; b3 _' Y{* M' U2 t" L1 d9 P' n) j% m
    int16_t result = 0;% @) G  Z4 }+ L
    switch(axis)
7 \9 I6 W5 e4 C& f, o: m8 h: {7 b. c    {! ]5 r% _1 ]) t3 U2 r# \* _
        case 'x':
6 U9 t% W% [$ A1 E! _& g        case 'X':0 I: ]0 N' z! z5 N0 O1 e
        {
4 X) A$ N. D" T% d            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;% Z- b9 x. L, [; U" K
        }' Y6 e* S+ x: w5 X& `) j0 ?
        break;
2 v- b1 b- L2 u0 {        case 'y':
5 Q/ r% k: Y, q7 e        case 'Y':
+ @& U( V( f& @1 d4 M        {
9 Q  o3 Z+ o# D; w& o! L$ \            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
4 q2 m1 {# f" x' m        }8 z7 C# W6 X7 u+ U) A: c& J* \
        break;9 u/ ?) h5 L; F7 K: F7 l- U* E
        case 'z':% o( b: |" j# A& q9 a2 {+ I! R. r
        case 'Z':
) ]; A3 |* C3 u' `( s$ u        {5 r5 K! v; u6 U& J
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;# {( @, T# h( l7 B& v* l
        }9 a+ {2 u& e3 t- F4 @
        break;6 z3 j3 s4 O0 C2 L+ ]9 Y
    }
+ E& S( d0 _) u% C. s5 t    return result;
/ h/ r- B6 l/ F5 u3 [}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
. d) w; A5 ~1 j! k{
4 T; Y0 O$ M6 b: l- _( }) z9 f& f. M! d/ j: _( ~- r0 g* T; R
  /* USER CODE BEGIN 1 */' I* E$ {9 z+ H* n+ n
+ S  w$ [8 ~1 x  P8 D9 r; [; M
  /* USER CODE END 1 */
/ v& A( J' t6 M4 ~( P9 A; \" Q6 T0 q
  /* MCU Configuration----------------------------------------------------------*/
8 u8 v2 D* H* r7 w0 m) @3 I5 H  n. o* m) x/ E1 B9 u
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
4 {- u" j7 r' F% G4 z# b  HAL_Init();
/ F  r) l: P% W5 x1 Y
2 S" A# z- @# j, G  /* Configure the system clock */
$ ?+ B- m6 }7 s* I3 g+ `' R! y" E  SystemClock_Config();+ S) j) K, u! w; h
& D. J7 ^8 ?0 q/ X+ A
  /* System interrupt init*/
; I7 X( V  ?+ n  i* e  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);2 M, ?6 Z8 q" Q9 x$ T: j( E5 r! g% x
0 @" q/ ~% Z3 \/ S7 |
  /* Initialize all configured peripherals */
% T% O7 }. c3 {# R6 i  b  MX_GPIO_Init();
2 [. ?8 s) G0 W: j1 j  MX_DMA_Init();+ w1 l- C' F' c+ @
    MX_I2C1_Init();8 t* V: g  _4 F! }. V
    MX_TIM2_Init();# A, u$ E+ o" z0 w) Z
  MX_USART2_UART_Init();
+ R3 h6 j1 f0 h5 F' ^0 V    InitMPU6050();
+ c' A3 n, x1 w6 m3 T
; Z5 a& j3 }" w+ t' `  p, K  /* USER CODE BEGIN 2 */' `2 v% f; \$ @
    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);1 S% _9 F  t* U+ X2 P" H/ ~  F! m
    HAL_TIM_Base_Start_IT(&htim2);
% N. F- ?- P# O1 W/ l1 C( \! [  /* USER CODE END 2 */: @8 e: |( ]0 K9 Z5 S. u
# w: c" q) u% q% i( }
  /* USER CODE BEGIN 3 */
/ }  }3 w2 e3 Y6 C9 x* q  /* Infinite loop */8 e  @, W1 i: i& {$ g" Z  ]7 r/ m4 _
  while (1)5 u5 c2 R3 W( Q
  {
, ]+ l  Q  \5 T( c8 N# I        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
& D; B% z3 _$ b% D) [        VisualScopeAngleOutput();
. ~; p; p+ J- g+ r* S; W        HAL_Delay(100);' r: x# d0 |8 Z' n# y4 o5 f  q! S
  }8 k) j6 `2 \& J1 s5 z9 V* M) L" O7 I
  /* USER CODE END 3 */2 R+ g9 w: T+ C' C

/ a* t( I* l: x* J1 H}0 ?; ?4 u/ Y8 ]0 ]  m2 E

" G. T  W- e0 K* F% M, z/ Y8 e: ]/** System Clock Configuration
/ M6 K7 t  c6 S" p3 [*/( S& R; |+ |# K% Y5 A1 A3 P
void SystemClock_Config(void)
. F; j  E' F- T; g{
" A# k1 i/ p6 ^$ b$ {4 X
% c' K. @, F3 a  RCC_ClkInitTypeDef RCC_ClkInitStruct;, l( J( {3 p3 `
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
& H1 J0 @3 d0 `* e  RCC_OscInitTypeDef RCC_OscInitStruct;
. a* j/ J1 b, D, r* ~* z$ u8 ^; T! e' V: ?) L5 C" w6 T7 c) J6 S, _
  __PWR_CLK_ENABLE();
4 ?' [) i; a3 d/ U  y/ w6 a- f$ t4 N% ^' R! v
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
: {3 `. s! r+ u2 b. J2 H# J0 o: t' G4 K. b: i  Z) f$ h5 m2 L2 s
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;- b+ `$ E; i2 B" t- [: x. v
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
6 e; m% l8 j  X5 Q2 G1 l  S9 X  RCC_OscInitStruct.HSICalibrationValue = 16;/ I$ ]6 X% F  F1 H) b" g
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;- E9 A  X6 |5 |- [  }
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
3 h# z6 M% V0 L3 Y  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;. Q7 k5 Q" K+ W6 I) G: W
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
) v4 G6 C4 K: Z/ I  HAL_RCC_OscConfig(&RCC_OscInitStruct);/ ~3 a* i* u  Z* v6 Q# [
  b. y+ _6 u% f+ d4 E
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
1 r( F& ~" c( r  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;6 ], R7 Q" V+ L
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;3 N! z& Q+ i. L
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
4 g& F$ C$ z" c: O( _  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
1 f* c+ [  u+ r5 m" X( @, J  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);( X- N/ x6 j1 L
0 U" F2 W; q# f9 }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
' J5 v3 n  D- r# c* I/ D  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;( J( D. J' P+ J9 A  H% t' }5 q
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);( q$ T' e+ J9 x

: A% h0 K( {0 n5 i+ _% e" U9 m  __SYSCFG_CLK_ENABLE();) _* o, M8 v6 h! T7 y9 g. W' J

' [6 S* V4 K: J. |' V6 Y}, w( B, g& l7 D+ m! u* [

" x1 e% T9 n3 a) I) |+ Z+ y) V/* USER CODE BEGIN 4 */
) `% R; \; `4 svoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)8 o0 b5 |+ y- c+ J- f
{
+ ]6 {! p, J) b; O% }8 w5 T    if(huart->Instance == USART2)) Z* Z% q9 E! U! X$ `3 W# R) p
    {
, P4 g) X; h# o3 |        memcpy(txBuffer,rxBuffer,RXSIZE);
6 @- v6 z6 P! ~5 W        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);6 t0 `% h5 Y6 l6 n
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);  [' t2 Z6 |$ {* y2 t0 u! h
    }
% t! z+ l) w( A0 K' f, {7 s3 q}' n/ X0 |: E+ ~4 G6 @6 w
# _' p0 G% u: @6 \  i8 D
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)* @: O0 p) {; k3 g7 O
{
& F( g- {9 D1 l4 Z3 }% E6 l& R   - ]. I6 g# B" S+ G% L. w0 G
}. W0 z( }6 X  ]! x

9 D+ z1 W$ n' cvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)+ o) k  x1 i: L) N) v! k
{
6 t, h( `# m& H, [    int32_t GyroValue;( x0 f; A, F3 I% M% @
   
! q' _) q1 W9 D    Calc_AngleAccel();! ^& P: L6 a) t& Y3 a  w" ~4 e/ W
    GyroValue = Calc_AngleGyro();/ t& i( Y6 V8 f
    ComplementFilter(GyroValue);& X7 I/ j9 U6 A; ]; h4 @9 U, Z
}
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
' v7 U  b* P' o/ g6 }6 ?楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
$ |+ V) V/ U. r% e9 q3 P
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
0 R% n! k1 H& d0 S) ?1 P楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

3 Z2 [$ q3 G, J1 m, x如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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% m7 I  z$ _+ Q. N6 D7 S! Z如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

7 Q$ o8 |$ z) _2 Q% N好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
  Y7 V( {( E0 `$ O请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
& w7 c4 P4 F; ?  p0 x) A$ H楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
2 Q: P* _5 X% s& g: k请问应该注意什么地 ...

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