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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:& n- d' z3 H& j  J  P3 G
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------$ i% Z8 v- d7 |+ [
main.c2 c" V7 Q$ Q/ X# }: f  Z$ z  {
#include "stm32l0xx_hal.h"6 X) o1 Z/ ~; T3 F" S* a
#include "dma.h"+ B8 n( s1 F8 z6 Q
#include "i2c.h"
3 L3 z) F1 }) h0 w#include "tim.h"
% T. b* H) `+ G: ]4 ^& z' `#include "usart.h"
0 R- _' E7 H6 I* M# u; |' q#include "gpio.h"( _+ t) D9 l, O+ q" S3 O; G
#include "mpu6050.h"
9 i$ K8 P- J# H, c. J#include "visualscope.h"
" ^7 A/ O$ {# L0 W1 W, i% j2 z# [/ ^: R( Q  a2 L5 P+ ^
#include <string.h>
  i, n- q) q. A" N' p( [2 @7 A#include <math.h>. n& N/ i1 t! z6 j5 D" Y, E3 G

+ a# o/ w& z! m1 q/* Private variables ---------------------------------------------------------*/
: F! D- v3 o5 Y#define RXSIZE 8, {/ g5 [" }$ \  M+ r1 f1 e6 d
#define TXSIZE 8( a3 v0 I4 G2 H% ?" K+ E" m
uint8_t rxBuffer[RXSIZE];$ A; b& A2 d7 z. ?% U
uint8_t txBuffer[TXSIZE];' k8 @' n% p9 t" S' P
- S/ a5 ~$ X; O/ ~1 Q1 {6 ?9 P; a
float Angle_accel = 0;
# @5 Q8 E, e- `! H4 Qfloat Angle_gyro = 0;
/ u% F) k3 A+ H6 a: m  N3 O6 Z  f% Gfloat Angle_comp = 0;) O6 e/ G% W/ F
uint8_t outAngleData[10];
; D/ Y+ r( i7 ^2 {) e3 ?/* USER CODE BEGIN 0 */
  [, T$ b8 Y- W5 y- U# D# s' l
: f9 [' k/ \6 Y; P5 k' K8 w/*---------------------------------------------------------------------------------------------------------*/
3 n/ L6 j7 R) E! w, v/*  重力加速度算出的角度                                                                                       */
7 T6 Z. r5 o2 \& w) O/*---------------------------------------------------------------------------------------------------------*// x0 F- n6 C8 E1 ?
int32_t Calc_AngleAccel(). [* a  @* k  b' S! O& _  O
{
# E( i  r2 y* N    int32_t value = 0;
/ ~% E+ g. g( ?    / h" j+ V: L" j' o1 e
    value = GetAccelValue('x');
) g; X. K8 v" L) B- h    if(value > 16384)
3 D" E7 R7 V5 i) [: x        Angle_accel = -(asin(1) * 180 / 3.1415296);/ k' B7 l  _) C$ V9 M# h
    else
0 k3 f7 e6 q# P$ D        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);( d6 W  q% a/ \- W% I
    & Y  S" l# T$ h
    return value;
; G# W% `& {' r' j7 C* s, |}+ H8 k" V8 `( x) G8 C9 P$ ^
3 u# x0 W6 R) o% x: c! A
/*---------------------------------------------------------------------------------------------------------*/
* U4 |5 `' V4 Z/*   角速度算出来的角度(积分)                                                                                     */
1 B4 c" H2 A2 J8 H) R. g/*---------------------------------------------------------------------------------------------------------*/& v$ [# g1 C: H' `
int32_t Calc_AngleGyro()
# H4 e$ z4 T% f# Z8 x{
3 [' k% V) t# {" t% ]) T    int32_t value = 0;) i9 w% T" i3 K, t

' H1 ?4 a8 y1 B    value = GetGyroValue('y');# {; y( P2 `" V. @$ B* P& E
    Angle_gyro += (value / 16.384 * 0.01);
& _2 [' s" `5 x$ b    0 \7 f& P/ s2 t
    return value;
2 X# p8 U* [3 K7 }7 X  b- m}
4 V+ O) ^9 T! v* M: s. v1 `& Z* Z2 [
/*---------------------------------------------------------------------------------------------------------*/
' u8 K) Z. M: c' {( ]$ }/*   互补滤波求角度                                                                                     */
, E# }3 E% y! R% {/*---------------------------------------------------------------------------------------------------------*/9 M: e* L/ v; l0 R! g
float ComplementFilter(int32_t simpleGyro)1 ]5 e0 B9 C  o/ ~0 g/ N9 a4 \+ ~7 [
{
7 I+ Z/ @# [, G# y; [* @9 _    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
2 O" p( q/ a8 W( m6 E0 R   
; u' H- s8 {" `7 s1 c: f    return Angle_comp;
& h( X/ ^  b4 @. _) r) X}! N& m% Y5 y7 T! \
' `6 z' T+ X! m) z: N, k1 z+ R" d7 T
/*---------------------------------------------------------------------------------------------------------*/
/ W4 @* m. p5 R* _/*   输出角度至上位机                                                                                     */
; V+ I, Q1 l( k2 c( j; ]: h/*---------------------------------------------------------------------------------------------------------*/$ k4 c0 h8 N7 J# `$ j
void VisualScopeAngleOutput()
7 v6 e& p  J5 z8 a; o8 i% R- j{1 s9 [, J- K3 Q0 j- F3 x
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;
1 L0 I% K0 e9 e6 r  g    uint16_t crcValue;
  K# r6 f& o+ t$ P: s   
3 R/ d4 M1 H. A! F. \9 d2 p! P    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
& H6 G# E/ Z5 f$ K3 U, ]    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
, W3 v" v! y0 r3 J    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);. ?, r  T& ^- m( t5 w) f  D4 x8 g8 N# u
    , m0 m/ h& U- d- j. y
    outAngleData[0] = AngleValue_Accel & 0xFF;
3 q! K# x# K- m( ~    outAngleData[1] = AngleValue_Accel >> 8;
+ {* \9 }/ q6 u$ c1 y( `    outAngleData[2] = AngleValue_Gyro & 0xFF;, j' \" T4 W" O9 ]
    outAngleData[3] = AngleValue_Gyro >> 8;
1 E' _* e! w+ U3 }+ C    outAngleData[4] = AngleValue_Comp & 0xFF;
8 Y& q5 Z7 r* O    outAngleData[5] = AngleValue_Comp >> 8;
+ a9 |# D+ \: J. R    //计算CRC
1 {$ Q& W- B8 S, V0 v; [: i    crcValue =  CRC_CHECK(outAngleData,8);: ]) a) T5 ]8 B! L. `6 l
    outAngleData[8] = crcValue & 0xFF;4 I: |8 P: I" m6 |4 `
    outAngleData[9] = crcValue >> 8;
, y4 k% u& E* H    //发送至上位机0 i; e- H1 p% u$ }: T9 T9 _% f
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
% u8 Y/ m) x3 ?2 W- t) C}
& a: F$ ^5 o' u  n/* USER CODE END 0 */
6 j# U% ~, H% S& P( i- ^* P7 x( _8 G- @
/* Private function prototypes -----------------------------------------------*/( o$ x7 @7 j& h! A% U& T
void SystemClock_Config(void);
0 c" r( p' Z2 H; o/ x9 h: {5 C" k* ^3 F
3 p: u6 ^& K0 \8 E. [3 i' ^3 }; q
硬件连接图:
  a" h' L: v6 j/ m 1.jpg
) N# _! y9 B% V. B波形图:  ~6 X& c$ \& T
2.jpg
% o$ Q& z% j( y5 k( ]: X$ I最后加一个视频:7 a  d9 I# E3 @% I) E4 O
STM32L053 演示
" F8 e9 h2 T; S! T# L' K: x' I
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C' B7 h$ T' z* r# P" j2 F, ?
#include "i2c.h"
  z2 c: e7 K; g- X
( M! u6 s" ^* l3 M% j2 E* ~#include "gpio.h"
1 D. R( r4 K9 K
* [" ]7 d, p4 k/ i! A9 c/* USER CODE BEGIN 0 */% H4 r) Y+ i+ r: x
% Z( P0 m: L- S1 ~* X
/* USER CODE END 0 */' r5 {# I( W. e7 r! B6 [
6 K/ p! F; J6 Q+ Y/ o. ]/ m
I2C_HandleTypeDef hi2cx;
+ f! d6 h: O1 R* k: T! x6 ~( ?7 T. u, M4 U% E( S! S
/* I2C1 init function */
: G3 J7 ?8 a4 ~' g8 Fvoid MX_I2C1_Init(void)
0 C5 ^8 i: \! v. B3 W2 d{
& y; E# A8 Z8 E% ^0 W: s$ Z1 J# c$ E# Y
  hi2cx.Instance = I2C1;* \" T1 h/ ?1 T3 z0 V2 V  T
  hi2cx.Init.Timing = 0x20D22930;
, D' W- }4 A0 O- W  hi2cx.Init.OwnAddress1 = 0;
  @5 J5 Q1 n  ]: b0 {: ?; J  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;+ g, s+ p, _( W6 I- G. S. H
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;5 Z# t, m' r, z" V0 [) \
  hi2cx.Init.OwnAddress2 = 0;
! r: G, n2 ]+ ?  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
2 f/ H. A. [/ n  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
3 O+ q6 n9 ^+ J: k) d# T  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;, D3 l6 m$ V& Q7 y6 K2 L6 x
  HAL_I2C_Init(&hi2cx);
+ F- e& k3 t6 e+ t: b
. e' |1 n, C/ d) l( @* D    /**Configure Analogue filter, k  ?- Z6 h/ K2 n* Q# ?( R7 X
    */
5 ~/ X# B* h" W+ @# x( \7 ?  H  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
/ @1 u" w: p3 O* g
( r9 R0 l. q0 M7 z}
; w& I" i- X( l* @
- ~+ s5 q. O, ^; H" q, }void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)7 ^% ^3 A$ I  i- {' k
{5 I, ~8 F0 D; c+ C# p5 Q
8 Y& b- Y0 U* ?' s6 p
  GPIO_InitTypeDef GPIO_InitStruct;
  a2 M( Z, V1 s' k  if(hi2c->Instance==I2C1). g! {( |0 u$ I* t, Y8 O& O/ J
  {
( C( w9 o4 C8 d4 F  Q  X. ?. u, D    /* Peripheral clock enable */
& S2 r, V- ]9 J3 @. u    __I2C1_CLK_ENABLE();
, H6 l$ T, T* T/ x) d  3 f( W2 s" ]4 d% m) F. I3 q
    /**I2C1 GPIO Configuration   
1 y6 ^; \9 x- x/ z" [1 R+ P% h* ^    PB6     ------> I2C1_SCL
% o  d. _. l7 ^$ L, J: G# J. j    PB7     ------> I2C1_SDA! T' c% s5 @( w( u9 l& w
    */; D8 G, S/ j* c3 w/ ^9 Z3 s- r! x# M
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
& }% a+ K) G$ Q3 a, H5 ]    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;* ]" k6 F  E8 U5 L- t4 A# m, l
    GPIO_InitStruct.Pull = GPIO_NOPULL;
- w7 K- Q# G: c- c    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
8 `) P  y" ~) n8 s3 F! }/ ^2 c    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;+ e/ `) C7 m8 k) J# }& ]0 B
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);$ k. ]! T/ b4 W" t* ?) H" }
0 z* F% v7 ~( o$ @  }
  }% W4 \6 L* u! g; ^% y3 [8 R. C" h8 p
}
7 [  S% W) ]+ {3 N4 y3 v. S! q+ S4 p% q: a7 e% c! q0 o! Y# z
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
3 d  d8 ~3 \+ U  x- z9 f{3 B6 n/ n$ `, _% h8 l: V

/ Q; }3 O" |7 ?: P" ?  if(hi2c->Instance==I2C1)
  S, H4 s# r; G/ N, A  {
2 _5 F  F' h" _2 X6 c& A    /* Peripheral clock disable */* s" j- L' M* p" x1 y( w
    __I2C1_CLK_DISABLE();" v; Q( z5 W3 z4 l# _! B$ v
  ) @& i/ X9 G) `8 A8 {' @
    /**I2C1 GPIO Configuration   * n" F* g- z: l' o, p( [* t
    PB6     ------> I2C1_SCL8 v6 ^3 G4 s% P2 f! g* M2 T
    PB7     ------> I2C1_SDA1 U. O% g, r# F$ u& c0 D* ^! H
    */' g  t0 \. H8 ]* T5 f# N
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);% u- |' e8 n0 B! f0 s% a9 Y

1 d6 a! f! }4 L; c9 v  }
! S0 T8 W: m: W# I  k/ F}9 [0 z* d, N) O: V; |. _8 W% Z
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
! _5 W$ c2 ?$ c3 Pusart.c2 @) Q( X/ P' C7 _* R
#include "usart.h"
& E: L' C( \6 J- q) K
  H" F( c' e, T+ b0 X#include "gpio.h"
) q' A8 j: P% U6 N4 Z0 l#include "dma.h"/ T/ j* E; C. V6 J# L
. ~& K3 u* o9 e5 {5 k, c
/* USER CODE BEGIN 0 */4 t9 e/ ^9 j' F9 I& \

% ~3 b* U+ V# q6 Q! l2 k/* USER CODE END 0 */- z8 \; U7 ~& S. I& L

/ n: a& J* K- e  n! FUART_HandleTypeDef huart2;3 r1 z8 x4 f7 A$ P- Z' N; _7 d
DMA_HandleTypeDef hdma_usart2_rx;
, e2 P) g* u1 J- K* Q# V) SDMA_HandleTypeDef hdma_usart2_tx;* [5 q- T( b! i
) Z' |) x0 R1 y$ ~- j* x
/* USART2 init function */
5 K) g0 U0 D5 F9 l) o; z& z/ g: D
void MX_USART2_UART_Init(void)
- q: Q$ C! I6 x1 R{
; J: b5 m4 M$ j; C3 P; F0 k# g
, `- z' H& T; M! r; F. \) N; O  huart2.Instance = USART2;5 |/ Z" x3 Z, G% W
  huart2.Init.BaudRate = 9600;8 K, G0 t' H. W- ?
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
1 y' `( F8 ]* M1 s% a  huart2.Init.StopBits = UART_STOPBITS_1;
% J% Y% S6 m* ~' Z  huart2.Init.Parity = UART_PARITY_NONE;
- _; l9 B; Y0 L; k; E7 l1 U  huart2.Init.Mode = UART_MODE_TX_RX;
* `" M0 y! Q: n$ K- q. f* p: h  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;  A6 c0 Z- P4 d% Y( w/ e7 `
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;6 S; t7 X7 _* Q& i/ ~$ B* t- g
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
( a( A3 ?6 [' {2 x6 ~: E  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
1 ^7 v1 V) Y! b, p7 B  HAL_UART_Init(&huart2);
! M) x! ]1 ?8 K
% J; \+ L) F6 ^8 Y/ [}
3 K, \( C' h* D0 `' E+ r; F3 T
  P6 I" C2 U# O! c! n5 u* w( Nvoid HAL_UART_MspInit(UART_HandleTypeDef* huart)
. V# |8 J) J# L8 v* ^{
5 I# r  r' ]9 e3 F/ L2 p8 v8 w6 a" o; u9 ~) ]
  GPIO_InitTypeDef GPIO_InitStruct;
" _* Y5 W& u4 k( S  if(huart->Instance==USART2). [" t3 ^  h: M3 q: r' ^; w
  {1 T/ M# W5 w6 a) {+ |
    /* Peripheral clock enable */
2 q4 p$ A8 W' G+ b$ \    __USART2_CLK_ENABLE();3 n9 H) F3 f7 n9 L: b
  ! q2 T! P( O$ D/ m) T2 a
    /**USART2 GPIO Configuration   5 s4 q$ B  k( N
    PA2     ------> USART2_TX" Z+ ^9 v" t0 F2 _! ^6 I
    PA3     ------> USART2_RX
2 [/ l% }1 E! }9 q! A& G    */
' E& y" i* j+ W- g+ {; I, |) I    GPIO_InitStruct.Pin = GPIO_PIN_2;) S3 {2 y2 D% W) L$ b( p
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  \' r+ @- P: D6 @4 e4 V
    GPIO_InitStruct.Pull = GPIO_NOPULL;7 j; x! [: l9 W+ w
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;* ^. P. j* v9 W9 u
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;2 b9 Q  U. l2 t/ m! k5 N+ L+ Z
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);: ^) G* U' q+ P1 U; u3 _+ s

$ z% s  T$ m! Z# v  X    GPIO_InitStruct.Pin = GPIO_PIN_3;2 U0 x! r5 U/ v
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
5 V8 p0 n' l: @; u2 w6 J4 `    GPIO_InitStruct.Pull = GPIO_NOPULL;3 X4 C) S. Z! h- M' @! b* O
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;8 N9 Z5 c* P, Q  p
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;% ?, ]& J1 f0 G5 d7 w9 `
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);6 b1 q8 e# O$ `

