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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:; q' x: E2 U; T. I5 Q4 [
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------& i$ B7 w$ b( Y
main.c! Q  [$ H( N/ z# i! T7 k" v2 u# }
#include "stm32l0xx_hal.h"* N1 Y+ G9 z- ~+ [
#include "dma.h"
- z1 y1 R. H4 }#include "i2c.h"
( N0 J4 N1 r$ m1 d' X4 z& O#include "tim.h"
. ^4 M% ^: ?# x. K+ M) r$ w#include "usart.h"1 Y! f5 ~  S. R+ @0 \& a! u
#include "gpio.h"+ W4 K# O  i2 H! G% q/ @
#include "mpu6050.h"
' ^: x! E) C/ @7 A7 s#include "visualscope.h"
: L. O, n% `/ f4 X' P7 r( t  C! X& R* a+ _3 K
#include <string.h>
. e+ s. C, N: R* B#include <math.h>6 |  _- t5 K6 L* _4 @

# |( f3 ?4 j0 W! i/* Private variables ---------------------------------------------------------*/6 {6 Y% T6 {0 K8 C8 \
#define RXSIZE 8
, r% z# o" Q; y/ f: D) ]4 _: Q& @# }#define TXSIZE 8: V' o7 v. y" G; K
uint8_t rxBuffer[RXSIZE];
% ^3 b3 e7 b' B3 _* Tuint8_t txBuffer[TXSIZE];$ c- X- w+ B8 I& r3 r
% ~6 w$ F. w9 `, x7 T2 {9 r0 w' V8 z
float Angle_accel = 0;
" V. [- `3 b; l6 T: j7 g! `float Angle_gyro = 0;) U: t8 U* t8 |5 A, E$ E# x$ d3 y
float Angle_comp = 0;
: c- T4 V7 L+ r" x9 ?uint8_t outAngleData[10];
+ \6 b. @/ U" N2 @$ d- @3 N/* USER CODE BEGIN 0 */; G% y' M  z2 F

; W4 k0 F. U( j$ y/*---------------------------------------------------------------------------------------------------------*/
+ {- b2 k, |; O/*  重力加速度算出的角度                                                                                       */
4 p( }' B7 ?, e3 i9 U- ]/*---------------------------------------------------------------------------------------------------------*/
$ Q7 s: V/ s( a; m8 D" p8 @int32_t Calc_AngleAccel()
6 `6 b% {5 s3 ~+ }' _{6 I" F& y( S1 ~$ M3 D3 g
    int32_t value = 0;
2 W* [" S' `$ ^) y1 I. M2 G   
4 f1 J$ w; w; F+ a3 m6 x    value = GetAccelValue('x');
+ t9 N( m: w# B% `    if(value > 16384)
4 ^& `! H7 i. {6 h' Y        Angle_accel = -(asin(1) * 180 / 3.1415296);
$ J  L) m. Z; g    else8 Z: s. Q4 {7 y6 u; t# s
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
: a2 \9 p% g$ r- R' P  Z   
0 n' G/ e5 R# T- }9 ]    return value;
6 j, \( T0 l( J# H$ Z( {- r0 Q" _}
  u8 ?$ D: a7 I+ s. _% v) U7 d2 E, r' u0 p* C5 V, K
/*---------------------------------------------------------------------------------------------------------*/
* U- \$ v8 i/ ^! b2 u9 n9 Y) x# L/*   角速度算出来的角度(积分)                                                                                     */) G/ W) ^& I7 U
/*---------------------------------------------------------------------------------------------------------*/+ H1 U% x. Z6 A/ T6 t
int32_t Calc_AngleGyro()
8 y. r% K$ N( s) h{3 F; T0 k' V, x' g9 s/ {' n
    int32_t value = 0;# U- S- `7 s+ I0 V' L

! `1 F: T8 q  ]6 V4 r    value = GetGyroValue('y');# E$ P. q0 K& L$ [; _6 a
    Angle_gyro += (value / 16.384 * 0.01);4 B: Z$ I  I% z% _+ L
   
  ~/ O  c& }3 [% G- v    return value;
9 M' x0 z+ b% i& E: k- |}1 K9 K/ O9 F# u6 J
* V( Y( x7 S* F9 w
/*---------------------------------------------------------------------------------------------------------*/
+ v0 [: i4 I2 C2 P: _+ g) \/*   互补滤波求角度                                                                                     */0 h% J7 ~5 P- b5 K* U; x4 Y
/*---------------------------------------------------------------------------------------------------------*/
/ ^0 M* k5 n0 X5 S% F" I% B( T; \float ComplementFilter(int32_t simpleGyro)
; E* t0 O4 [4 {- D{1 e: R7 b& y0 n
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;" ~" `' i* q4 R8 [! C$ F) \( U  x
    0 T# V2 S: I/ Q: `6 n, |
    return Angle_comp;) e' X2 k* C1 [5 M; {
}/ ^) A5 T7 _& V$ e9 S+ B

7 z- {1 R( a0 M% @3 [0 d/*---------------------------------------------------------------------------------------------------------*/) u6 ?5 }! v, W9 b7 ~# g, p5 _
/*   输出角度至上位机                                                                                     */( o+ ?4 W5 p4 M' j7 Y
/*---------------------------------------------------------------------------------------------------------*/1 \$ _- m( z0 W/ i  p
void VisualScopeAngleOutput()
4 O) F  V- g7 i/ A$ M. }{! ]! W8 o: _. X" j1 C) j5 N
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;
2 \1 T4 |+ y  w1 z2 i% z    uint16_t crcValue;
1 t" i# N/ ?0 [7 R    . C* V! c3 l: b  t( A6 H; I
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);1 j& y/ ]  n; `. l7 c4 v) w8 j
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
: `7 E1 o; n: S. o! g+ L    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
7 @7 r/ f( k6 m! V: [    ) X' F: M! R/ c
    outAngleData[0] = AngleValue_Accel & 0xFF;7 h: h5 W3 Z: D
    outAngleData[1] = AngleValue_Accel >> 8;
( ^2 V+ i) Z" C  v" ?    outAngleData[2] = AngleValue_Gyro & 0xFF;6 e. {0 U/ Y0 I: r1 A; g) B
    outAngleData[3] = AngleValue_Gyro >> 8;
# D5 k4 G) }, O: H9 H: `0 P    outAngleData[4] = AngleValue_Comp & 0xFF;: l7 |! d' z; J! k- Y/ [
    outAngleData[5] = AngleValue_Comp >> 8;
% J# y. a! O5 B4 \5 e7 t    //计算CRC2 `& {" y; J1 Z
    crcValue =  CRC_CHECK(outAngleData,8);' b/ G! }+ D1 C; C
    outAngleData[8] = crcValue & 0xFF;
' w* j4 m: l9 I) [+ R" D; a1 O+ d! Y    outAngleData[9] = crcValue >> 8;
$ Q+ _. g* s. b) L& H    //发送至上位机4 [: w# D* V5 X3 v; T! Y/ G- R
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
: Y# f# }/ Q9 R! [6 x3 R$ z8 S}- G; o7 Q6 I. J+ b; x
/* USER CODE END 0 */" X: f5 r8 B/ l" ]; c& ~

- s  `0 {- ^4 |* R/ e/* Private function prototypes -----------------------------------------------*/
8 g7 J" X7 i! d+ R( r: z1 ]6 cvoid SystemClock_Config(void);' b( j" @' j7 ]5 O8 z
2 l9 O. D8 Z* p5 a+ t
' ]5 G; j1 x2 ^1 B+ X3 `
硬件连接图:
8 J. `! b' _0 y1 ` 1.jpg 2 D) k, \3 @3 d( x3 ?4 E* W) z
波形图:
& _7 C/ D5 i# \ 2.jpg
$ D- m6 K' Q  u( x& |最后加一个视频:/ T8 N3 d% n0 I7 `0 r
STM32L053 演示/ m: \. D- z" n) m' N  y# X
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C( q/ A- p4 W4 K7 U. n- I
#include "i2c.h"
/ A$ Y/ K) I' {
9 n7 I  `# |$ c9 w4 B/ Z#include "gpio.h"
& q: E$ g; N1 M+ E4 f* T% O0 m8 _/ P* N! l$ c+ }. }4 j
/* USER CODE BEGIN 0 */
5 G7 @7 Z& U, G$ s. j! \+ C/ c* _" w* |' G2 `
/* USER CODE END 0 */
8 K; S$ r+ m# D0 @+ i8 ?& O. w8 V( ~1 n9 o. a4 L& Z# u9 [
I2C_HandleTypeDef hi2cx;
; e- n' m9 Z" @* Q
9 P  `; t, L8 r/ n9 J1 m/* I2C1 init function */0 @7 q- h8 _& f
void MX_I2C1_Init(void)
$ @' v: C3 K& t! J1 R. A{
$ O. J; B. V7 y  M5 S) M) N9 V
2 k2 z" K2 \' q  hi2cx.Instance = I2C1;
9 K# d% ~. o* F! ~5 O  hi2cx.Init.Timing = 0x20D22930;
! v4 _9 E( V/ D# j; \8 z  hi2cx.Init.OwnAddress1 = 0;( Q: }* t# F+ y8 ^7 ~9 Q1 K
  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;. m5 a% p% ^* @! q7 ]1 Y+ t2 g
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
: k3 T% A! h5 o, F  hi2cx.Init.OwnAddress2 = 0;
( U: M7 d7 }% g8 J7 {0 W- r( j  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;# Y6 T' |. a% m
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
( o1 i! S# L# v0 G: q, `" w  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;: n3 q5 {, `' P5 b. i
  HAL_I2C_Init(&hi2cx);
# \- X4 a) \7 G# w7 O5 B7 C1 h8 M0 V9 V
) i& j! B& F$ q% T5 P! s    /**Configure Analogue filter* d4 `2 z: i4 C& P) @) R" I
    *// P: b9 b4 C) F: p2 X+ g. A0 T  i
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
; W- u* t3 |. @3 e0 \9 f
4 e. B/ O, R9 I! L1 o}+ |# J0 s: h  u
0 W. s6 ~0 m8 ?# {0 T3 `
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
, g( z  ]/ `& R7 N4 j{4 Z4 B- m7 R6 Z/ t' r5 \
! t) T& J$ T+ K7 p/ _/ `7 t
  GPIO_InitTypeDef GPIO_InitStruct;
