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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
8 z4 y) R9 V3 B-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
7 X, T0 I6 ?' G6 M0 N& Hmain.c
* {0 O% N+ b! t5 \+ j#include "stm32l0xx_hal.h"
: d7 G6 k( S$ D2 R! R0 m#include "dma.h"
; D4 T* |) k6 M1 H( l, A#include "i2c.h"+ M$ q8 [' I- H2 q1 u
#include "tim.h"
) _+ E: a2 r: |8 L/ c% f" S7 Z#include "usart.h"
) ~, y, P) Q) d6 M#include "gpio.h"
, K( Y* ]* g* u6 b#include "mpu6050.h"
% m% X% t' N7 Y- p' X* y#include "visualscope.h"
9 p- u; m' e, h0 c  r# w1 N0 D8 E: }: k1 ~3 x
#include <string.h>& F0 g9 _5 U3 o% u
#include <math.h>! b) t$ X& u: a; [, A4 }

: T/ c2 j' L& Y& t3 {6 u/* Private variables ---------------------------------------------------------*/) \, U, ]6 E. u$ N9 B
#define RXSIZE 8: l7 h; q; ~3 M& ~* L2 `3 m: ~9 I
#define TXSIZE 8
% w  G0 R$ C0 e8 Luint8_t rxBuffer[RXSIZE];  F& N  q- a- F$ e; J; r
uint8_t txBuffer[TXSIZE];, s, Q9 [) A& V4 o( h5 T+ q+ m
0 @* v; [# p$ B6 H  B6 t
float Angle_accel = 0;2 Z" {, @3 x2 i+ n$ D/ |# \* P+ z
float Angle_gyro = 0;
# Y( _% g6 U9 e6 C$ Lfloat Angle_comp = 0;
( f5 b  j& g& b. huint8_t outAngleData[10];
$ l. F% |: [$ l/ M9 P/* USER CODE BEGIN 0 */
! P, P2 Y' c# K- q" H2 H. j: ]1 {* ?" P, O% Q& ~, h. j/ O
/*---------------------------------------------------------------------------------------------------------*/
* e- X" C4 I9 J3 I( Y8 f/*  重力加速度算出的角度                                                                                       */
* h1 h) w4 P& T/*---------------------------------------------------------------------------------------------------------*/
7 E, @3 g0 {0 R/ I" L+ Eint32_t Calc_AngleAccel()) g8 }- y7 L' @" j# f
{% l- r( K: A6 [5 D" f$ k
    int32_t value = 0;
3 Y6 |1 V/ l- o" S& ^- V" c' c# _4 Q    % F7 W% O/ q; W! [6 r* B4 V+ @
    value = GetAccelValue('x');, T& n' ^9 Y, t4 t
    if(value > 16384)
8 I) o) {5 A$ y. l2 c, m# U        Angle_accel = -(asin(1) * 180 / 3.1415296);' j7 I: |+ M! _+ A+ T2 g" P
    else
2 ]4 y2 ~' j; v/ b/ [        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
# `) J+ m7 T$ f9 N% H: B( B    % ]5 p! W4 N' ?6 y& B2 V5 r6 y
    return value;3 b1 z; `9 H  B" ^
}
9 Z: i# T" Q  ~. m& M1 \, c! E) [- k' t. }- G
/*---------------------------------------------------------------------------------------------------------*/( a3 p& w; ~+ M
/*   角速度算出来的角度(积分)                                                                                     */
1 L6 t( O1 a2 b, Y/*---------------------------------------------------------------------------------------------------------*/! h8 A) |) a; P3 c$ ~0 s" o9 {$ H3 J
int32_t Calc_AngleGyro()7 g5 L. h( S/ c. w1 z
{) I& T# }+ D* s% O; V
    int32_t value = 0;
0 D5 G, ]' P/ \0 `* V8 e5 v; F& H* {, m' e: k
    value = GetGyroValue('y');
. H* [+ w. K. k+ H  b" h    Angle_gyro += (value / 16.384 * 0.01);
3 x4 U/ _$ l6 s$ ^    : |! A6 g* O1 h5 T) a! U3 x
    return value;
2 W( P- ~. W4 G2 X}
( v0 u' e6 n5 B$ ~0 g" t- o3 g/ E% W" p- X+ d" y& t
/*---------------------------------------------------------------------------------------------------------*/( v- f! J' `0 v8 x% n. x$ ^
/*   互补滤波求角度                                                                                     */; X/ N" W0 S4 b' T' y3 |
/*---------------------------------------------------------------------------------------------------------*/
* p/ ~( [; |' A, g/ gfloat ComplementFilter(int32_t simpleGyro)" g% V  t- l: T
{
) W. O0 f8 D7 K3 a- D. |    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
4 }) n) a. H' t' B  H   
$ o! D1 G4 Q& t, e8 w0 |7 Z% g    return Angle_comp;
$ ~% M# t$ M8 F/ v0 U& A}) B8 W8 c+ a+ Y  ]' B8 W4 `
$ q( I/ R8 t; N* g+ I! y& }8 k
/*---------------------------------------------------------------------------------------------------------*/
% O' f( s! g+ `+ }; p" g/*   输出角度至上位机                                                                                     */
1 p! x# s- n1 j) g1 z/ c/*---------------------------------------------------------------------------------------------------------*/
& z% f9 R4 k) u* \4 _void VisualScopeAngleOutput()
. i4 q! Q( M/ ~{
7 g' P; G. {9 N0 W8 @) K    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;$ A6 q; R" q2 t3 T# g
    uint16_t crcValue;. O6 c' O% H$ Y  ^% q3 N) C; E
    # B; W2 E) u( s& X  @3 _
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);* C$ S9 z7 ^8 x4 {3 z
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
" x. m& w: B5 I7 j& Z' M    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);& b+ {- y$ l# e. v  l) S
    9 P# p8 c+ U3 [$ \% }8 i
    outAngleData[0] = AngleValue_Accel & 0xFF;8 u* I5 U: K8 B
    outAngleData[1] = AngleValue_Accel >> 8;7 a* L9 B5 t8 D9 T- j
    outAngleData[2] = AngleValue_Gyro & 0xFF;  i4 K: A! K% ]& j& f+ \4 }8 x
    outAngleData[3] = AngleValue_Gyro >> 8;5 d9 N% ?# N& {8 g4 L* ^
    outAngleData[4] = AngleValue_Comp & 0xFF;
% ~% l; [. n8 i    outAngleData[5] = AngleValue_Comp >> 8;
0 N) O% `- H' K% f( K2 e8 ]    //计算CRC4 o* z# L* e+ B3 z" e
    crcValue =  CRC_CHECK(outAngleData,8);
/ T. O" f; {; ]9 ]' Q; H+ k0 Y6 p    outAngleData[8] = crcValue & 0xFF;
2 B5 ?1 `: v9 a! F) b' V    outAngleData[9] = crcValue >> 8;4 w7 V/ M2 l2 S3 X" b
    //发送至上位机9 }. h* k0 Y6 h$ k9 L# i, u
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));* X) K1 T+ E5 b# e& }7 R
}: k# {2 D0 |0 `* b* ^5 d# P
/* USER CODE END 0 */
$ r5 F; s) V2 p5 }; o$ {3 o
- u0 N$ A- R4 i: i2 e6 T+ `/* Private function prototypes -----------------------------------------------*/
: J2 V! U, G/ O3 [! I1 B! Xvoid SystemClock_Config(void);; D9 O) k) I6 m" c. s9 l; Q
2 p$ Q' r4 x7 y" L+ D

- k. T- R0 d" F) c& B) E' ^2 m9 t' a硬件连接图:
0 }) b& ?! ^" D/ Y6 k 1.jpg
6 V2 N( H8 A7 b波形图:
# |7 b- Q1 `  | 2.jpg 7 h* [# C1 i. s' a5 y
最后加一个视频:
, l1 x6 b8 i- Y2 f/ u; |8 eSTM32L053 演示  U. U3 s3 _; j8 q& e5 e
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
% I1 R: e, H7 r% a" |#include "i2c.h"5 X. k  Z) v1 A, Q, y* ]5 }( b

8 J4 D* }/ G5 H; ~#include "gpio.h"
0 K* i( O* b% c$ B& P2 W3 i( \) `% p4 t% B. x8 u$ c# ?
/* USER CODE BEGIN 0 */
" ]3 {4 U* C& G$ Y  P5 t; k, ~$ z5 S% N3 Y# u
/* USER CODE END 0 */
- U" R3 a5 W* d+ z" x, T
  C  H9 p  i- l  V: ]I2C_HandleTypeDef hi2cx;
* A- ]% @+ |7 z# ]- N5 i. q) R+ H7 _8 D/ E5 o
/* I2C1 init function *// `+ ^+ R- W1 o% n, U% Q1 s3 A9 b6 O
void MX_I2C1_Init(void)+ v, V0 l6 l' G6 V5 f
{+ z4 F; i  p, |* Y" X7 {7 ?
  I- E1 d0 }' [9 M$ _% l
  hi2cx.Instance = I2C1;
0 H5 e: j. d1 e+ U# c! y( f  hi2cx.Init.Timing = 0x20D22930;
5 C1 K9 s) d9 ?. N* g& j  hi2cx.Init.OwnAddress1 = 0;  H/ d% j3 |2 Y' u( i- e
  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;# Q% A$ ~5 m5 l, h$ m4 s' ~- F$ c, }
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;, u6 @2 _1 X6 P! \
  hi2cx.Init.OwnAddress2 = 0;0 o% t; y3 V+ Z& C" d4 L/ M7 p
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
. ^. o- Y( H5 e4 s# D  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;" d5 c: a6 z, W$ U
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;8 p# K" ?- Y8 _! T2 a% ]
  HAL_I2C_Init(&hi2cx);
6 v; D# v& t1 t1 j7 f/ @6 J" k1 G! i0 ?+ Q4 j: G
    /**Configure Analogue filter
- k  \2 M2 u( C1 O3 S4 u2 W    */$ p2 J& i2 ^3 [5 y6 |  I% o
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);7 t' f1 W3 Y8 D9 d
5 V. t& Y' ~  Z3 S$ N7 L. N2 J* k
}- J8 K, o. b* |$ v& h- x/ _# o% Q

* A. t7 j3 J4 S! b6 Dvoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)$ b9 y0 G1 O- @: H+ H% R
{- {6 t3 w9 R" m% H! D0 I8 |
" \8 H  T( X" p8 e. ~- E' ?* B
  GPIO_InitTypeDef GPIO_InitStruct;3 |0 g( F4 `4 t; S+ |8 f
  if(hi2c->Instance==I2C1)
" k4 Q9 a/ y8 w  {- P( I; _" I9 j
    /* Peripheral clock enable */
2 `7 P7 f3 p# U" P, R6 }    __I2C1_CLK_ENABLE();7 g( d$ h' U, [" f
  
! g) u' e* t4 i& [% w' k; `    /**I2C1 GPIO Configuration   % u' v$ ~) X7 s: @3 P( v
    PB6     ------> I2C1_SCL2 ]$ ?* Q5 P3 |0 y. g2 k: |* V
    PB7     ------> I2C1_SDA. j. v7 _0 o. g% D$ p2 R! y
    */
% W! `! Q% `& i/ M; c    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;2 D( n* _, l( c" Y  h
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;8 O& M/ b2 U5 J2 F5 N# @& y
    GPIO_InitStruct.Pull = GPIO_NOPULL;
. T# o; t/ B; Q    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
1 i2 a1 X$ e) c  |    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
; u/ E5 j7 B+ D    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
* U6 c4 i$ Z5 i4 @+ n, G) {
* ]( x  q& N! O8 A2 ]  }
- g, z9 g6 h: J1 V1 A! Z6 N}- m5 ]* w; B) B* c. z

/ U% o& O6 i% T/ zvoid HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
6 p. t1 T  D) N$ x$ Y{
$ D+ e4 b9 ]; C- I) H  O+ O. V. l" o! l( [3 Y
  if(hi2c->Instance==I2C1)( |+ w& i1 d2 a+ E) V0 B7 L
  {
9 m' e7 |0 I" l# q1 [    /* Peripheral clock disable */( P8 H8 A) M8 l/ d2 {
    __I2C1_CLK_DISABLE();
) ^, X0 D' Z* |% k' c' [  
% p" [4 ~4 P+ |4 S4 ?6 M9 Z% @    /**I2C1 GPIO Configuration   
  T6 C: v7 T2 J4 M1 D9 C    PB6     ------> I2C1_SCL' j  C0 ~: p  p& ~) o' a8 ?& Y
    PB7     ------> I2C1_SDA% A/ w, ]& j+ j- U
    */
' H/ E+ h2 e% j+ c( b8 S    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
( ~1 K7 o+ c& g4 W" d& R$ D: I- ~. z0 h  N, _
  }
% X, K6 q4 X# y5 ]}
2 x& S# S4 h& a* v& q1 k& |------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------3 n) ]( \& O, b. t- g
usart.c  T0 S" Z9 x4 W  S
#include "usart.h"& S, U: _% n! x1 l+ J8 h# w( ]

- C! l: R5 p* [5 i/ \9 s#include "gpio.h"1 D+ w5 B. C: p4 F
#include "dma.h"* a/ H9 A! _2 |! ]% \6 z9 }
$ {4 P/ ]4 q! u) G  G
/* USER CODE BEGIN 0 */
- Z& j) E# A8 u1 s
1 w7 o" c2 o- P+ m/* USER CODE END 0 */
6 `$ S# r  A; f/ O! j0 Y4 G" q" [  d* Z  `
UART_HandleTypeDef huart2;: p9 G/ ^2 j& {/ I  e( h- h& d
DMA_HandleTypeDef hdma_usart2_rx;+ \! D' ?- Z6 ^" c
DMA_HandleTypeDef hdma_usart2_tx;1 \! q  a, w4 b1 S% ^1 X8 J
0 |  p1 H& Y1 n* V4 o! ^3 a* ]
/* USART2 init function */+ S) q+ h: }- q8 Q7 b8 U

9 T8 @. L; M1 \6 {: s: J  n( Lvoid MX_USART2_UART_Init(void)
$ T  B8 \2 p5 q{
7 W0 Q/ L) x' W
1 L5 Z1 m5 b8 u  b+ C: ]" l6 J; Z) m  huart2.Instance = USART2;+ l6 P6 R( K2 \$ P" u4 ^" G
  huart2.Init.BaudRate = 9600;8 ^$ A) V$ ^* U! s. R/ r5 i
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
, D& }4 \# ^. X  huart2.Init.StopBits = UART_STOPBITS_1;9 T/ T# I& J$ w* k0 e
  huart2.Init.Parity = UART_PARITY_NONE;