/ h: M. b5 \$ f8 G    /* Peripheral DMA init*/
5 m! x, ]% I: h- Q* T" h1 `  
0 k# [& b9 c4 z) W. L5 R6 a+ V    hdma_usart2_rx.Instance = DMA1_Channel5;& Z% q* W+ ~! O
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
6 [" N# J  R) m" a/ @    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  \! ]: t+ M7 \0 c: Y    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;& u: e2 J- d. |/ x
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;& P7 o# G6 t. N! O6 D8 N1 ?+ l
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;% Z5 @- e, n' z' B* m/ {2 m
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;6 u3 u: k! P4 B/ W9 a4 t
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;* X' s; N& c# g6 q
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
. \, _) p# C8 B+ ^5 l    HAL_DMA_Init(&hdma_usart2_rx);
4 [, M, F' b- Q& x* k. j  z$ {7 B
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);9 b& i' K& D8 E6 d! k( @

/ Q3 C% m  i5 Y2 h    hdma_usart2_tx.Instance = DMA1_Channel4;+ z2 r( T. C7 V/ Y, s1 O" \/ V
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
* s1 o  b0 H3 P6 c+ m    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
" I, p  n! R* ^# |    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
% y! N! M- l+ Z    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
1 x. q& \4 s0 Z( ~3 a- f    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;5 E4 a' E' k' q( l$ ?, q
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
) p$ C/ B5 \* B0 L    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
# q+ ?0 E2 y' ]! U' [* f    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
4 @8 r% m) Y# a% w  n  d" n: Y. a    HAL_DMA_Init(&hdma_usart2_tx);3 G( C. G$ V; J  s$ ~% U. S7 `