3 A. h% I6 V$ [( N/ ]8 S  if(hi2c->Instance==I2C1)) @; t- L% }3 s1 c# V- t
  {: C& l: t: K5 L4 q: V- p$ R
    /* Peripheral clock enable */
! v$ t9 p  u# b) `! p* u& O! A( y, b    __I2C1_CLK_ENABLE();
: A* V+ x, ?$ V' U; j  
* C5 `2 U( a  H: P  \1 o    /**I2C1 GPIO Configuration   8 k2 [0 U1 n9 }( q5 z
    PB6     ------> I2C1_SCL- n4 Y+ {. _" ~0 z/ S- P
    PB7     ------> I2C1_SDA: [7 @" A' \& Z& [* _
    */+ e% k4 K4 d( ?: d
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;* c6 C3 W; {4 R0 b! j
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
" v" r" }" o5 s/ O    GPIO_InitStruct.Pull = GPIO_NOPULL;
) Y4 ]: n4 K: M3 ^+ K    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
& q2 v1 p+ q/ ~8 g. e0 b    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;- E! Y7 R  U2 E( L, E, j
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
# k$ p9 P, `# k
9 O; T/ V1 \, Q8 K6 F% @  }/ k1 f- U$ m/ M4 G) o" E8 d- O( a
}& V; Z* J4 o' c8 w" A8 }