3 x5 `0 i$ y$ L" u' y  _  huart2.Init.Mode = UART_MODE_TX_RX;4 a- r( M) G1 X# b6 e
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;* j6 z( k" P& L3 l  b8 Y, P* k8 f
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
4 A7 U! e" k: w' [  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;( n' m+ v6 L4 c( p6 B& O; Y0 U
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
5 e: Y; Z' [' ?7 q; i  HAL_UART_Init(&huart2);
/ S% X( x% E& J& R' U8 |7 q& O% C3 V( m) A0 `
}% o/ L' r" S5 L" N* t. o- X. U/ U

! e) O& K6 `& p; \0 u  avoid HAL_UART_MspInit(UART_HandleTypeDef* huart)8 L: X6 t6 _* n: m" O: C" ]
{& C3 @/ A% n% ?( R
& S" o% a4 P. l( b
  GPIO_InitTypeDef GPIO_InitStruct;
8 v+ h$ E$ I; I* a  if(huart->Instance==USART2)
7 q. l5 u  P  F; B$ Q6 u  {; Y* c+ h+ Q9 J% N1 B5 u1 I) w* ?- {3 u
    /* Peripheral clock enable */
- E5 c  W- J! G: e/ ]+ q' H+ m    __USART2_CLK_ENABLE();8 m- S" y- \$ T: g* H* x
  . N8 n8 o- W' P+ i! }" ^
    /**USART2 GPIO Configuration   ( o: Y; e" V3 L, T# b4 }
    PA2     ------> USART2_TX2 Y  A# ?, X" ?3 c+ X4 ~
    PA3     ------> USART2_RX
0 A, \# g3 \) F' H    */
+ I' F; ~& w" B; U    GPIO_InitStruct.Pin = GPIO_PIN_2;- k' l+ q) D) @
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;/ C  q" U* M/ [# W* L$ @  \$ M
    GPIO_InitStruct.Pull = GPIO_NOPULL;
& l* p( Z  P5 g, F1 k3 c2 ~- ?6 t    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;( W# R" d) X# i9 I$ m
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
6 ^2 j4 g* L1 A9 ]    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
# x% p& ^0 ]! w6 e% o
5 Y& W6 f4 f( V. I    GPIO_InitStruct.Pin = GPIO_PIN_3;( Q- t, q% J) d  u  ^# C
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;2 W6 }7 l! e; O4 `
    GPIO_InitStruct.Pull = GPIO_NOPULL;