3 D$ x6 c+ d& ~, o( F1 F% {    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
9 O; k( ~2 v: G1 K1 V
4 l, L$ ?( D8 h& ~) K  }  P; ]4 V! ~; X- n+ @
}
& ]' D7 `; P) U
6 r, }# Y5 H& pvoid HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
# e1 R5 p; I2 J' `. \3 ?$ F{$ t# S( e4 }/ d2 ?5 T6 `* {1 L

1 M- ]  [  q8 T2 K0 a0 Y  if(huart->Instance==USART2)
# {( }% ^% E* b, ~4 Z& d) a4 z) W  {
! T. V8 ]6 j8 F% J) o! I8 _    /* Peripheral clock disable */& U+ H# l7 u! h1 a; M
    __USART2_CLK_DISABLE();4 _2 A8 n; B7 K) G, w! j
  
  b4 Z- u! \2 y; _7 ^8 _    /**USART2 GPIO Configuration   ( O3 p' o- o7 o9 P& C7 \# f& |
    PA2     ------> USART2_TX+ ?  T) B4 q4 ~; S! q
    PA3     ------> USART2_RX
' g1 {# b6 }5 S% c    */- J2 V2 @% m0 [) ~+ I% `
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);( [( C; H( T& q

+ [3 T" f# m4 p' M% z+ p; N    /* Peripheral DMA DeInit*/
  {. A; n3 Q: O4 }# W( O    HAL_DMA_DeInit(huart->hdmarx);
6 W8 r5 c! I2 H1 {8 o    HAL_DMA_DeInit(huart->hdmatx);
) h" e3 r, k# x  }
3 g, ?1 d$ y2 ^# J3 F9 j% L}; i6 u3 K9 B# U0 g
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
+ [4 d) G# E3 D9 k/ z3 J7 empu6050.c2 e0 ]( O% ?& c- M. k7 _9 ?
#include "stm32l0xx_hal.h"
% C( |8 d0 ]/ K#include "MPU6050.h"
% N# l/ o* O3 v1 O3 F. W4 ^5 W% E- R
! U& v$ E& n. h; F" E% N//各坐标轴上静止偏差(重力,角速度)  j8 m! i% b, n$ h
int16_t offsetAccelX = -195;
) R1 E% y4 k2 m' ~5 {$ [int16_t offsetAccelY = 560;
$ u! o# P5 v* z9 Aint16_t offsetAccelZ = -169;' t; Y" b+ d3 S$ _
8 C7 T! y( L4 U& A3 b6 s. ~/ S! z
int16_t offsetGyroX = 12;
1 j" c/ e. m! R0 Y* q+ \7 ]int16_t offsetGyroY = 33;# G- W0 i. s- C" ^- g
int16_t offsetGyroZ = 4;* q8 p! e; C3 e" S; a7 b" b
8 T  @( c. S& \" I: ]  |
extern I2C_HandleTypeDef hi2cx;2 F; `8 F! `! @. e2 }$ @  Z
5 O! P% M0 X7 Q
//**************************************
+ F+ F6 W- Q' N1 W* s/ @//向I2C设备写入一个字节数据" G  ^3 a& f% x& \) V0 I% b8 g8 N& r, v
//**************************************! f7 u/ [# @& E/ I. {) M
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)/ \/ G) S- @& f% p- m! k3 [
{3 i2 P2 P' [! E# p
    uint8_t rxData[2] = {REG_Address,REG_data};3 j& V6 F* m/ Y' W. e3 V; |
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)+ ~; N! u. \& q" N8 t  s0 \
    {. C. {" Z0 f# [% u
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
3 d6 t: I& _, m/ A        {}
: d2 l/ j, c0 Y; |3 ], ^+ H    }
& c( S& l  d1 [* d' X0 s$ G}
0 |& w  k2 U1 Q//**************************************) p1 P% Z/ s2 x+ n
//从I2C设备读取一个字节数据4 b. f3 m0 E& U% h3 K
//**************************************
* U! P  p" i+ d% P' Z' i! e. cuint8_t Single_ReadI2C(uint8_t REG_Address)2 a/ @3 R  _9 E, }
{! T+ p9 }4 t& v( i
    uint8_t REG_data;
- S: s6 R( e/ M. C1 z    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
1 Y) A' ?6 C7 |+ ~7 b9 d* s: e    {$ d  D2 p3 C/ F, V8 C
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
' ?: U5 I+ x8 m* e        {}5 u( X  v8 ^: f7 ^9 N( o/ {) M% {
    }  N# \: }/ E; G5 a, b7 p
   % D9 _9 W& g: K6 N
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
$ Q5 m" v% t7 I2 f; \    {; j! {! K3 C8 `( m; Y5 t
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
; v* p8 U; N5 g- U5 e5 E- a' ]        {}# V% i* ?4 ~) ^. Y8 d' _' ~; W
    }