5 M0 _6 F8 C1 K! A+ @void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
5 ]- Z+ M  o1 C) _: f{
! O2 c' C  g7 V0 G/ R
' S$ t# i: ^8 O  if(hi2c->Instance==I2C1)0 W* A( j  _, q$ L% O! ?
  {
. W+ `" l, P5 f* {1 J    /* Peripheral clock disable */
! ~! L( [( t) b    __I2C1_CLK_DISABLE();+ T' |' G0 [  D4 |
  , S/ `, \. @2 K9 n0 Y7 p
    /**I2C1 GPIO Configuration   
- J7 r: \0 r* V$ I    PB6     ------> I2C1_SCL
. ~* ?' _) d8 e7 Y    PB7     ------> I2C1_SDA
" Q) T: R- v0 v: r- G" ]% L    */
$ Z# M1 r" w; y5 P: X( I8 n& o2 w    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);& v3 |. B  E) q* ~% y  J
; ]$ i3 y2 C3 o0 W" a
  }
; t7 ~  d9 j, i3 u! s" `  m}
$ L+ m4 X0 ~% d- y% e------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
0 W( o: a" V, u4 yusart.c! I  R0 b4 p; z, E- \
#include "usart.h"
2 A0 E8 L2 W+ k2 |2 H/ A& d* s, J9 u$ c9 L* e; ^( w
#include "gpio.h"
% ~& ~7 r+ [( n: z4 p#include "dma.h"2 I- F. O' X! m

) g, \; Y% Y& g, s0 W( j; v/* USER CODE BEGIN 0 */
2 ]" B$ D2 {( X. t
" V& X; ~. @6 @5 [* p# T/* USER CODE END 0 */
  `2 L( C; e( e8 o
: T7 x/ f  _* i) Z; d% w  kUART_HandleTypeDef huart2;6 d, Q. i, q1 X* S: t
DMA_HandleTypeDef hdma_usart2_rx;+ n! L: P: s& c( q4 x+ C/ I
DMA_HandleTypeDef hdma_usart2_tx;9 f* k9 S/ O. g8 `
- u- c2 K( v$ ~, m
/* USART2 init function */( i3 k* C; h& D% Y) B

0 q" w# W! W4 Y/ T" X( evoid MX_USART2_UART_Init(void)
8 r# X0 ^+ R7 h, G* Y4 s( L{6 t8 p  r' J. D7 H4 c8 `

! a9 F$ I1 I% t9 G" H1 R  huart2.Instance = USART2;7 ?' }% m8 ^, w  I
  huart2.Init.BaudRate = 9600;4 C7 x. q  W% \& b+ ~1 S7 n% j; C7 ~
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
; Y* l6 f. j8 E" y- l# j% v  huart2.Init.StopBits = UART_STOPBITS_1;
2 r+ a" Q2 {5 N7 u  huart2.Init.Parity = UART_PARITY_NONE;: B' G2 j# y) x$ m
  huart2.Init.Mode = UART_MODE_TX_RX;
9 W  z! W  U8 _" b2 t  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
; E; l" }. K  j1 s1 T" f% v- Z% J& N  huart2.Init.OverSampling = UART_OVERSAMPLING_16;4 `1 J- X( l/ `/ n5 f
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
) O6 u# `1 V" W- P' Z5 D. t  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;! U$ G0 F+ R) ~$ y
  HAL_UART_Init(&huart2);" K( u) f: R+ A! B$ M- S
; E* V5 a" g  a- l1 D2 N
}
$ M9 B% L. _* v6 i7 ^  T, d3 M: b
void HAL_UART_MspInit(UART_HandleTypeDef* huart)  [' k- p, H3 O8 h% k0 B
{
. ^8 W0 D6 O+ f9 g. {0 M8 f) [; c' [
1 D! n$ n& M2 a" a7 R  GPIO_InitTypeDef GPIO_InitStruct;
$ f0 b# @; t; Q0 y  if(huart->Instance==USART2)
1 g' p& I/ }: b. R: q  {
0 y; I. P! T  ~  R9 r  }    /* Peripheral clock enable */
* j2 L) H# N) c1 w+ Z0 O    __USART2_CLK_ENABLE();9 {, M7 Q% j+ \' x
  - C& ]. X- G3 _; e
    /**USART2 GPIO Configuration   6 z# ]6 B# q5 {& _2 {
    PA2     ------> USART2_TX
2 G( }, B4 [2 l3 t    PA3     ------> USART2_RX
* Y$ p: a1 c  f0 b8 o% K    */
4 E# f7 g4 W3 m4 K& P$ c    GPIO_InitStruct.Pin = GPIO_PIN_2;
( _: G1 J1 M' O$ k4 V    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
% _8 e8 M! o# d2 }% c: ]    GPIO_InitStruct.Pull = GPIO_NOPULL;
, f2 l9 x9 L7 ]7 c+ Y    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;$ F  k% c6 S+ t7 I* T
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;/ }& J+ z' I" l  _
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
1 p8 M/ y. _; f; S2 P7 ]! y  n/ m; _# n! D: h0 q
    GPIO_InitStruct.Pin = GPIO_PIN_3;% S7 g2 C4 u, W: O" g
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;- E/ W: t$ T2 m; l9 o# Q
    GPIO_InitStruct.Pull = GPIO_NOPULL;
( a. o3 `5 w% l2 i, P5 R: o    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
2 o# {) N" w) `( T8 m    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
# G9 N- }* }% y8 ^' C* w3 M    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- L1 q3 l  y9 j2 K; ^/ M0 K7 M0 k2 Z! M  Q2 H  o
    /* Peripheral DMA init*/
0 C, I+ R# q8 v' B8 R  0 c% S3 t& p& |6 [* L6 l0 `( m! C
    hdma_usart2_rx.Instance = DMA1_Channel5;- O8 y$ Y+ E( h1 d# j
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;. D; X. `6 w+ S6 [9 c# C* w) b+ n% D
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;4 N( n% ^$ W' D0 H' o' p* B
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;& s% g2 Z* a3 F9 Y+ |
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
$ ^& L* Q; ^% J/ S; Y6 I    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;, |. T! {' `5 i# L  \
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;( |5 R4 h& @( \  w
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
  x$ H7 P+ e7 e" K    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
, a6 s; c. e4 c" i9 L2 g0 |    HAL_DMA_Init(&hdma_usart2_rx);9 s( \! q+ F% _* q

) S2 J( \+ l% ]5 v6 t1 p    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
5 `" r) Z9 {* E( x; m) T, p; M: d3 N1 S
. L: Q0 i8 A0 L1 M+ a! i0 B    hdma_usart2_tx.Instance = DMA1_Channel4;5 X2 H. M2 v" m) c+ w
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
+ [3 G; p) n. d- F% o5 X* k    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
4 [/ R0 W! a& [& X    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;( \* [4 O4 J- k. C* H) p
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
- u" |- Z. ]" Z8 S    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
9 W) E( B. {4 Y2 k5 W3 ~+ u% j    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;  ^! L$ B8 @7 x# i* e" s6 L( n- F
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
& L6 Z: O  A6 x% |$ N' W& k1 H- z$ {    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
' \: [9 J0 ?5 q' ]    HAL_DMA_Init(&hdma_usart2_tx);
/ }# K" E+ q! J7 i! n
" \# M  v) F  f3 d, w    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
7 Q$ U, z- c9 ^( ~# s6 q( \  [+ j: N  I1 N6 _( e
  }5 o" Y) T2 A- N9 n+ \" `3 }6 R
}# N' g+ [* _  g) @$ N' `4 E: V# k
8 G) E' I. C7 ^% ^8 q
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
7 n8 G: N- A3 f/ l0 G{3 a) ]' D3 }/ d3 L! ?# X+ y

1 [9 y; ~( p% S/ f' F  if(huart->Instance==USART2)
3 ?' i+ i5 f7 @0 t4 R+ }  {  m6 o+ j, \- Z5 g8 S' C4 b
    /* Peripheral clock disable */
4 H" W0 C9 L4 q% x9 w    __USART2_CLK_DISABLE();4 n4 R& \" h) M  Y6 }8 D
  9 Y; x, A; f4 c5 I
    /**USART2 GPIO Configuration   
% z" d9 G6 H: J; W5 J    PA2     ------> USART2_TX
& j0 U1 \" U; {' n. G9 f" `    PA3     ------> USART2_RX# B; l) O2 a8 N; g3 W. D
    */! I$ k5 i  {! b, }
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);: Q( a7 \, I  @0 o

! |' V& T! P, P, c7 R+ K6 q7 @    /* Peripheral DMA DeInit*/+ t6 p) C1 ^; T) H
    HAL_DMA_DeInit(huart->hdmarx);
$ J+ ~2 l0 P( l4 b& M2 @    HAL_DMA_DeInit(huart->hdmatx);
" _! E/ h7 n: M7 V. V  }7 k' c9 w6 ]% X+ C' M: V, j$ n
}
8 Y( \! v' G& p5 S# j  z$ Z+ g: h------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ R& |- s7 h) A* d' Z$ G, E
mpu6050.c% X5 N& w5 r$ g2 n5 `
#include "stm32l0xx_hal.h"7 E5 n: A, F# m1 ?+ e* O
#include "MPU6050.h"+ |/ Q0 v* q2 T5 S) T& w8 M2 a3 O
" W9 S! W& A- U4 X3 t/ y0 p& {" r
//各坐标轴上静止偏差(重力,角速度)
0 D6 J- I% L: E8 s; r" Cint16_t offsetAccelX = -195;
5 X9 h0 L5 r* I  x! Q$ Pint16_t offsetAccelY = 560;7 y% V0 ~# I# z- d
int16_t offsetAccelZ = -169;
8 B! [1 n- _( v/ C
1 S5 s- L  a: }! U% Rint16_t offsetGyroX = 12;) a8 u2 A6 t* |7 B) J9 ]/ e
int16_t offsetGyroY = 33;7 W1 `, i1 F$ ~
int16_t offsetGyroZ = 4;2 }+ n* y, ~, @7 [
' _% L6 h6 m" j
extern I2C_HandleTypeDef hi2cx;
0 G! h! e; j+ i% Z% E- b# X, u2 Y  X/ z
//**************************************/ y. X4 o6 U  Q0 J
//向I2C设备写入一个字节数据  a1 K+ `, u( b% C" }6 u
//**************************************8 `6 j4 T8 |8 u3 a( @: c! a* o& s
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)  B8 U. X( [: T1 m5 n& l
{6 v2 ~  m6 U7 d. H. Y6 o" r; l, v
    uint8_t rxData[2] = {REG_Address,REG_data};
, p. B8 c' C6 E# U& [2 g    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
; }- S* p. E0 N! L    {, N' R& u+ S6 I/ |, O' V; }
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)9 e5 V! \6 E4 g) [; V! X
        {}
& E+ ~- v6 y3 [% C: }! S/ _; V7 i8 f    }% P+ L5 ^$ D; q0 r
}" N" p% m8 a3 L8 e
//**************************************& x, K! G4 y. e* r4 w, H
//从I2C设备读取一个字节数据
3 s" l* \' i1 U- m: @) f0 L//**************************************- C8 l8 B3 L  Q3 I5 L
uint8_t Single_ReadI2C(uint8_t REG_Address)
$ N' M: S1 l1 {! D5 v{1 o2 w9 C, W) m& R: N
    uint8_t REG_data;
4 S  x/ Q/ L5 s6 n3 |    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)8 o4 a2 X/ C+ i2 b! ^/ J2 }7 \
    {
* n3 F, F2 T, }6 e. L        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 n2 z% B2 s! \9 |
        {}# C" }- Q! d8 H) t9 A* b2 i, p4 z
    }