6 ^. n' i1 `/ e    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;8 ~& a4 H$ A, c
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;, G/ |6 \5 K9 S4 g
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);+ `& _+ e+ G4 w! x
" U! o6 u- o5 y
    /* Peripheral DMA init*// S( x7 f( l% }/ H8 x
  
* R8 t# Y1 H! o) Z" }    hdma_usart2_rx.Instance = DMA1_Channel5;1 o, Q/ q! e1 s& J9 ?! ~
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;3 G) P5 ^! r5 w7 o/ y+ |$ E" U2 L
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
( V6 m& e; C4 V4 V; n9 l0 Y/ }    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
0 Y4 Q, f2 T4 l$ {8 y2 A, H  U* l    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;5 t8 K  @" E6 |% _! X7 B
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;: a8 _, c8 N* ^7 }+ }  E6 r5 ]/ Z
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;0 v  I& V$ f' f; T; n. D) x
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;- M' ^1 t1 S1 J. w, U2 [) F
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
/ [0 `) T$ Z* r5 W6 {    HAL_DMA_Init(&hdma_usart2_rx);5 q. a  \& D8 W4 b
0 r# c& M: k6 ]9 B$ x8 ]& x
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: d: x: Q1 h, V/ b1 O" U; b" Q' ]

* J4 }2 o' |9 M# g9 z    hdma_usart2_tx.Instance = DMA1_Channel4;4 k, `9 o! Z/ H, ?) a. e2 _, T
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;6 B6 Y0 g( k+ @$ q* t$ d
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
. H1 ]' m! A- `( `3 j6 B& A    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;# _( I* L( \! ^  X1 J
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
/ v6 v8 |5 |, I( }2 ~+ d2 o+ ?5 @# Q    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;5 J0 K+ Q9 Y% s: }" Q( P
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- }: P; A8 M( o* Z8 |8 W1 }6 l
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
0 S  P8 v0 }, o& v) x% e    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
+ G) |4 Y- Q) H' P& m    HAL_DMA_Init(&hdma_usart2_tx);, `0 {6 p9 Z0 v/ T5 M& X5 t0 X
2 T) C& U$ H  Z
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);1 a8 r$ E0 h$ o' B- Z
# x- l2 y* Y: x
  }
