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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:; A0 u) ?, ~  I4 l- B
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------8 n  A( i1 j8 p! z; w
main.c2 N/ X8 L- b; U$ q( ]
#include "stm32l0xx_hal.h"2 F/ g# D' L+ p6 }
#include "dma.h"
/ T0 X( h7 i+ d( N$ ]# B#include "i2c.h"
) V& k: Y9 t! k( c1 _3 @1 I+ z#include "tim.h"
9 g. f' v1 i/ M' f3 t, }#include "usart.h"& I* p/ Q7 e! N" o- P
#include "gpio.h"
- E/ J3 j1 I8 F8 U% B: r" n#include "mpu6050.h"! t8 V( N, k3 Z  p6 u! T) G( u
#include "visualscope.h"" I4 S9 n% O- W) s6 d2 j" u
0 ]/ w. H: }4 X( x3 f6 X7 ?* B( C
#include <string.h>, N# Y4 d4 A2 G; U. M$ L
#include <math.h># R9 t' R" r6 t3 {0 x

. r3 g. d8 X5 s. S$ i+ ^. Q: J/* Private variables ---------------------------------------------------------*/
" y- |6 N: L0 `# q# i4 E; Y#define RXSIZE 89 {" H1 R/ x$ R# J; V$ f1 |
#define TXSIZE 8
  n4 n1 p6 ^1 Muint8_t rxBuffer[RXSIZE];
( X: d+ M9 w& g: f2 R) ?3 `( |uint8_t txBuffer[TXSIZE];8 _* \+ ?. E' Z1 u! Z9 k+ J

; l% n8 O' g+ j8 i5 \float Angle_accel = 0;5 I( W4 Z( S3 m% t! A
float Angle_gyro = 0;
. e4 n/ p/ Y5 pfloat Angle_comp = 0;) h) f. `+ Y0 w* }- O
uint8_t outAngleData[10];
7 j) S, Z7 R$ l/* USER CODE BEGIN 0 */
0 @( R# i1 t3 d0 Y; T4 k. x  I7 _5 i  A* j
/*---------------------------------------------------------------------------------------------------------*/) v0 g) h! ^# Q# F$ e) z1 _9 |
/*  重力加速度算出的角度                                                                                       */# N/ j# d7 X5 Z
/*---------------------------------------------------------------------------------------------------------*/; K* s: v& i. @1 X8 t: E. R8 Q' i
int32_t Calc_AngleAccel()$ e( l) n) k' t( ~+ @3 n$ k
{
! V& Q" [  F2 H& ?. A7 e    int32_t value = 0;3 `/ I1 N' k" \# s
    : ^' s% v0 x( A9 G  X7 S
    value = GetAccelValue('x');
% P2 p( ~% w1 A' k- M    if(value > 16384)' K3 U/ t) e3 G
        Angle_accel = -(asin(1) * 180 / 3.1415296);& C" p2 s9 r. s# c
    else
: l+ `2 a% K! f0 s        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);5 F$ b5 h! i2 E. X4 W
    ; Z2 H4 y) W: F# p1 o& W
    return value;
! w! p) b) v+ r6 \1 L& }! p# m; T' w}
% E, z% ]4 x. I: B/ m; ~
- x. r$ N# `0 g/*---------------------------------------------------------------------------------------------------------*/
' n" R% O" f' P) f/*   角速度算出来的角度(积分)                                                                                     */
# U  c7 n5 j/ m/*---------------------------------------------------------------------------------------------------------*// @. ]7 q- X' y4 f0 m. N& a
int32_t Calc_AngleGyro()
% q! f1 _- i* {5 y$ |5 `{5 S; q5 F% D6 }: ?
    int32_t value = 0;, v0 g, O- d6 B  P7 {. }7 g: f

0 K7 [! k* r: a- g( Z    value = GetGyroValue('y');; W, X) k; _9 G  C
    Angle_gyro += (value / 16.384 * 0.01);
1 a3 ]$ `5 K6 H( ]3 j1 c   
# i2 h. i# t% w5 w. X7 T    return value;# Y0 P1 h' S# |9 n% p7 j- k( \' X  X
}
3 q' w3 p8 e2 h: q& j5 h4 I
7 j; O/ o6 N" J: M/*---------------------------------------------------------------------------------------------------------*/
0 x2 W! T$ a/ \2 |) h  U/*   互补滤波求角度                                                                                     */! S6 c+ {6 ]3 f. l* F5 _: K4 k
/*---------------------------------------------------------------------------------------------------------*/$ Z3 S; S8 g+ c. g9 s: X
float ComplementFilter(int32_t simpleGyro)8 B8 f9 W! n- f7 g5 ]
{
1 O9 Z9 L9 g1 n# m( {    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
; z% e/ x* W: D- @9 Z: h   
" X( C  p, e- h& I( y  O    return Angle_comp;
) V1 @) d- S& P0 H$ [}: e! m# D" s$ m" F9 V, h" \" [
/ W: c. U3 f8 v4 U- d' K
/*---------------------------------------------------------------------------------------------------------*/
4 W& N" ^; O/ v/*   输出角度至上位机                                                                                     */- _2 i' Z$ B+ x! F8 ^3 U# k
/*---------------------------------------------------------------------------------------------------------*/
% z+ j) S' `/ ^8 _9 Qvoid VisualScopeAngleOutput()* i' ?% ~4 x4 `: v2 ^; Q
{2 i. E% |( F: O; o( H
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;$ ~% t2 l) a3 N% D7 A6 F3 V/ }
    uint16_t crcValue;
2 P3 }8 |5 }7 c, `; k3 N; t9 f! C    " X' A0 U$ `/ ~# a
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
8 y. S1 }/ Q7 ^% d+ R    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);; {1 t% O7 E* Y2 U( h& z" ]) D1 b- C6 x5 w
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
+ c* S+ A" i' V! r; ~    0 f7 F/ m' F+ }1 C0 Z& ~
    outAngleData[0] = AngleValue_Accel & 0xFF;; \- g% d3 s5 D) h' b) B
    outAngleData[1] = AngleValue_Accel >> 8;8 d) n+ J5 p5 c3 j
    outAngleData[2] = AngleValue_Gyro & 0xFF;% o: p% f* u+ u6 d. ]+ b4 p& C! M
    outAngleData[3] = AngleValue_Gyro >> 8;
) ~. t# p. B) @- p    outAngleData[4] = AngleValue_Comp & 0xFF;- v' ]. t% s' H' B# P" W' p# K3 U0 L
    outAngleData[5] = AngleValue_Comp >> 8;