& A3 |0 q* G! C  M! v    return REG_data;
" y7 p3 k: Q9 j) G}) S0 \3 O- b2 ]# @+ q
//**************************************
! ?$ N. V8 `7 s# q: A& K//初始化MPU6050
) }4 h6 X) x# z8 W//**************************************% G/ y8 d; Q7 P! \4 n3 n* L
void InitMPU6050()9 M7 r4 X/ ]) m. f
{
! z9 e. Q* ^$ V/ s    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态9 t4 d. C6 |$ D2 |( g0 i* b0 j
5 n) t6 X- ~1 |. b* M! b$ K) O
    Single_WriteI2C(SMPLRT_DIV, 0x07);. C# F: @# s2 ?" L* v: `

# g- e  M& Y, K# R2 a6 j    Single_WriteI2C(CONFIG, 0x06);
! g" `- s8 _% l  H; S, Z: V$ h& h7 I$ n2 h& B
    Single_WriteI2C(GYRO_CONFIG, 0x18);1 f* y% Q5 B$ n# F
# j5 ?) A, r6 V( }2 m8 n/ M; d
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
* q: h0 D) Z# f; _- F}
: I+ S* a7 T/ j7 [& o' U//**************************************# Q) r) y, ^4 r( \8 S& K
//合成数据
0 s' @" |3 r$ t) f* y3 ?//**************************************7 L  a! _8 {7 D: y4 f  F
int16_t GetMPUOutValue(uint8_t REG_Address)4 l" v, `5 J6 h
{
# `1 z. I2 c: _    int16_t result;# d" _/ C3 a: J+ `5 Q. I) j
    uint8_t H,L;
$ Y* e4 D% C% O! x) T2 K    H=Single_ReadI2C(REG_Address);
- K( h8 L  `2 \    L=Single_ReadI2C(REG_Address+1);
* b6 f) J& K1 W' {# {6 j+ `  J2 y2 D9 D    result = (H<<8)+L;. ]3 q% P' ^( @9 b% {+ n
    return result;   //合成数据
4 }* N$ S/ ?$ |: ~}8 J' ]3 G$ M5 E
. ~. U+ R1 C5 Q# q& V
//**************************************% H9 `2 h5 z6 k9 a# Z& G6 d
//取某一轴上的加速度数据: M, E1 p( |, u+ M% ]
//**************************************
; |# v$ d8 r0 Mint16_t GetAccelValue(char axis)
4 ?& T3 U, O. j{' D9 _3 |- u5 b
    int16_t result = 0;, z( z0 I/ `6 y1 U
    switch(axis)) ^* C- ]0 O5 o6 a8 B- E
    {8 {: ^6 f% D- |( Z( x  Q
        case 'x':
. E5 G7 X; l! o0 j4 e: W! p        case 'X':( D: _! `. |( G. V
        {
3 y. P2 Q  V8 N3 B4 ]+ Q2 ~            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
1 M3 r! n0 G0 d4 s, a- w        }
7 m, C6 w7 N6 t+ c0 [        break;/ [9 s# K9 U6 }. I% J
        case 'y':5 e6 T- N) T  \5 q. A
        case 'Y':
" D9 U+ f+ k0 J0 s5 x5 C# o( g        {: `) u6 c- H- g3 F$ y- ^+ r) W
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;& F- }# Q  L; t; |
        }$ l, q8 ?; l! }. B
        break;4 n4 c3 ]5 J0 c- c1 v, s( A- ^: c
        case 'z':
$ ~) s* G) e( r, U. x        case 'Z':
. n+ V1 ~8 A2 I  K# f        {
" X' k( B5 s/ R& t( ?- y9 b            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;. }2 g3 G8 Y. Z3 p
        }