; C% U1 Q# `  ]- D( X}
$ t) B$ G; F+ M, n7 N9 N! i, F# q4 V7 M: H3 r, X9 n6 E
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
( L) y# t8 \5 i{. R# l% I( _+ _

. }2 B5 I! ?* w; c; X9 Z  if(huart->Instance==USART2)
+ D; C9 H+ \1 R5 G. |6 Z- ?& y  {
+ C7 X: q' `1 A( E    /* Peripheral clock disable */5 m4 U5 l  Z. g! e$ ]
    __USART2_CLK_DISABLE();
( O% R- T! \8 B" \0 u# K" V- G  4 P# T4 u' n2 n
    /**USART2 GPIO Configuration   
( _/ i3 o: R6 ^    PA2     ------> USART2_TX
" P. q: Q" n+ P9 Z/ {  t9 e  ^    PA3     ------> USART2_RX& R& v/ A- y7 w: @$ [
    */4 ]. h4 T3 o7 m# @1 \; X
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);  S0 |! z( |+ J7 T5 I1 ?; N
( z, s( p; z4 w  o1 X$ ~
    /* Peripheral DMA DeInit*/
1 z5 b9 v: M+ k    HAL_DMA_DeInit(huart->hdmarx);. Q: g7 M2 \/ B" P
    HAL_DMA_DeInit(huart->hdmatx);
) F- H! D0 z; V' k) P: R% H  }. L6 J% Z: {4 W
}5 }/ `% v) |7 l1 R/ M
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------& r6 d7 k6 {7 T) S; E& J, B
mpu6050.c% Y6 }& @* M1 @8 y5 h8 H
#include "stm32l0xx_hal.h"
# \' d+ A+ ?6 c3 e) Y#include "MPU6050.h"
0 O! x7 C0 ]8 I7 q) O
' g( z6 F9 H' h3 A$ ]. Q//各坐标轴上静止偏差(重力,角速度)
1 b5 A3 o" ]9 p" fint16_t offsetAccelX = -195;2 `, F8 K/ e8 R% ~. @8 p
int16_t offsetAccelY = 560;
5 O+ f5 G2 [$ L* k) T& S; o- vint16_t offsetAccelZ = -169;
% b9 |" ~8 j9 h0 h& s4 ?0 v4 n7 J0 p. V
int16_t offsetGyroX = 12;
, E" B( ^2 r; `5 w% ?" f7 aint16_t offsetGyroY = 33;
4 E- G) C& K9 n2 rint16_t offsetGyroZ = 4;9 c2 H+ h1 t- T9 a6 `
+ D3 J6 N/ x/ x# u" A- o
extern I2C_HandleTypeDef hi2cx;
7 ]1 B1 s4 x0 T5 r6 O3 r
" k+ L  n- m6 ~% H* r1 N//**************************************6 R- E0 z$ m1 g) o" Z
//向I2C设备写入一个字节数据
, b( K4 `. z: m: t' o! r6 M: L3 W9 q//**************************************
, _6 b: N1 [* T- ]% Wvoid Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
, k2 |7 P* t7 D; t7 U{
& Z; [' v3 J5 a6 P, V5 j% i6 j    uint8_t rxData[2] = {REG_Address,REG_data};
: W7 \# x' b! e$ B9 p    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)  F8 q' W9 W4 ^( M
    {
6 H1 ^4 k; [' M7 ~* W5 s( p* |        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
" F! D  f( G- X$ _9 V* l0 A        {}- F/ ?2 _( C% ~7 d6 A$ s" \9 H
    }
+ Z) L0 A  {+ K9 h4 }0 \1 `}2 `  G5 V, ?' m. g" Q/ W
//**************************************
/ l9 t: G% O( C* l+ i, s- \+ N$ V//从I2C设备读取一个字节数据% j* U& k; g- h
//**************************************7 \7 r5 r! Z( Y: A0 f$ Q
uint8_t Single_ReadI2C(uint8_t REG_Address)' _2 Q. v# q1 J8 p) ]
{  b0 p+ N. O/ N. O, ?( H8 C5 @
    uint8_t REG_data;
1 R# v; G! {; u/ o    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
+ b! Q4 Q* J( w1 s* K5 u    {
0 @& Q9 D$ _) B        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)% g5 q+ ^" W+ N' D( U- M! l( P
        {}
2 M* _- P3 G: L1 |2 Q    }
) G7 Q; p& d/ n' n( F2 \  S   
8 p" L4 W/ \/ v    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)" z0 ~1 w. Q4 k& d% J4 p# a
    {% k) J( O" D4 {5 X" l
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 n0 P6 O9 B% g
        {}
1 D0 i" U2 H5 m; B' h9 a    }
/ [  o/ P# C5 K: K    return REG_data;
0 P/ G" V, D) Z( D3 K}0 ^0 k# q9 q- C% y! H% ^
//**************************************& B/ S0 O  E7 @- z
//初始化MPU6050
& u) {& k. r: P" X+ Z& @4 f+ s//**************************************6 u5 m/ l7 Y- l
void InitMPU6050()
2 J1 J( ]  h9 H3 u+ [. [{
7 }0 Y2 p9 U8 O0 O8 j, a    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态/ K' K8 C& a/ U- s! r

8 {" R& a* i7 q7 t2 a1 I' F0 z    Single_WriteI2C(SMPLRT_DIV, 0x07);; @0 d  F7 X2 M( |1 @; Q

+ R* V: u8 {- ^2 I$ F( F5 L4 H    Single_WriteI2C(CONFIG, 0x06);1 p+ }( J4 D$ _; D4 r8 g

  r- V) E  d9 N4 b7 N& N    Single_WriteI2C(GYRO_CONFIG, 0x18);
" l# `: j  n+ ~6 \- R  H, t/ N- b8 _+ h  Z0 U
    Single_WriteI2C(ACCEL_CONFIG, 0x01);+ Q7 O, D& z8 L9 L& y8 g
}
9 K5 r/ ~( Q; G. i# L+ v//**************************************) o+ H: \+ X( e2 K$ H: P. v
//合成数据( K& y. O7 D  a% u! b( K8 a
//**************************************
: |: L: L/ y; ^int16_t GetMPUOutValue(uint8_t REG_Address)
; v$ w7 W2 {7 H; O  b" ]; w{7 A/ d4 _: A9 X
    int16_t result;* U# }# q: X: i' u; n
    uint8_t H,L;- g. X9 L+ Z% ^* H& W8 b
    H=Single_ReadI2C(REG_Address);0 F1 @. }" V1 ^6 t( x# p4 y2 A
    L=Single_ReadI2C(REG_Address+1);
8 `6 V& R2 X9 f% S0 O: c  f9 l    result = (H<<8)+L;
% g$ j( a! \4 e    return result;   //合成数据' [4 N/ }8 ^, B$ e* U" @3 v2 n
}
0 _, r* w. o+ S  w
. B8 k! ?4 ~. K//**************************************) c$ `8 j& _6 Y6 H0 D  j3 D8 m
//取某一轴上的加速度数据9 l+ b% D. o( k" X- N7 Z, ?
//**************************************
& S7 t* |; b# M/ L; Fint16_t GetAccelValue(char axis)1 {, n: `: R. t6 g2 p; W
{
3 S" g$ J1 n. o5 D1 ]    int16_t result = 0;
# Q. m, W; J0 Q( G9 D7 E) s    switch(axis)
% K" c. b0 t% I    {
' Z" [" Q# E( B6 q/ `        case 'x':+ V3 e( M0 A* J8 L. x6 O0 W' y
        case 'X':. W  u$ ]% H# o3 @9 \8 n8 c
        {) w! `! z! W' ^( R. {! h( p2 {
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
7 w" j3 `& K) z) u        }/ ?9 S" x4 h! e
        break;
# Y- M) H9 U) R& E6 l6 e  r  t' R3 d        case 'y':
9 a+ ], e2 O7 @' p- Q9 E, G9 n        case 'Y':2 Z& n9 E$ p+ t8 d  r
        {8 v& Y) H2 f! W8 i
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
) h* T! a1 @4 ~* r: l        }/ N- D* L: q  x! c
        break;/ s: ?* _7 J+ T6 o
        case 'z':, B  I' ]  [. U8 ?
        case 'Z':9 B/ b  f- V1 [8 I
        {
( i  @+ U) U% P( y; T- ~            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
5 Q1 s2 X$ C  i% h: q# B. [        }' e$ x2 V2 g* ~/ T% u
        break;
: \) G) @* C! c    }
# k6 P* o; |( T2 @" N    return result;
, a+ H" L6 I$ X2 E" |8 k}3 w3 }9 P9 c. B$ R" I# R" N7 w

+ C& b) w8 P) G6 w' }% b% o  U  v//**************************************8 s2 S, c% D7 Z# i
//取某一轴上的角速度数据0 U) G2 q+ |7 N& ?
//**************************************3 p7 b) j$ ]. C( U6 _/ @! E' ]2 p
int16_t GetGyroValue(char axis)) E( ^, u! d' o
{* L. H2 E- g6 c* ~3 v" v' K& m
    int16_t result = 0;) X. n* |  l4 b6 {( m
    switch(axis)
$ O" n  c2 u5 t/ ~    {8 v3 m6 c; j5 {4 P
        case 'x':
. W- X- |; f! Y. L' l3 F        case 'X':
) X  x" Z5 r1 N9 s# C! J& O- o        {
$ g/ {4 [3 D3 \  v            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;2 B" E3 ]6 b/ V6 g/ E( y/ r" G! d
        }4 k0 C7 ^, E' C: H4 f& @. V, [, I0 `. ?
        break;9 o" j& m+ I' N# `( n
        case 'y':2 a; c% m. \  r5 Y9 m; D6 u3 Y
        case 'Y':6 m" R: F2 m- y. x; c5 a% ]  s
        {$ y& P, I! {) }. P# D; K' c
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;0 Y7 I" d3 z' X! e3 u3 I
        }1 I, }; e. h; p% t4 d6 ]9 g* O
        break;  J7 s& C# [* s' U# ?
        case 'z':0 |+ {1 m- ^6 v$ z/ v4 ]
        case 'Z':  D% _2 x2 \- B1 r* U  s+ l
        {  l  y$ w! D* j: K1 W6 s" V+ o  @
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
8 K8 Q- ?2 ]7 |& j' F        }- {* P( ~/ C0 h: y9 S% \. i
        break;' P( w' A" d% p0 B6 d2 s6 N) I; o
    }3 h* y( x5 z. m2 P9 n: n& B
    return result;( L2 _. ~: N2 b& s
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
- R" c5 a8 o( U6 V/ x0 N{6 I) K: B% c9 U

5 S. |4 m1 s( Z+ V4 f' z  /* USER CODE BEGIN 1 */: L, _% q9 Q8 y0 {

& [# I. X- d+ i5 v  /* USER CODE END 1 */
. Z. f2 X, Y* ]+ ~( `' O# y' `! G7 q% W. I- |/ I7 [$ r2 K
  /* MCU Configuration----------------------------------------------------------*// a4 j) U, r% A# w
; W1 I- t  ]9 a% C: m/ f
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
6 J$ c" x6 b) F6 V% s  HAL_Init();* j- A% {8 m) {/ h: f4 y4 a

% a0 k2 ]% I6 w  /* Configure the system clock */
+ B: C! z- R3 O# }2 t; A  SystemClock_Config();! T  I4 `& u- ^0 y
; ]7 u7 c& B9 |2 g- @9 k
  /* System interrupt init*/" H% ^& W  l3 [& m$ U
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
# K0 m' ?7 D' o; O$ J( ^
7 u, U! A4 p! ^  /* Initialize all configured peripherals */0 ^$ Z6 q7 e' X/ m; d
  MX_GPIO_Init();6 S0 ?  }! d4 V7 o0 i- Q: t
  MX_DMA_Init();