. t3 f+ `4 B  K/ V1 a    //计算CRC
8 C8 Z. E( y7 o, o; C; y5 `    crcValue =  CRC_CHECK(outAngleData,8);; T, s# x0 ?* I9 W
    outAngleData[8] = crcValue & 0xFF;8 c& ]1 p8 u  ?) n5 ]
    outAngleData[9] = crcValue >> 8;
" Y4 I3 F' k$ D' @; P, E    //发送至上位机& a7 }' W" v% Q$ v% {! \$ o
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
1 F0 |+ Z0 I8 k9 ~) I& j0 v% \) d3 ]}
+ v8 C+ [. S: ]4 {7 ~/* USER CODE END 0 */2 Z* C1 d$ l* ^7 n

$ i0 v6 a5 G+ r7 E/* Private function prototypes -----------------------------------------------*/5 Z: m; [- B: X& P  s4 z& c+ R
void SystemClock_Config(void);
( z/ j  t- c$ \3 D' w; ]4 L7 C' ^2 \( }2 [3 z

+ f6 U8 R( a5 u& u1 E& X. i& j; Q硬件连接图:: ~6 G) R* _1 v% ], S' R/ _
1.jpg 0 d# x3 |3 n: a; m
波形图:, ~& S; R* f6 a1 Y) e& g6 ~; s
2.jpg
1 X+ g: u+ N7 e2 a( g& g3 M* _最后加一个视频:
3 w9 `' j5 v3 l+ j* BSTM32L053 演示
; T1 \6 F3 H% e- i8 l/ M6 P
赞 1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
7 `" p# c) E2 M: |  N9 j/ D#include "i2c.h"
, M) m2 P% Y2 r' G$ y) C
$ _! G7 Q8 S. x. M* C#include "gpio.h"
+ o0 P! @: o2 ~; G( w
$ _/ S9 G' m+ E& G; Z; _; t. K/* USER CODE BEGIN 0 */" V3 C) r' B0 K. t0 Z; X4 x& p
- s" l7 D  e9 m4 v# a4 n
/* USER CODE END 0 */8 ^6 m7 e, \; m1 I: Q, \% Y
7 S1 ^  H! [: ~: I7 l! h+ j0 d
I2C_HandleTypeDef hi2cx;
4 g3 k1 M0 T- k% F5 I( i2 T0 h4 h9 ]9 d
/* I2C1 init function */" `) @# P# N+ o; N4 H) i3 R
void MX_I2C1_Init(void)% \. Z. j8 R( a% G# K4 B% o2 u+ a
{& X% f: Q3 j: _: v$ k

- ?. S3 Z8 `% z$ R3 W0 t) T  hi2cx.Instance = I2C1;
1 N2 w* Y0 r' d, g! ~  hi2cx.Init.Timing = 0x20D22930;
0 r# u& }0 Q  P6 j( l  hi2cx.Init.OwnAddress1 = 0;
' b3 C! Z* h4 m6 [  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;6 q4 x: \+ p& O  S+ Y, S) z7 I
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
  S$ B+ `& Y- O* S& E4 ~' K  hi2cx.Init.OwnAddress2 = 0;$ s0 x6 ]4 I- O2 j9 ~
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;" A) W) l9 y: w8 S) ]
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;, a0 P* w' ^' d# S: g: A. Q) e
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
) G3 M5 j4 }" y0 D! a2 l  HAL_I2C_Init(&hi2cx);9 I9 s, t  ?' t

7 \+ d3 }5 \' P1 Y2 B    /**Configure Analogue filter
+ K# V+ G$ Q- y: v: T    */6 q1 F" O& v( z& c+ R' H
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
/ e  j! T$ ]9 H, C
; j$ E8 {  I6 r  l+ U}8 G2 l( C: A' |5 n  }, t8 v) _  n! I$ z

0 z! d7 G; i: G: u+ dvoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c); f# {# T+ i) |- E' U) V, v5 a6 d( B2 x
{
' s4 T8 d1 Y& j* Y1 s1 ?2 ?, _. Z9 D
  GPIO_InitTypeDef GPIO_InitStruct;
5 y7 d1 B5 y! F3 P) I4 W; Y4 ^  if(hi2c->Instance==I2C1)2 [9 M4 H  b. i
  {
- G1 f8 U7 k' q$ Z    /* Peripheral clock enable */
! }$ O. Q( Y& V5 W8 l( c    __I2C1_CLK_ENABLE();
* c9 y% @: l8 W. k  
1 P3 ]6 C% g- U2 {3 f! y& }    /**I2C1 GPIO Configuration   / h4 U# O' H" o; F8 [: q- F; z
    PB6     ------> I2C1_SCL
( N. Q8 A7 T  d- }) h2 R+ y3 t% p    PB7     ------> I2C1_SDA- t! ]$ k* U8 x- C
    */
7 d3 `. w' z* X( T    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
7 m# ~- V" z* ]  H  \    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;9 v6 A- q( l# A( v6 t1 o4 v9 G
    GPIO_InitStruct.Pull = GPIO_NOPULL;# |& H+ _* k) J* g
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
0 t! e7 w9 a8 N) j8 ?    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;+ y5 {! h: H0 I5 ?# \1 ^8 u& K2 r
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/ Q- Q; K/ e" J5 H2 B7 n, H) \3 S' W& E/ s5 P: ?
  }- T, _9 i! X, |7 ~
}& P5 z! k  ~3 u3 C

/ W# E5 I1 W5 s& [* lvoid HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
% ~. P8 n  S5 M) I{# Z2 G1 U$ C* m$ r
- A) H$ }% C2 j% {1 g- [
  if(hi2c->Instance==I2C1)3 G5 h- G  d1 r# e5 H& U
  {* r. J! B: i6 r
    /* Peripheral clock disable */# \+ h& o' y* @* z9 b
    __I2C1_CLK_DISABLE();
4 ^6 a  M- X9 ~& r- L' i  
! a% d6 P; I4 [+ z  Q% ~    /**I2C1 GPIO Configuration   
# W  j6 H. N( I2 M/ F6 E    PB6     ------> I2C1_SCL
0 J. @9 ?6 m0 Y( S4 h+ y0 E    PB7     ------> I2C1_SDA
) X2 `0 G$ G% R# f9 U, c5 Z$ Q    */
! r: B# N+ e+ J! D    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);' E- R3 F: i6 k' Q  {) N- e, b
: c( |/ @4 B' ^1 d- |  j
  }3 o: A2 D0 M# I
}7 M$ Q  _2 X9 p! O9 \
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ O- R$ Y: O0 I& g& ?+ V
usart.c
4 ?5 _1 N9 \; D  M  Y$ b0 C#include "usart.h"
; \7 L8 {  D' h: B7 M
! h3 I/ g, `7 `; n' D9 d* S  I#include "gpio.h"# H$ P3 F0 R3 L) [
#include "dma.h"+ p  X! R4 X- c, r6 M

- z  L# R& q5 G/* USER CODE BEGIN 0 */
0 r5 ^& Q: n; J$ G+ s
6 G9 ]. T1 F8 \. P4 @/* USER CODE END 0 */
# e: q7 o: ^+ g- J4 ]  ^6 ]* U" h2 U' z8 l; o7 K( \
UART_HandleTypeDef huart2;
1 g/ e, Q2 h% ^% ?1 @DMA_HandleTypeDef hdma_usart2_rx;
2 N8 G1 G+ b4 _: `! s0 c1 y2 {5 G, uDMA_HandleTypeDef hdma_usart2_tx;
+ [6 O3 A6 r. h5 m$ U
; E; H: i# L3 E# q# }/* USART2 init function */
5 g8 c. ?% {" k" ^8 A8 K2 t) w/ S
$ B. |) J! r$ l( dvoid MX_USART2_UART_Init(void)
! N, `( ^6 R) J7 w1 o+ e{
: }4 S6 }0 G# C4 E# F! p; W. g+ @0 ?/ Q# p- S" a
  huart2.Instance = USART2;
# m, n5 t( M% a  huart2.Init.BaudRate = 9600;) x# i$ @5 n. Y4 `. `2 z+ V8 X) p7 N
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
& z0 j) K* e# {5 h$ ?9 n  huart2.Init.StopBits = UART_STOPBITS_1;; s- U- G, ]9 v3 I/ N
  huart2.Init.Parity = UART_PARITY_NONE;( w" ^' ]7 W1 `$ j% ~
  huart2.Init.Mode = UART_MODE_TX_RX;
2 N5 y+ `. F$ q9 c- I  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  c' v8 R8 o, A9 I3 m  C8 F  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  g, U. S! o  T1 _& r9 g: \& }  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;/ ]# X. m8 Q; h) b" y3 {) p' Z5 F% {% V
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
; t0 p( d+ t  O8 \  HAL_UART_Init(&huart2);
( O  ]6 f; v. ^0 ~7 w' ^7 g0 z  j3 Y/ y9 j# Q. I' f5 W
}; F; _! m: d7 M( w
5 }3 U) f* Z7 d" H8 \' g7 N
void HAL_UART_MspInit(UART_HandleTypeDef* huart)/ k* j! L0 s5 i! W$ G
{
4 A2 L# N" ~0 D( ?. P+ d# t/ L: v2 M: U3 G& H
  GPIO_InitTypeDef GPIO_InitStruct;. h: Q7 t' k8 L, @  E& o8 {
  if(huart->Instance==USART2)
; d0 h( \; S) [' K3 U$ I! X, {2 r  ~  {
( C& Q0 z, t! A& ]  K1 P    /* Peripheral clock enable */
. J- ^; O9 Q5 V5 D    __USART2_CLK_ENABLE();- R6 p* V. y6 H. h" \
  & Q' r) y5 o: M2 a
    /**USART2 GPIO Configuration   , R8 H& ]) ?+ T, `3 S- K4 o, t/ O
    PA2     ------> USART2_TX9 r- R; z. Z% y. l! p
    PA3     ------> USART2_RX
1 _5 V) h! ~% E7 r. m4 H    *// G. Z% q; e1 j3 N  k7 _. D+ O+ H! u
    GPIO_InitStruct.Pin = GPIO_PIN_2;5 k, ^% d5 R2 |. }( r( X
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;+ i5 \  H+ M! B' \% g& j9 p/ [( w
    GPIO_InitStruct.Pull = GPIO_NOPULL;6 t, u) j# r5 ]1 g* T
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;0 V4 b2 s, j/ I( Q  e1 e; A# Z
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
& q$ X+ e9 M* h% }7 ^5 k8 \    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);5 Z( H6 B8 R' H% l2 o9 ?
; H7 H  {- {/ ]1 N3 L* J3 l
    GPIO_InitStruct.Pin = GPIO_PIN_3;( u. A4 n8 O! `
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
# V. r1 f) \0 z: X& }    GPIO_InitStruct.Pull = GPIO_NOPULL;
, D3 o' [7 e9 a+ }7 X    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;. y0 g8 B* y8 t
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;# F4 _8 D7 M/ Y) o5 G6 a
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);' X, e# j5 R1 W: I3 v: V

  O" z: C2 ?0 X$ D' l    /* Peripheral DMA init*/
$ l) L2 Z7 y% e4 D" C$ Q0 A2 G! p  ) G6 T' a( M1 z" d
    hdma_usart2_rx.Instance = DMA1_Channel5;: Z9 `2 Q8 [2 f( u2 t& k- T
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;+ V) t3 p+ A1 X" S: z) z! B7 H
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;. O' D/ y# e, {
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;) ~0 W; }- ?4 u0 f; k
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;8 |" m' x$ `9 i) c
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
( p* d3 O- o/ G# I" @$ @" o    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;' g# X! s. P; T3 V
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;2 }! O6 a4 T4 o8 E# j( `* l
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
( B8 L! Q0 w6 t" Z    HAL_DMA_Init(&hdma_usart2_rx);( m. N7 D: |; E) P! ]/ x

* b. d# g! N* r) E0 Y! Y# ]% _    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: {( I  w* G7 d/ e" j# m# E) _' e5 H
' m) M7 Z/ K0 D8 \9 K1 r% k# t
    hdma_usart2_tx.Instance = DMA1_Channel4;
8 s" C( ^% K% L1 Z1 e  \/ l( A    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;6 p+ @# U1 U! K8 |
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;1 t" q  Y. u1 n
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
- ?" ?" k, W9 C/ `5 f. j( Z    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;2 m  S  Z0 R9 F1 R& F
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
! S' w5 S5 {* c2 H5 o/ y    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;: U" @7 R& A' x$ ~# S. x* t6 }
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
. G3 `2 X4 _+ x: m    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;6 ^/ Y4 W9 N. a
    HAL_DMA_Init(&hdma_usart2_tx);
* E1 Z* S+ l/ o& M) I& p/ W5 r
, C' N' @/ H- m& ]1 k" O( l    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
2 R2 V  k, N  w+ x% W$ Z% U5 I9 \& O; e  w1 I1 ]" L0 {# @
  }
) V* P/ M: z$ W. H}9 n- ~" U( G* @8 w3 Z