! y1 X0 A8 B6 _        break;
; ~  `& U; U" L( Z    }! C2 A, I% H& L# [  u0 b
    return result;$ `( O" @1 z% u/ S( v2 v( }  }
}5 V# s, i& S) ]7 [1 Y' i  d1 m+ v$ Y
! O$ G" O  Q, v3 k+ ]
//**************************************
" |$ B/ \7 j! b4 ~+ P1 a//取某一轴上的角速度数据
/ y2 |1 C+ ~* x9 L* K) }//**************************************
: s! l) u1 o, s  oint16_t GetGyroValue(char axis)
6 \, z* s/ H2 r: e{
1 N( l1 C9 W. j1 i* V$ m    int16_t result = 0;
0 m- \: z/ r: e3 l( x  [  j    switch(axis)& C; a7 x' v6 C% _* v) h
    {
, d! D4 ^9 m. _9 C9 d5 m: p        case 'x':$ l( r. W7 d7 R! ~; O
        case 'X':( i, d* q; z- J; x  f
        {2 Z0 T' G0 L- {9 P9 A4 F- S# t7 Y
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;+ N% M& z/ j# E6 x9 e
        }& n/ D! B2 k2 T$ l$ ?* j$ T
        break;8 u* D- [$ w/ ]  k0 h( H
        case 'y':) X7 n9 O( j& r6 ]/ B9 t
        case 'Y':: c- J4 @0 p' m( p
        {
: `  F7 |+ [( T- m4 ]            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
' }4 n$ ^' c8 L3 i' U4 X: f  f        }1 }0 R( o" A) b
        break;. w: U( O' A, ?7 s: M
        case 'z':
5 ~$ O2 Q! X5 i        case 'Z':) ^7 w( R& ?0 w' b6 D" N
        {
- U% M% e: [" u' {5 U* A" y- O            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
# x4 Z- c/ F! o6 U( M. t6 s+ D        }5 x) Q$ ~  c, Z5 V2 ~
        break;
0 w: P! e) C+ |  P' s7 }    }
1 h* N  ~: c' |    return result;
7 b6 D' m# }8 a8 _& r. D}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)9 N& Q7 I) i, C( N: a4 ^6 l
{
2 ]* Z$ @3 v+ W. O/ l1 N5 c
  B, f; Y3 X5 O. e  /* USER CODE BEGIN 1 */
% Q: E5 `( g( E3 M& D; F; k* W% y9 Z
  /* USER CODE END 1 */% T- U- t, L* [3 R7 Y

* U& D1 X( j+ z  /* MCU Configuration----------------------------------------------------------*/* A& N8 q9 T  ^  A2 M* U: S0 p2 P2 |

4 z2 Y, q  Q" E' y, W  l  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
6 j# G$ a, w+ r+ V  HAL_Init();
4 |9 h' R3 _. h( D# `4 z+ H( ]
; B9 C: n  s7 G3 L1 ]7 [9 g  /* Configure the system clock */
; [2 [4 A+ i2 s; I2 K0 m) z& i  SystemClock_Config();
. m* q5 p2 T2 u: _$ r2 Y4 m$ U
9 G0 R) e4 I# u$ ]4 m. n+ ~  /* System interrupt init*/
5 d- t6 O4 x2 `, c8 Q  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
# F- v( |# _! h8 `/ Z- j* d( Z9 b7 p3 c5 i- h) i- n
  /* Initialize all configured peripherals *// k  @- L- t3 M( _
  MX_GPIO_Init();' B6 ^8 V8 Q7 ^. P7 O
  MX_DMA_Init();
$ W# U- Q  i( h    MX_I2C1_Init();$ O& J- `! _9 l8 ]! M4 Z4 l% {
    MX_TIM2_Init();
5 P& m! L7 K/ a& G  MX_USART2_UART_Init();+ {: A! e# D& P* Y
    InitMPU6050();
) h+ X  B9 D( n6 c6 T! S* f6 y( M" J5 h
  /* USER CODE BEGIN 2 */
' a) I5 \. ]1 t  u( |  d# c* f  N    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);+ k: h! b3 t# z
    HAL_TIM_Base_Start_IT(&htim2);6 q$ J" F5 c+ V5 X& J
  /* USER CODE END 2 */
4 t2 H! W+ c* g
1 {* ~, H$ l5 U8 n1 R  /* USER CODE BEGIN 3 */* L0 m7 L1 i  o+ k" e+ c
  /* Infinite loop */1 n; ^7 v; q+ ?& b
  while (1)- B% j/ K8 j2 s# a/ o1 |# }8 A1 H, Y
  {9 {- F; i9 e$ D9 v2 L6 ^; k4 M
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
& \& n+ t. G6 B+ S6 L: o' D) ^! Y, S        VisualScopeAngleOutput();
) T8 b  v4 H) @( m7 O2 C% E& I        HAL_Delay(100);9 u- L- U3 u" E. `+ I: Y8 Y" K$ i
  }
$ e8 o8 B& o. \2 E  /* USER CODE END 3 *// o# ^' L+ ]; B
+ V  p5 G) K0 r
}6 j* X+ l6 W* d3 }8 X2 K
& ?( |0 `. I* x+ y* o" n* {' o
/** System Clock Configuration' U7 {) s/ a7 X, S2 A. O6 ]
*/( B5 k& B, j* Z+ A. |9 K5 B
void SystemClock_Config(void)$ j+ T$ v$ J4 y8 A& ], M8 C# p$ e
{! }6 Q$ _. \2 f5 f3 n

8 `; Z# S6 s( X3 P  RCC_ClkInitTypeDef RCC_ClkInitStruct;: d6 U+ |, G0 ?3 M; G& v6 i7 t
  RCC_PeriphCLKInitTypeDef PeriphClkInit;7 |% b7 E7 v2 O. y4 W& n4 R8 m
  RCC_OscInitTypeDef RCC_OscInitStruct;
+ C/ L6 Z# f2 \3 K
6 I5 a7 M- J9 q& Y8 f  __PWR_CLK_ENABLE();
5 i# @- F$ ^! r1 {, Y0 l1 x, {) g" ?0 v! O: d
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
. Q7 W$ q; J  ~
# g  l* b' h: X$ K  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
& I6 \/ l' b3 Q) w* {! \1 h  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
* r# ?+ E" q+ ]3 h  O, q# v  RCC_OscInitStruct.HSICalibrationValue = 16;
- e: `9 \" f, j: y* ^6 e$ ~  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;; |3 J+ X/ K' a5 Z7 D/ g+ O
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;! O' u+ [% Y6 Y
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;2 e6 A+ d" P( z% _: N: h( M0 X
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;- _, C5 x* y$ O, {3 }4 _! H
  HAL_RCC_OscConfig(&RCC_OscInitStruct);  x$ y9 s8 U. R( a. u

0 k$ @/ ?! b: r& I- V! `3 y& g, H& [  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;; v: q9 z. j9 ^( f2 ], v4 `1 u
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
; y) l' r$ ?2 K. h/ S  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
5 o( z( L" h( T6 H* U, p/ U" }  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;/ k1 F  q( e9 G% v
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
* u+ `1 t3 P& N; g0 m+ {  l  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
. r9 ]  k. \- K5 F6 C8 A! u
) D* K& Y' y% d2 K& q( ~9 f  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
* D1 F! H' R* X$ t: X8 s: G  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;& B9 _3 U6 _; \$ f( L* E7 P
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);7 Z  _8 e+ ~1 C  a5 _8 A9 f0 L

2 _3 S' h9 d" {! i; F. l. ?  __SYSCFG_CLK_ENABLE();
! l  p$ Y+ O5 B1 K* m  T/ x0 O  b; x  g$ d
}+ ?& b" B  W# E. `6 X
9 }/ x* ?9 C7 i) Z. D
/* USER CODE BEGIN 4 */9 c6 z1 Z) m) H& y+ N+ R
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
6 }  ~! H" A- W$ P- m{
& W6 K( b2 p9 h7 p+ H    if(huart->Instance == USART2)* h  n7 b6 c! C" y  z# l' K( V
    {
8 G' ?. h7 l4 ^6 e' ]0 S5 a        memcpy(txBuffer,rxBuffer,RXSIZE);
$ C/ J  }8 N8 C! s) g  C        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);- x; B/ t4 x. B3 `! s4 N
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
% B: s1 z9 G) x6 x$ N3 M    }
) v! v. X; |$ K+ [% r3 l}
* n$ z/ D! ]" a$ V5 a; d( U9 N$ ]6 w& ~: \
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)+ p. A4 _- u9 M2 e
{$ S4 U/ l( d. F: U: ?; r5 }8 n" b
   
6 |, [" W8 p6 {1 X0 u}5 D, E, [& t. l' y4 `2 I8 q( @

- ?0 R1 a0 @; {( W+ K! K& [void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
% k. C! V! U8 n: m% Z/ R{  P- L8 {3 X/ I4 D* O3 U/ v9 r
    int32_t GyroValue;' g3 L% k( x, t* m* }2 V' O) Q
   ' Q$ I' s7 P# A+ R9 a+ m3 {
    Calc_AngleAccel();6 y" h1 y, \: U9 S7 F) G) x
    GyroValue = Calc_AngleGyro();
" |- {% y- d" G1 Z) P$ f" g    ComplementFilter(GyroValue);) A& X, g) ^: j7 k) X
}
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:008 k! ]4 [3 I$ k# m) b1 D
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
0 g  ^4 e. P( ~( T4 Q  Q
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
; R: Z0 g) R' {楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
6 H: Y' D, Q& j, f2 x' @/ X2 H
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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:211 ^6 e( C0 M. R! t( B6 [2 j& D
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

; V( L, ^' V7 }& Y* c0 B好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?3 H* P5 c  Q. K1 u, n9 l3 J
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08) \% i7 }! U* X
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?# [2 K" g& R, }; Q
请问应该注意什么地 ...
* C8 X( h$ g  _' }: _# y
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版