8 G; V5 n: \% a/ n  g, P& k9 m    MX_I2C1_Init();* g+ |. D- E8 Z( ~4 \
    MX_TIM2_Init();
! h2 o9 s$ `0 P; t( C4 J+ j$ N  MX_USART2_UART_Init();
' @& Q# v5 a( K* R2 k. q    InitMPU6050();
3 s/ F* e8 [5 A+ [4 q4 i' n2 L5 j8 ~$ s: d
  /* USER CODE BEGIN 2 */
$ _" t/ g0 f" Z    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
, ?+ m2 c: ?* t& ^8 d. T    HAL_TIM_Base_Start_IT(&htim2);' ~5 j1 H, ]0 P6 P$ U8 Z+ {& B, N
  /* USER CODE END 2 */
: L5 J# O/ Q. I& T# u3 ~
& Q/ r& J. V7 ]9 W) c  /* USER CODE BEGIN 3 */
  M5 d: @7 \) y: z. X  /* Infinite loop */% r2 c( k% m+ E3 |1 |
  while (1)" y3 e  Y9 B0 H3 T8 @# Q" q  L
  {$ f; [2 V. W' B, Q4 U  _
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
" _8 U" H# E& I, A/ _% {6 n        VisualScopeAngleOutput();
1 e- p6 i/ J# n        HAL_Delay(100);# k% k# E: U, Q8 j- r9 Y9 V! @3 [8 E: c
  }6 w: [# R; q! R! B
  /* USER CODE END 3 */4 _# q# {2 V' Y! z! v& f  h

) S6 v# l, R% g. R8 z: V! `}
* n8 N( w: ~$ C4 X: s/ Z% x1 ]4 ~1 r, h* C
/** System Clock Configuration* X2 V* i* _, z( ~4 R7 S9 b
*/
* m" v* S, @  gvoid SystemClock_Config(void)& G* ^- U' d5 [* O7 ~5 ~* g
{
1 Y4 Y, r. ~) p/ e
0 z* m* `3 }/ E; e  RCC_ClkInitTypeDef RCC_ClkInitStruct;
& d- O$ j: p( F. l, }: Y; `  RCC_PeriphCLKInitTypeDef PeriphClkInit;
% y. _* @; p2 ]' z( H% S% T. m  RCC_OscInitTypeDef RCC_OscInitStruct;
) L2 T0 g: X0 |, m( J2 j3 ^. U4 S; d
  __PWR_CLK_ENABLE();. ^' X: F; S5 I1 c% T* r

: t2 w  c! r! H, E" T* p* Q  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);' w; [1 D5 x7 Q7 u4 ?
9 y% q' \) \4 p" j, ?  C( M
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;. @* p' p7 J& ~
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
3 M3 @. L7 `, u  RCC_OscInitStruct.HSICalibrationValue = 16;
! x. Y4 y$ P3 ]# d/ r  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;3 n$ |+ P5 e: g2 R
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;; w! d, y0 u5 G0 l- I8 Y
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
$ t) F0 k% |6 v; N  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;; c8 a* K9 Q0 Y' P/ [% w! D# a2 n
  HAL_RCC_OscConfig(&RCC_OscInitStruct);0 B$ k* P, F$ Q# P& z1 |3 F

4 c9 ]% O) w/ g% |  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;' H( w  v4 i6 G; ^9 y
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
" S' D& p# e. ?  c  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
) a. X$ a! d7 R! p% o: m  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
& Y2 w8 t) X- v" J  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
9 n1 u" c( w& l* s* ~+ j  N4 [  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
  y! d8 ^2 N$ L: V- D2 X8 ~4 u/ x3 W: A3 d6 {2 C5 x
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;: |* V- Q8 V+ U; }
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;" \; i. _* K0 n/ x7 s" Q
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
$ H. J1 P  M8 d
, Z+ m) I  K" q; b9 K  __SYSCFG_CLK_ENABLE();
0 s- W2 B& e: r* T" G
. i, C6 z4 n* w, \; D8 w+ N}% I. q  m5 E/ ], w* F, K; E4 b
& U+ H1 S4 Y$ }- k. w2 [- |
/* USER CODE BEGIN 4 */
( @1 ]/ V% U9 @& \void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/ h% a7 L0 k7 P  W" Y{
- V$ f( R' A5 x! ]- T9 D1 D    if(huart->Instance == USART2)- s' T0 r" D: e+ K9 C/ h
    {# {: Y2 g3 ]1 p
        memcpy(txBuffer,rxBuffer,RXSIZE);
. P/ X$ p/ z* A  J        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);9 ^$ q4 U: b: h, l* ?
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
- L6 q: y7 g  C8 g8 v    }
* a% D; g0 q' z}
  B: v( h$ a* V7 h& _2 p& ?) _
, c' s1 t6 l& [' V  p/ `* Vvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
7 i3 u$ r( Z& I9 l{; T# {: C& F8 v
   0 P: n* [2 q1 p4 z9 v
}
6 \8 @8 v4 Q9 V+ U/ x
; u# u4 q( ]8 }9 @void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)- A! w4 T7 O- Y( v
{
; X3 r' H& O5 t0 B3 S, u9 J' S5 [    int32_t GyroValue;
1 L7 ~" M) m- Q* R   
+ X- y- B2 F9 _. Q& G    Calc_AngleAccel();% M! G9 M0 d9 s3 v8 }' q
    GyroValue = Calc_AngleGyro();$ R- O5 u4 ]( [. |9 X. H! L) h3 V0 i
    ComplementFilter(GyroValue);
  g1 f) n6 E4 B}
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. _& N2 n7 W+ f3 C6 z- L9 {( k
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

. R- \' l) ~6 Y+ }使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:008 h( s) x2 E) d& H: X8 B
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

  c2 ]$ j9 o' y& {+ b如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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
! F/ ~6 b' p6 P, q如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
, D2 k% o7 j: Z1 d) H; w
好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?! a0 l. n, ^) A( k/ Y( V
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
; p( c8 c3 X9 c8 \; ?8 P7 N. w楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?9 }+ M; ]/ b6 _% d
请问应该注意什么地 ...
# V) f  y* X+ n# @, [3 f
我使用是没有问题的呀。

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版