$ l0 q& G% |/ |) jvoid HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
0 M2 I) A- b) {* n{2 L) b0 N9 M) y7 e7 A" x

2 N# S4 i' K) [  if(huart->Instance==USART2)6 y& _$ x2 d0 ^: k. L* s4 j
  {8 h7 i+ j, M2 v7 v/ @
    /* Peripheral clock disable */1 s2 _7 c3 P% u! c  a& ^% g8 z
    __USART2_CLK_DISABLE();! Q" O" \2 @1 P: c
  
2 L& {  w* f5 i; u    /**USART2 GPIO Configuration     ^! R+ i8 u' |# i% v7 \. {/ K
    PA2     ------> USART2_TX
+ p+ A" d6 k, w( @" a) L    PA3     ------> USART2_RX* u7 ~) d' K! P" ~
    */
# [- [" `, t9 e. B    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);3 N- U6 t) E3 s7 s$ X& l: Q! B  r
& F: u5 O" y5 I7 `" z# R: ?+ e
    /* Peripheral DMA DeInit*/& q8 f) C9 m# v  j: [
    HAL_DMA_DeInit(huart->hdmarx);! k* Q( E( {8 O2 r0 ]  i! b! O
    HAL_DMA_DeInit(huart->hdmatx);
0 H3 V/ [- L! P  }
- U/ W7 ]1 n8 C4 }, Q4 _) v2 ^# H}# s7 _/ g# I5 s- E/ U" g- ]8 _
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
5 o3 Y2 u' g# t* U7 p9 S5 n9 \( n5 Xmpu6050.c
0 b  B: U) Z) C$ v4 A#include "stm32l0xx_hal.h"
3 i! Q  f& c  F9 Z- q0 p/ g# F9 K#include "MPU6050.h", z* K4 |% A( ^
6 d  S- }0 _+ g2 f5 Y" W
//各坐标轴上静止偏差(重力,角速度)
1 O- ~8 A5 F( J9 y8 V- M8 Q$ N1 @: jint16_t offsetAccelX = -195;
+ X; A; _$ r- @' I6 a9 s7 J  R& i3 Fint16_t offsetAccelY = 560;4 X: ~4 V& P& I$ q8 c  F+ j
int16_t offsetAccelZ = -169;
4 \& Q1 [& Z; d7 |* W* r/ S" E- ]& t: T) ~* k9 b# S  ^- [3 ~2 e
int16_t offsetGyroX = 12;' C7 M) b" F4 y
int16_t offsetGyroY = 33;& G" D, U. C( R' t) |0 b9 e
int16_t offsetGyroZ = 4;
( i2 V+ u& C0 `4 a" i& G, t; R  `& d  ?
extern I2C_HandleTypeDef hi2cx;9 x/ W2 U3 M2 {% k9 f. h  r- U3 x

* O+ E  c9 p3 B3 b6 y//**************************************' \9 l- K- o- h" N+ K$ N" d5 H
//向I2C设备写入一个字节数据
" g% T" N9 s/ e7 ]1 v//**************************************& H( W! t+ K& [2 |' x) C
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
' e# Y4 g( {' L* D$ H4 S{% f) q& e& [2 Z3 Y
    uint8_t rxData[2] = {REG_Address,REG_data};
# v( O1 c, P' I$ x    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)) U2 D7 R+ l4 r  [8 z+ L/ F4 ?
    {* ]; d& e1 c$ `4 @0 \" m% d% B
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
7 @* W6 L$ R$ \! u. g" J  Q        {}+ x; x1 j& q6 C
    }
4 o+ ^2 o+ t. m7 K}
: g% v1 o: H' }//**************************************
! D9 J, s- X) N: z: E8 j/ {+ G8 y//从I2C设备读取一个字节数据
' C% Z( z9 ~$ i6 b/ I//**************************************8 d' `8 r. J6 p6 h8 H2 F6 F( r
uint8_t Single_ReadI2C(uint8_t REG_Address)4 R; o2 R1 Y+ k% P
{
  D- B7 ~* j( v. H! h9 n; |    uint8_t REG_data;
! y8 p# k1 L) w# b3 g1 v6 ~    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
' z* A) a0 [  V3 D    {
- r1 r* f+ D' |, ^        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
3 \4 F9 p0 [& I2 h% `        {}$ D) j! X- D! D2 ]) }3 O
    }
) q5 S# `& w6 ?( [  x   7 u: b/ _+ k- ?1 b0 S
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
; U( l7 f( J: X* H2 H* |    {
7 q* C- K6 k" j" M        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF). u* }: K% m6 R- v
        {}
- P8 i" P3 N; U2 R' X* }, ?  v    }! d6 u- {7 ~6 e  V4 e7 D9 I' A
    return REG_data;" S5 P+ O/ f& E- F8 }
}. s$ i6 b% w/ y8 Z( ]
//**************************************: e! Z* {) Y* v  N  ?+ Q
//初始化MPU6050
4 q5 K) P3 h) W! f$ i//**************************************
6 m& R0 _6 @: N1 e  z; @void InitMPU6050()5 O+ W+ o2 I+ l" r" W1 E* ]
{, m6 P# O% H5 N* O( f' \
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态  f+ R( r: ?0 M6 Q2 J, ^
/ S( m# D" q5 S+ D/ A
    Single_WriteI2C(SMPLRT_DIV, 0x07);; q9 s* K3 p4 u6 n. [

( r; Q( D* Z7 |    Single_WriteI2C(CONFIG, 0x06);
8 D7 E4 q. k) a1 i
$ `3 o. c; F- V3 k    Single_WriteI2C(GYRO_CONFIG, 0x18);( ^* w: a' x+ e1 Z1 d0 d' m
5 F* c0 Q: Q$ A* Y  [
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
, b) D. {1 w, }) J4 o}0 {3 M  ?- B- G
//**************************************
$ [1 k8 U$ j8 {/ c" }! a7 y//合成数据
- C5 e3 _- T3 v4 z- X* t& x//**************************************
4 E/ @& v! l2 H- L, Nint16_t GetMPUOutValue(uint8_t REG_Address)! M  S/ i$ t. R3 L/ \0 F' K  y( q
{
; j, f/ Z! C# f    int16_t result;* C* `8 ~3 M% ]2 F. Q
    uint8_t H,L;# L# ]6 I/ o; X. Q) F$ d
    H=Single_ReadI2C(REG_Address);) N: Y& Q) |1 B) ^$ ^) J* _
    L=Single_ReadI2C(REG_Address+1);
$ z6 G4 l1 F9 _% X" [3 S5 Z0 r    result = (H<<8)+L;- W1 h  D, g( M% _
    return result;   //合成数据
8 a7 W# e  g8 b! ^  `}
$ c, o' o, S1 H2 ~8 b2 p9 w. f+ e" A" J7 i8 S( G
//**************************************
4 y+ {2 s( `  f9 f//取某一轴上的加速度数据
) d0 B7 O& [9 L- N//**************************************0 r4 P5 E! t7 y5 R
int16_t GetAccelValue(char axis)
: v* `. W" @- Q0 o% j{
$ s2 b3 c( K; Y# b  k    int16_t result = 0;, o* V! Y  r8 x3 D4 D) `9 p
    switch(axis)9 r5 ]1 ]  u1 E3 i* s
    {
" S5 A8 Y2 i0 K, X        case 'x':" j9 M4 E- A/ m' m& q# w, P
        case 'X':
* i" w8 ?8 X7 w/ v3 h! e# w' ?! P        {  w% C( o  q+ H! T# b5 [
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
; R4 d$ E' q; @, }        }
; A/ z2 ~; ]* x3 I* L$ w        break;* J- m! w# e/ R3 W
        case 'y':
' f3 Z0 ?+ B/ f        case 'Y':
1 ]4 S" [7 P( U6 b& ~. G, N% K/ M        {
9 M9 S8 F3 L& N$ C+ O2 `            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
, A" U% \  `4 C* G+ B/ W        }
) I, o$ H- z. O3 M% w( r" D4 e; B        break;
9 @% Y4 f1 ~" j; e        case 'z':
- A7 F- G( e9 ]" Z5 F        case 'Z':
5 x! O8 E$ K2 }" d        {/ ^. l( |1 p: v
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;+ ^/ g: S4 O* e
        }
1 Y  f+ [1 @6 L# O        break;
2 E' D% R! x1 a  i2 K    }5 z% s' Q. Z- L2 m
    return result;
$ {% U" x% ~" O' L}6 S; o$ j4 _5 h5 t% Y1 Y
" A+ {3 ?) t1 F! E$ S
//**************************************$ h( ]( r9 j: ~3 s7 g
//取某一轴上的角速度数据
$ f' [" w( }8 t2 u9 j" b//**************************************! m3 E/ S2 P, D# ?" n* Z5 U  s
int16_t GetGyroValue(char axis)/ x0 y3 ^  [  J5 L" E3 a
{
4 X; ?/ }; E& z& A+ _+ n0 n0 N8 U    int16_t result = 0;. Y7 k+ ~2 E: H% I0 |
    switch(axis)
! _* }( E* A! A4 l' O    {* v" i$ [" U! W  s5 A2 H
        case 'x':% F' V( [# p/ s% z
        case 'X':  t2 _6 O& n$ T. z, D
        {
: n' j2 L; Y: O% Y! A            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;& m3 n. N  m% A6 W! o$ X' V' ]7 @6 Y  S
        }
+ r+ M' Y# G- F        break;! E" o4 A3 _( U& r& Q$ h
        case 'y':( V( Y* T2 O( j' N
        case 'Y':
  v, k5 x3 K1 K1 h        {4 Y4 w9 W5 ]) t7 _
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
% Q/ l$ b5 L( k0 n( @8 L/ h3 S        }
, y0 e4 I1 R1 I/ d) w+ m) L        break;) x8 n4 `: n: u& b
        case 'z':
5 m* v) |, H2 W0 }4 H3 S# j) [        case 'Z':
( J) G! T2 Q" G+ n        {
. A; f3 S% V1 U4 y9 R* s; h0 K9 \            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;6 C0 Q; U+ w* q
        }
$ R, x* |! x9 |( `        break;9 t' {- f# M# K
    }9 ?8 e% N$ T. ~* u
    return result;' g5 X$ u: T3 {' m! @
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)# ~: c% }2 ~8 c9 U% x$ t* S/ O& K
{6 |% F5 Y  I8 ]- |! Z

, U  C2 i7 ]  Y, ?- r, _  /* USER CODE BEGIN 1 */
% ~+ F1 [9 s: h5 i  I2 c6 e2 E) u
  /* USER CODE END 1 */! |( F" a& c5 ]( z( q

4 d, K% _1 o' r8 n2 n0 T* H8 q" k  /* MCU Configuration----------------------------------------------------------*/; v( U& A  G' u( a+ j, [
2 X. q! w/ c7 M: L
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */: ]7 E+ _" A0 Y. ?
  HAL_Init();
0 s4 e. i5 c) j8 B
  D* Q5 _: ^* c& v  /* Configure the system clock */
: I- q' a/ U8 T' d: g  SystemClock_Config();0 ?6 I$ r* `( T
! C5 H% X! O9 U& l0 {$ c
  /* System interrupt init*/
/ u+ r9 T# K( V; n1 v  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
* O; k6 r" ^9 U4 u! p2 p8 O/ e3 ^# K% c6 B( A! R# X0 ~$ i3 i! j
  /* Initialize all configured peripherals */  ~; Q. R7 J' \3 ]
  MX_GPIO_Init();" `- ?  R! X: Z5 H! _) X9 P$ X
  MX_DMA_Init();1 F! I# D  j; ?: V* a- I! T
    MX_I2C1_Init();
8 H2 ~; w9 R( A8 ^! n( ?( U1 R    MX_TIM2_Init();5 _: @5 J5 ~! ^* |) r8 b: [
  MX_USART2_UART_Init();
0 c8 t5 l, D4 ?1 v0 S$ x    InitMPU6050();
1 K. X2 `, k& q9 d0 e2 Q$ Z7 F/ ^" Y" i
  /* USER CODE BEGIN 2 */4 ]7 _4 ]( g' u, A5 v$ O
    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
. J  t3 e" t( Z$ ^    HAL_TIM_Base_Start_IT(&htim2);/ b2 p! H  C! h5 L' f
  /* USER CODE END 2 */) r6 A+ G; C% i  O: p3 T
9 W  n& i/ |! I. k& c, H6 I5 x/ q8 J" M
  /* USER CODE BEGIN 3 */* [# L3 x' c+ W" l! F( h1 d" X7 n
  /* Infinite loop */
5 p* h/ z# w( X# e0 D, I- c  while (1), d8 F/ S* m5 j) j0 ~$ l7 n6 A
  {2 R5 n* h; g5 ^8 @5 t2 @& N; X
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);: z! {, ?1 j: Q+ T
        VisualScopeAngleOutput();
1 y6 V6 g4 t8 D3 `8 P        HAL_Delay(100);- L. t$ o& e7 r. C; a4 M
  }$ k% f1 H4 [: ^- i: g
  /* USER CODE END 3 */9 a1 `: h+ f( l
( A9 E9 k& Q* F- I) ?5 L5 G
}0 c3 \1 F* V4 N
" u: k2 ~# P, J) T
/** System Clock Configuration
  A" Y% X1 \, x  r% E*/
: u% E) h1 @" k; z! ?0 Pvoid SystemClock_Config(void)
3 }8 v8 k9 W' p( g) U  @{# J/ ]9 C, d5 O4 X- P5 ]
6 [: \4 p0 c1 u" U8 p5 e1 |! [. @
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
/ r6 e. }) b, s& u  RCC_PeriphCLKInitTypeDef PeriphClkInit;  k5 S% X- E, i5 @
  RCC_OscInitTypeDef RCC_OscInitStruct;  l2 e3 m- P! `1 R/ M! _

  t- Q* C8 r% J3 E0 l  __PWR_CLK_ENABLE();
; t% f0 a; L$ {+ z9 R
5 `$ L. X& l' b9 k1 u+ w; g' V  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);& g1 ?5 m7 C$ }- Q3 O9 p2 [
$ g3 q0 K- e, O# M
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;! _8 F/ t8 E% _7 H+ N# d1 s
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;: L& o) [5 I7 a+ K) I- ~4 B- u
  RCC_OscInitStruct.HSICalibrationValue = 16;+ h2 t5 W9 l% F+ r
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
' |: Z5 j3 i$ G/ _- p$ |& A/ j  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
; M1 ?* p3 E. Q4 q2 m: s% ~  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
  E; s  B( c- J7 ^* |# a/ v  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
5 f; e% L4 E# N) K, [8 b7 c  HAL_RCC_OscConfig(&RCC_OscInitStruct);6 v% o3 k2 t$ x$ Z

" _& b% @$ L& k1 }  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;  o% [4 ?. k, u1 |6 T
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
* ~* L4 q  J# T) \  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
* f! J0 z' T# r# u- X2 Y: t  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;# i! \' [6 Y* L+ I, x
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;% d6 g4 m0 ?5 D3 g5 Q$ c" T/ J
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);  P* S" Z' B: T; q: x* b: v* Q
7 R! M, `; Q0 ^
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;) V1 x9 q& ^& A1 }6 }: b# m7 V
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;: {6 v$ J: B. n& {
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
& @% X# u- E7 y* t: G$ y; r8 y3 D+ u; y5 J
  __SYSCFG_CLK_ENABLE();/ D0 Q; J2 ~/ {) m

; V6 R. K8 g8 ~7 f}
- E# z" g9 u, _6 D( w+ a3 B: q3 ]6 m5 G$ P3 ]
/* USER CODE BEGIN 4 */# P: b, F8 `/ z
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)$ H0 O6 J2 \7 T) P+ ~: c9 [
{
1 ~( a# K% O7 L4 h7 N) d4 X    if(huart->Instance == USART2)
& {6 n. T8 N1 s7 m/ ]! v    {' k6 G6 z0 _% C' n8 g
        memcpy(txBuffer,rxBuffer,RXSIZE);& N5 P$ w, p3 b6 o1 u( K& y
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
1 }  C; u7 O7 x* d+ `9 r) |        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
3 {6 N8 [9 x3 n    }( E: p8 S0 o9 Z9 `8 y1 f3 l
}
! k' p' x1 c+ U1 D) U+ a* h, J& m" i: s5 F
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
' Z1 A* @7 w+ {" i, s{7 `( x; Z* v6 j; S# f2 l
   
6 a) c! `  W. i/ M0 e! k}
/ g# v! O0 ^, A7 o$ F( y) v. E" E1 x- r
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# d" R' o( {$ m! Y. U
{
5 I" ]  Z/ h3 I  e    int32_t GyroValue;
2 e+ g# L  N' C1 ]! S   
2 H' }/ t6 N- D6 f    Calc_AngleAccel();
% U& X% W, l3 l! [, X    GyroValue = Calc_AngleGyro();
( e! L9 N- ]8 c! I9 S    ComplementFilter(GyroValue);7 c- }+ |' c0 C/ L. b0 n5 w
}
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
8 Y3 {8 \4 C) K" z% ^1 n+ B楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

6 l* q. K# V7 d7 V使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
3 N2 M8 M5 V* M& K% N! s" Y楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

) n% A/ T) @* Y如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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
/ i2 i# l0 f7 s# @( X; ?如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

- N" r, _  y8 i( a3 h好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
  }! K4 M% Q( W$ C2 P6 e! W8 K! E2 B7 C请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
5 }' y+ Z9 f, }' }+ x( J9 ~楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?* k$ E3 N/ [/ r
请问应该注意什么地 ...

  ]: T$ v$ h2 ]我使用是没有问题的呀。

所属标签

相似技术帖

官网相关资源

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