& I! v' K5 z0 I4 C6 @   
5 M% W) u3 R7 @% c% z) i    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)+ M' g& h9 T# @- P
    {
0 P6 f" b) R& B        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
1 M. ^2 C1 _( @  q5 S) \) i        {}+ ]# [( r. l6 ^7 H
    }
- g* e# d+ l0 a) t3 f    return REG_data;# X. U7 H; i2 r2 F9 p* U8 c7 I
}( x! p7 X$ D9 h$ f0 C
//**************************************+ h; d# m/ }! f7 O: Z  D
//初始化MPU6050% B- j! Y8 T) d6 P
//**************************************+ ]% ?9 c; C6 @1 u. l
void InitMPU6050()# W( _1 G, z  w* `$ G5 s3 ?
{
6 \% k8 h" X* u1 r6 o. J0 l    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态# y. L! K% f& `% d, O) q

* m1 e! B2 N: e7 m1 T( v+ k, S    Single_WriteI2C(SMPLRT_DIV, 0x07);
6 o  e# K% B' I' y: I0 \6 X! C+ U8 |( D6 w, N1 w6 `5 Z  F
    Single_WriteI2C(CONFIG, 0x06);! N; U7 I4 l. l2 u+ O* L$ |1 i" a% _

+ |, P) w9 s2 n! ~2 l    Single_WriteI2C(GYRO_CONFIG, 0x18);
* w. n/ T4 }1 N, {3 H1 d" r+ g8 j9 x% }" q. w- v
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
2 t8 i2 X/ e5 y/ |}
: _  {" v/ d8 c9 o2 @7 z* T//**************************************; Z2 L8 Y2 Q; M7 }
//合成数据. S: X& E1 S9 D( _4 k
//*************************************** q. }  ]. R$ f" J' D6 g3 s3 y
int16_t GetMPUOutValue(uint8_t REG_Address): s  [2 J! ?6 P* r. J
{/ n- u8 H: z1 s' ^! [* Y4 q
    int16_t result;. H) d1 r5 E/ I( U
    uint8_t H,L;0 E+ x( \3 `( |1 x
    H=Single_ReadI2C(REG_Address);# d# n# y, E# M8 P
    L=Single_ReadI2C(REG_Address+1);
# k5 j( H! T0 A. E: i    result = (H<<8)+L;5 ?/ d  I% s6 Z0 [% B
    return result;   //合成数据9 ?* T5 Z, s0 k: K$ G
}
. g7 M3 M4 F& r# s: J7 M8 n) R: {3 g( ]' Q( H* k) w
//**************************************7 ~& N7 q0 ~8 r; d
//取某一轴上的加速度数据
/ @. Y, K8 p+ R$ a  \/ R* k& v//**************************************4 X5 k$ L0 N7 F7 @9 n
int16_t GetAccelValue(char axis)+ [+ ^9 z  j/ j) F! I, C3 j* b
{3 v$ \: Y: {7 w1 O7 H
    int16_t result = 0;
% V* \( ]2 Q4 c2 Z    switch(axis)+ B/ X6 g! M. g' s; K* k/ `. G
    {
; ^6 p* d% w+ ?        case 'x':
  s' D9 G+ K; p( {4 M- X        case 'X':
+ F" X: `  l% T# G6 m) @, C        {
6 }  U) t! ?7 _" P            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
- }$ y  z& L: [$ K        }
. I4 l1 g: h4 D2 M# R7 [        break;
3 ~: ^  y5 r# ]" f        case 'y':# K/ f2 y  F- ]! _' G+ m: s  Q
        case 'Y':4 _; f+ f+ @2 p2 w' p$ r, w
        {
8 t! Z/ `" L" U% [. P5 g% Q# O& G            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
! Z2 v2 p  R9 n        }" h3 K5 Y/ L0 h; A
        break;* u8 m8 w' _9 `1 r) M, w
        case 'z':
1 z8 |0 o2 h# M/ G) C        case 'Z':
3 L3 P7 b2 h0 d* E% U9 z* r5 u        {
" N/ Z  V0 f" ]5 }" ~2 r            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
, a+ @0 v; V+ M9 y+ l& K9 ]* k        }& r  [; v2 Q6 t& C* h4 [
        break;( h# n7 M! w7 j% M0 o( w5 ]  e
    }$ T$ [, W, B$ C7 a
    return result;
8 d# }( R8 r; @}! C( y: \  e# [, F* Q+ L

; q! y* a5 ]/ p+ C& d: X" g//**************************************9 G# N8 {) A/ P2 H. c
//取某一轴上的角速度数据. h: t/ V/ R6 i* \& \7 Z
//**************************************
+ E8 H1 w4 y6 u; V8 a4 v( f. @3 ~int16_t GetGyroValue(char axis)8 h0 q% N3 ]7 R& s  d  m
{; [& Z) R7 b' E8 m# u% Y  N
    int16_t result = 0;
( ~7 w" R9 D& q, Z+ E    switch(axis)+ b! @& c0 _/ J
    {
  D" s* y- ?1 \8 n& V( ]. ~        case 'x':1 N" E8 q1 g4 S0 D0 U
        case 'X':
9 f  C* l9 q3 F! E        {0 q* s8 ^# f+ Y; I& `& R0 i
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;* O. C9 T  z( p7 {1 B. `. I
        }
& d$ X( n6 T. f; h        break;* C' O2 W7 A5 e( v! u; N& Q
        case 'y':; b: ~, p' f' h; q
        case 'Y':8 j& N# I5 b- n- F3 W
        {
* t3 {6 \/ ?" @2 c            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
( A& R* R, l) ~9 h; U5 ]        }- x+ P1 V7 f  O8 `
        break;8 j8 e& l, }9 n; z( k+ M- Q: s1 \" L
        case 'z':
! P: z$ P$ z" c: B& W4 r        case 'Z':& `$ ^4 }0 t; v3 U) `
        {
  E; x9 l) t5 P+ o6 t' E9 U0 m            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
$ \* K/ C! f# F4 O8 L8 c        }
) R# i. k6 d6 F  i; c7 Q        break;5 G, d  g3 K8 _3 g7 [
    }- {) P! q2 k0 |
    return result;
% g' B* W- D# Q! g}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
6 m* S% c4 E7 p* x{
1 N6 S; Q; e3 D8 _8 G- ]& i
. o3 O/ g8 Y' d1 N$ S' \( Q  /* USER CODE BEGIN 1 */9 k6 c$ p7 u6 m# H% w+ S

5 t5 n; F6 d4 o- ?  /* USER CODE END 1 */1 H$ _+ ~8 [, K7 x( j

$ B/ `& Y& B) q5 e2 n" o  D+ }' L  /* MCU Configuration----------------------------------------------------------*/
5 f! _% r1 c. N7 j$ ^" L* y" i2 L' z- q( c# L
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
: P' _% ^2 l" I# x* ^* }5 [: a  HAL_Init();
* D  F! l' d# C" b$ s. H' I( n/ P) Y! i2 z# I* G; V# j
  /* Configure the system clock */3 K7 a. K9 a0 F
  SystemClock_Config();; A, Y5 _  C+ D% q, V8 [/ \
6 S  W* T8 |  B( Q2 q' f! o* S
  /* System interrupt init*/
0 Q( ?3 ?8 b+ s+ ?  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
7 I) t# S" I4 V! E! b
. O- J1 g" p; G  /* Initialize all configured peripherals */7 n, g0 s8 S" @4 u
  MX_GPIO_Init();) N5 C6 P- h# s& y/ R; _6 f8 Q  B" A, f
  MX_DMA_Init();
1 @, {0 E0 o0 i* Z# [; a    MX_I2C1_Init();; w( g4 l* q0 q
    MX_TIM2_Init();
7 {/ \7 j, t" p/ D5 T( ^. i! I  MX_USART2_UART_Init();7 k7 j9 h; @' x: W' \0 d
    InitMPU6050();* b0 M0 Z0 \3 ~+ J0 y2 d
5 p" @# d+ E/ x- m3 `8 v( V
  /* USER CODE BEGIN 2 */
3 {$ q$ d  W; d* `* R' P    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);( Y% x+ q" P4 h2 Y' n% Q
    HAL_TIM_Base_Start_IT(&htim2);1 @! s% f9 m+ G3 G2 E) l0 E% n
  /* USER CODE END 2 */
% H/ i7 g( j  k1 y  h9 M
5 }) f# o5 F! v# U# X  /* USER CODE BEGIN 3 */" R$ @, e) _  z  H& {
  /* Infinite loop */
. H& a; k8 w5 k. g: L  while (1)
4 [, ~% j2 {7 a+ E( V  {
& q  @% t( H3 b: m        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);2 B" B# W4 h+ h* z% I
        VisualScopeAngleOutput();
3 `2 Y/ O  Z. S0 ~        HAL_Delay(100);
' D! c1 I  N8 u1 e. _9 d  }$ B7 Q: }5 d7 b  }- Q
  /* USER CODE END 3 */
+ f. h& Z2 q2 ?( C+ w# r/ ~+ N. e2 j# i6 W+ u& q$ J0 @& O* C* p' ^
}
- a; o. P" v8 B* x) N( m- \( [+ U& U
4 Y- J& c  @: `! U/** System Clock Configuration; I1 b+ X: K7 p
*/
/ M6 ]* L' m5 L5 _+ b! j0 Cvoid SystemClock_Config(void)
, a9 t. p7 j- T& a' f& \{
/ Z. d2 K3 t' r! O
) a0 J, ?; w. l8 p( m  RCC_ClkInitTypeDef RCC_ClkInitStruct;
3 M1 R' K, j# m* Q, F, n# y( J  RCC_PeriphCLKInitTypeDef PeriphClkInit;
' C0 _; v; R; t% q8 Z4 d  RCC_OscInitTypeDef RCC_OscInitStruct;( e" [6 M3 G+ G) k
' ^1 a& e* A. a
  __PWR_CLK_ENABLE();
) ^$ T) J: x4 _8 {  ?' e# G
1 p6 }. x& q6 Q3 d; J- V  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
0 Z: ^$ W  S9 M" V6 W
0 c& e3 ?+ I9 e; p  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
' F( ~$ S% ^& T3 t  RCC_OscInitStruct.HSIState = RCC_HSI_ON;6 E  R2 Y5 X; _" N; ~
  RCC_OscInitStruct.HSICalibrationValue = 16;
: s! ?8 _2 ~  Y2 a  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;% `; [4 B: [# e3 B$ Y
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;9 z0 |4 G8 o4 L, k7 k
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
! Q  J% w/ N0 I2 q8 m9 M- g1 f1 J  h  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;1 q' g# V. u. Z, e8 a& T
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
/ {; m/ U* z/ n4 {, L8 X! ^' Q( ~( V& H& ~& w. O
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;2 r; O2 [( a- e9 }& c7 G
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;( W: j3 E/ I8 ~3 W# R" P
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;7 ~9 U3 k& c. n0 I# G$ l
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;6 M# W7 a+ f% k) x5 T- q# z
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
# c' u+ ^8 O9 n/ Y  J8 {  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);1 {. k# C  t, p  x7 h

9 q3 m7 Q6 y- o, B; Q% V5 ~0 T  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;0 {0 k& M! z# s' I1 O5 b+ R$ Y
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
/ p1 ^6 o. B. B! b  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
6 W2 @! S6 x7 Y( f( I6 C% A# u. j6 R2 i1 i; y- G- W8 s' ~
  __SYSCFG_CLK_ENABLE();8 t; |" f+ C9 F' ~
: a7 K/ @5 j  J) s4 ~% S" |
}# @- Z5 I$ D7 @# r
( }/ Q% Y1 |# O* v% I
/* USER CODE BEGIN 4 */* w* B/ E2 z' m0 a: c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
& Q6 }  X9 x- `$ ^2 r{
: o' s0 U' G2 n8 H6 o    if(huart->Instance == USART2)
5 H( N& d! G8 {$ L6 S* T1 f5 q& S    {
9 @$ H/ }. f: x        memcpy(txBuffer,rxBuffer,RXSIZE);
: \9 F, U$ \& y- ^. }        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);$ f3 e4 M3 a7 v3 |% i& J
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
+ S* ~7 h; j: B# m( G9 i    }/ f: ?* O5 h) c0 w3 Z# @1 M
}; o1 [- G& t: S' a( s0 D- b+ `9 g. M0 I

) P1 q/ w( ^7 A* ?8 a. |3 j, Qvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
' v! B$ P3 ~7 A( v7 i& N{
" d7 z) r2 a5 \* V% M4 }$ C6 L9 z   & H6 a7 A8 S# o- l; Q. s0 F4 F
}
5 _& {5 U% `) f# c( i& L6 s7 `' G; O7 G! I( S0 f- a6 Z% H# G* m3 u
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
" h9 S7 W' ?2 w, r' c4 k# j{
7 G0 e3 `, \7 R6 R    int32_t GyroValue;
7 q! I' g4 e5 z2 J   
% q0 G9 T7 P" d; c3 U. G7 r" X    Calc_AngleAccel();
* q4 J0 [4 f  X# g1 O    GyroValue = Calc_AngleGyro();$ L( [9 v, g+ A  j3 T3 E
    ComplementFilter(GyroValue);1 l, d/ h* p: Y/ {& ^) K( |7 m& R
}
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:001 b: ?8 p5 c! E; ~. y4 a& J
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
  Q/ M7 v) E9 l+ Y% s' f
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00+ L0 ?; j# p& G3 ^3 D( ^4 e
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

5 E5 B4 t$ J0 _2 g7 p$ W$ X" c如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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:216 q6 [% o2 E( a. g
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
; l1 {# Y- Q2 W0 ~
好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?" L5 V' a; H# d  N
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
0 y0 [* S/ r; D4 ~楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
  V3 ^% t: k4 R3 g" T请问应该注意什么地 ...
# E8 h# c8 Q; w/ G9 @6 [
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版