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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
, i5 C) a2 v7 Q8 z-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------% X0 V1 f6 X5 D( G3 m
main.c; X& s) Z; a! E) P9 ?  P: w+ p: f
#include "stm32l0xx_hal.h"8 v) u+ c5 Y; i" s/ T  N
#include "dma.h", Z" C$ m% i; j
#include "i2c.h"
+ l8 t# C# j' D+ H) F#include "tim.h"
* t7 u; F. P- F% x: b#include "usart.h"
" h" a0 B0 d) y$ }8 `# R8 }: V#include "gpio.h"
( w! w, `% t* w#include "mpu6050.h"+ e, z. O3 O: g
#include "visualscope.h"
/ u8 `5 K, w2 {5 W3 l
: F: f7 @) A+ L* y/ m! }" E#include <string.h>
: p& K' L* T# n' m7 J- w#include <math.h>
; ?. A! O( x" R% k$ K7 c8 R  ^6 q4 I2 ?
/* Private variables ---------------------------------------------------------*/
% Q$ U5 W2 _$ I2 R# E#define RXSIZE 8  ?8 q0 Z, S' t5 C# U  Q" J4 j
#define TXSIZE 8
. l6 ~$ z. g9 `. U% ?0 A$ a7 [- vuint8_t rxBuffer[RXSIZE];, s, I! p! C" i$ m, U6 @  }
uint8_t txBuffer[TXSIZE];
, i- M- [0 Z' t1 m' ^
0 V5 ^8 a) f+ p6 b, Z/ ofloat Angle_accel = 0;
8 I' Y( h" B7 _$ ?+ R# pfloat Angle_gyro = 0;
% m. H& t+ q1 h2 {! f% w+ Rfloat Angle_comp = 0;  P3 a- ?2 t# `3 z$ E
uint8_t outAngleData[10];
5 |) Q! k$ a6 t9 H1 ]  z/ ~/* USER CODE BEGIN 0 */' T0 b% v- `  |6 G0 E  k9 n1 t
7 x' t9 F' b: ]% h: g
/*---------------------------------------------------------------------------------------------------------*/6 B3 i' g; O- q. K. P! A
/*  重力加速度算出的角度                                                                                       */
) g  x0 ^. h8 _4 D/*---------------------------------------------------------------------------------------------------------*/0 X, W: v( _5 r1 j
int32_t Calc_AngleAccel()( Q$ F% i; r) }) Q) f
{0 |3 e; O! g+ t8 F* K
    int32_t value = 0;- W  o- {/ I7 _  N' ]% N" k* l
   
' y" C+ }, n" P- `4 }    value = GetAccelValue('x');
" i6 n. K, s( {, u    if(value > 16384). x! U; I! A1 ~# g/ u/ B5 l# U
        Angle_accel = -(asin(1) * 180 / 3.1415296);0 s2 x2 K# W0 ^9 @
    else
7 }% Z* D) B' H. b, Q$ I& L        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
- u. V2 u$ Y7 ~) d! b6 q   
/ @9 a9 ~) Z6 `$ g2 o$ n8 z    return value;! w1 e/ H+ Q7 y; E# ^' L
}
* o6 F8 F  H. n8 P: `3 g$ _3 V: b# w' x- o6 M
/*---------------------------------------------------------------------------------------------------------*/
6 V+ K9 O% @- C6 e$ g$ m/*   角速度算出来的角度(积分)                                                                                     */3 f2 M/ E. [2 z& N+ ~
/*---------------------------------------------------------------------------------------------------------*/% l  ?% W8 k) F1 X6 [3 [
int32_t Calc_AngleGyro()) ?# u! v' I* Q! c
{0 G( E) Y8 ^; N, }" i! \
    int32_t value = 0;
& C2 n7 @* O% L# Z5 O! h
2 s& W2 B( B9 q    value = GetGyroValue('y');& k9 l! x/ b/ p7 X- c
    Angle_gyro += (value / 16.384 * 0.01);
) x. n; u1 x+ _1 R- W* q# K0 I3 ~    & t5 T5 e' R9 [" a. Z1 P7 p4 k4 W
    return value;
$ S* x, u/ K" }0 P2 R) L! H}
: `/ J4 C/ d/ I% H; `  s) N" Q- n/ j( D- @: A# |) N
/*---------------------------------------------------------------------------------------------------------*/
3 e2 _! c# D9 \/*   互补滤波求角度                                                                                     */
3 b8 B' i) w* o8 ?/*---------------------------------------------------------------------------------------------------------*/
! W  ]9 j& b+ ufloat ComplementFilter(int32_t simpleGyro)
1 f* Q, R. u3 x& z6 M{
, r3 N, `$ _" Q/ d3 a    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
- l+ B' v" }6 D9 j; C   
" ]6 Y6 y% t2 ^  }    return Angle_comp;
) |3 }1 r" L8 N, N}
4 n- h. ^  x, O  ?* y& M. j4 G" Q3 n; h, u- c8 o5 |
/*---------------------------------------------------------------------------------------------------------*/
% `7 i$ t+ P9 n) z2 q/*   输出角度至上位机                                                                                     */
, ?( Z; t5 E3 y5 L7 a/*---------------------------------------------------------------------------------------------------------*/8 \. i7 M; G) `3 j7 R
void VisualScopeAngleOutput()
" @  G. o; T" R) L, d9 A6 A{: q8 ?! G9 L6 Q7 U# J" G
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;% |9 o  t' h- s0 O
    uint16_t crcValue;+ j9 x1 j, U- X( L9 Q0 t% f
    & f8 h6 x" b) q; I
    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);- E" b0 b1 _1 S$ p  u# E5 h
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);. v# r0 G* g0 b8 j! E
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);+ O$ {/ ~9 e" j! h. d& Z9 X& A
   
; [! R) z% L2 v! Q# L1 J1 U    outAngleData[0] = AngleValue_Accel & 0xFF;9 b8 K% I( b- y( k/ H
    outAngleData[1] = AngleValue_Accel >> 8;& h3 W- b, n5 i8 {
    outAngleData[2] = AngleValue_Gyro & 0xFF;
' S7 g  x. c$ a    outAngleData[3] = AngleValue_Gyro >> 8;
% o% n2 r* ^9 n: g1 \; N    outAngleData[4] = AngleValue_Comp & 0xFF;
" Z6 B/ `" j# v+ u* ~+ b    outAngleData[5] = AngleValue_Comp >> 8;1 b; T; Z, [7 v! L: G
    //计算CRC, F1 b8 c# D# c
    crcValue =  CRC_CHECK(outAngleData,8);
- _* p: p+ w2 j  ?$ C* A6 x; r- ^    outAngleData[8] = crcValue & 0xFF;
1 O* R: s. O2 @1 I4 a& J. i    outAngleData[9] = crcValue >> 8;* P8 a1 c! J, d/ \3 W2 i
    //发送至上位机
# G, e$ Z5 ^) h1 r) S    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
% w. Y5 m. |' ?( k}; n$ p; z4 R; z
/* USER CODE END 0 */+ ]$ g* T' p# K9 {6 u& ^2 ?% Q

/ }4 S+ y  f( C0 _' }/* Private function prototypes -----------------------------------------------*/
5 x3 {* R( m' ]+ E, A. |1 r( i  cvoid SystemClock_Config(void);
, q7 W0 E) ]0 j9 L5 Z; H: ~
% P! K% z; o& c6 P9 K
: a4 c8 z1 D' x! E$ ?1 |9 @硬件连接图:3 B) E' t( X, d# Y  K6 g, k
1.jpg 8 A/ J; y5 d6 Q
波形图:
" u+ z  ~, L' i2 } 2.jpg
4 t: O% u+ s7 g! u# d4 e1 G最后加一个视频:
$ n! R, l  u& Y  T% _, P( V/ ySTM32L053 演示, Q3 E1 S$ M. g# o. n; z. P+ d
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C$ o7 S3 P: X- i5 B& w
#include "i2c.h"
0 t( ~3 x; a) Y/ m
' u% ]" \) g* `- Y- ^  \' M#include "gpio.h"
. v5 h7 Z: r* y- }# w, o  n/ V% Z) i" J. X
/* USER CODE BEGIN 0 */1 L0 |* e& M; G1 m7 i

! r9 p3 Z1 Y3 w7 _/* USER CODE END 0 */( X1 v/ M. A! a5 U) I- H

. W( G: d5 S$ \+ Z$ aI2C_HandleTypeDef hi2cx;/ n' N$ a3 b. w* r- D
: G+ a2 `9 s( D3 }
/* I2C1 init function */
3 @) ]! R, l* u( n8 K1 ^void MX_I2C1_Init(void)
+ X: w  @8 d* \/ N2 @; N6 u; ^7 E{4 Z3 ~, e, c' m

- n% ?1 R" r5 T5 b, I+ n2 X  hi2cx.Instance = I2C1;% ]# `2 h! _9 a8 {
  hi2cx.Init.Timing = 0x20D22930;
/ d& s- q" }  K7 S! ?' C) w  hi2cx.Init.OwnAddress1 = 0;
1 @6 y  q5 k& q3 j( l  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;3 h1 h1 g# w" i# Y7 N' e( ^) n2 z
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
" v2 r6 m2 I7 A3 d& @  [$ @  hi2cx.Init.OwnAddress2 = 0;  p- z- C% ~( n/ t! C* H
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;3 C/ I2 H$ q! s6 e" D  S
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;2 N9 F% L+ D0 l# o& U
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
$ u+ `9 R$ |* t  K' |  HAL_I2C_Init(&hi2cx);1 k! p2 q; h% x  {

& Y" v; w9 b1 w7 u    /**Configure Analogue filter; g7 Q9 S, b5 g  s) y% P
    */
" T4 e. v9 k9 m3 }9 Q  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);+ c2 U4 E- d: H4 C! L# S; Y
7 m- L* H- M! w6 r# \; p. ^+ s
}
# c% S4 K0 z6 s: z% U) z7 G1 R) e& Q6 O* x$ v: {
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c), P7 Z2 R& c6 ?& u9 Y! u* }+ T
{
2 J8 A) j  E5 c' m) K' u
, X6 X  ~, a% b- W& ^% o. ]' e1 s  GPIO_InitTypeDef GPIO_InitStruct;$ @7 G: l0 Y. O5 \
  if(hi2c->Instance==I2C1)% O( K2 ]6 ^& ]/ ~1 p. K  j# }$ l
  {
" `1 }+ J& s5 l    /* Peripheral clock enable */
( D% o& f/ X; @    __I2C1_CLK_ENABLE();
& D% B" I# X9 j7 u  . `: t2 f! T7 l
    /**I2C1 GPIO Configuration   
) M5 G- L" S) [, z    PB6     ------> I2C1_SCL
! \/ y! g3 `' W! Z0 n    PB7     ------> I2C1_SDA2 c4 P( \4 u+ M
    *// F' z2 u' m# ?
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
+ _5 `2 i/ D' v6 L, r. C    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
5 U2 ?6 K+ d3 Q/ ?    GPIO_InitStruct.Pull = GPIO_NOPULL;' [1 z& R5 l) F3 Q" H* f% r
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;  K6 P# h4 {7 o/ E
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;- \' i5 |6 q$ e3 P* X: k- Q
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);& I- Z( ^) `$ d2 n: Y/ X& c
; o4 v+ X7 m  h
  }8 F: [7 ^7 e: R1 ^! U
}. l) ]$ y- E. A" b  \" w
# N& z* i8 ]3 ~, \
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)& D" b& g: n- w  J- h" t; N
{* J9 P2 H2 v7 ], i% H! |

' i8 t+ T( q# {  if(hi2c->Instance==I2C1)
) M) o/ ?  u  b  {
# s% c8 u# _1 v5 F    /* Peripheral clock disable */
7 A! I1 O" J  A/ B+ i2 d    __I2C1_CLK_DISABLE();
& @! }! _" U0 m+ \4 U5 ^( A  
/ k3 e% ]6 {3 O. Q- ?    /**I2C1 GPIO Configuration   ) W# o( r, K+ C( R6 j+ w' s' q
    PB6     ------> I2C1_SCL) x6 N7 X. J" ~4 M
    PB7     ------> I2C1_SDA6 ]4 h1 k8 o% a/ A3 `* K- {0 ?
    */
/ X* U6 m: {0 A, ]8 {* n    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
. P: J% ^0 _2 J+ R% s% w
3 T) G7 ?) @) Y/ A7 R9 d  }' Y0 Z7 b3 ]# `8 o$ Q
}
- z% `7 k4 f7 `; ?% i3 y) C------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
( F& F" ]' v% C# z4 i) {usart.c& ], r5 M* ^8 H- v+ p6 d2 a
#include "usart.h"# @& k$ V- L1 _! k$ w2 m
- Q3 X* f; y2 |8 ?- k
#include "gpio.h"
# {/ z5 q# d8 ?' i! s7 o% s  T#include "dma.h"$ {& t3 W" @$ F. b
% d! x; L- e: S! {
/* USER CODE BEGIN 0 */2 f# |+ X: I9 @
: c' t9 A6 t- j- g- {
/* USER CODE END 0 */! g$ F, D/ L0 G% s* o3 m
: T# j0 J- T& o* ]1 @/ \) s
UART_HandleTypeDef huart2;/ R7 W, x, a) z: }" Z1 F4 ?
DMA_HandleTypeDef hdma_usart2_rx;
2 P% v' P+ O! T* o& gDMA_HandleTypeDef hdma_usart2_tx;
- s. e+ S9 S( x+ i; B
5 w6 ]9 j4 L& F8 c& y/* USART2 init function */
/ G. k! W8 N3 M' B5 I4 |) {( n9 Z
void MX_USART2_UART_Init(void)
+ K0 w. U7 n2 i+ [% R% R% c{
& }7 c7 ^* q1 `/ G0 L# n
2 x+ g$ ]1 ~. q: o6 h6 J. h# K  huart2.Instance = USART2;) |" C+ ^7 j: ?2 t
  huart2.Init.BaudRate = 9600;$ K& @3 H! v5 G
  huart2.Init.WordLength = UART_WORDLENGTH_8B;& M; P. p$ D+ P5 @. _) |$ H
  huart2.Init.StopBits = UART_STOPBITS_1;' S5 Q1 T3 S+ N0 q
  huart2.Init.Parity = UART_PARITY_NONE;
8 U3 L! w! G+ D  huart2.Init.Mode = UART_MODE_TX_RX;
4 R1 q! {4 \- k  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
) |- {; p1 |2 o% M8 t0 E  huart2.Init.OverSampling = UART_OVERSAMPLING_16;7 Y4 x( |) |3 H
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
# e9 ^# p9 d7 `' y  n  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
. s6 H. s9 _; |: [0 u5 v  HAL_UART_Init(&huart2);8 S8 d* |$ w8 ~2 s9 X

4 P4 u( K- ]0 T- c9 ^}
) Q" ^, v* @9 f8 c- M6 o# q- e+ \2 v6 @/ h& h1 d: k& s8 h
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+ e( [8 O. O! r0 J( i) O{
$ k7 Q. [2 O# r5 E7 U$ t6 L  i4 L' ]" Q' H% j5 G. U
  GPIO_InitTypeDef GPIO_InitStruct;
) t; p& s) f4 C# D  if(huart->Instance==USART2)
( J: v( s! D5 A  U7 ?/ w3 M( o  {  f  F1 K/ J' s% ~
    /* Peripheral clock enable */
0 h( l  f- m1 P" d2 Q    __USART2_CLK_ENABLE();
0 y- ^0 J* I/ `$ M  |  G! h  - D, j: P& O- D, L
    /**USART2 GPIO Configuration   
. t- f" b* p- z8 k+ v5 G# K  i; X    PA2     ------> USART2_TX6 ~& r: }  Q/ A& f1 W# _& H4 W
    PA3     ------> USART2_RX" e) d! Q2 ]$ ]$ e. T# ]# h( w
    */
: ^8 I& {) H3 I  f$ v    GPIO_InitStruct.Pin = GPIO_PIN_2;
5 ^1 w# C$ e8 k$ G5 Q/ O    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
7 X9 t( j6 }7 _0 d- |% j! n    GPIO_InitStruct.Pull = GPIO_NOPULL;, c/ H: s+ O+ H1 ]: n4 J
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
( g7 B" m" @% t* U; T. M! v    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;2 [$ C. {2 d: i' Q9 Q
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);7 {! z2 v4 f% y9 p9 [% A

0 Q/ ], H* }: B0 f: A    GPIO_InitStruct.Pin = GPIO_PIN_3;
1 j4 |2 X/ j0 S' b    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;8 Y# x' d. q0 b% Z* c. j+ M  Z; z7 L
    GPIO_InitStruct.Pull = GPIO_NOPULL;
; o: Z$ L* T" B" q5 B    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
6 d4 P1 h$ U" @0 ~3 H8 l0 a; v    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;" q% k6 ^* j" {# g9 o9 a
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);' Y" w$ C8 m: k4 ~$ V7 n

! X3 x2 S5 {4 a3 b3 {0 W& \    /* Peripheral DMA init*/
4 E' K: i2 L9 r4 x* ]. a8 p( ]  1 t& [% V0 y6 u
    hdma_usart2_rx.Instance = DMA1_Channel5;
/ p( e) Y) y7 g+ E& ~    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
) L3 d  s7 [$ n: h5 x    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
3 T9 E& s% I0 b" X. ]    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
6 H/ I+ [; H9 |/ s7 x    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;  Q8 ?3 L% I6 J; O3 c
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;' K8 t  _+ Q& y8 W7 U3 m/ o+ G8 V4 A  y
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;+ y% |5 T* y7 ^( [
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;* `/ t+ B/ E& R4 d% Y. O
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
! A; R2 I: C1 X5 A    HAL_DMA_Init(&hdma_usart2_rx);
# a& _: n, d- d5 _. P# d% I8 [+ p3 C! X) O  W/ q* q
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
: P! Q7 D3 h3 W8 p! Q
5 S5 o$ O8 z3 p% o: @) B$ b  J' I    hdma_usart2_tx.Instance = DMA1_Channel4;3 f3 n' c3 }& S& f5 r2 j  B5 i, E
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;% V1 i2 ^5 l$ A8 `' G9 z1 z7 C
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;' |! U7 x5 [+ y' R
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
, H8 O8 z+ U3 h# z/ o    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
  W% ^; x* k% I  j" O% U    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;, A' G' d) k* R8 K
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
: T* ~- l& {& _! D8 o/ B1 f, V* i    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
! p# ~5 R1 B  e% |! C1 o% {    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;: X2 c+ m3 Y& q: Z# I3 O
    HAL_DMA_Init(&hdma_usart2_tx);
! L3 b5 {/ p- r$ k/ i! i* \3 S8 u" N
- T, Q/ B% w1 d* G' T    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
, R6 r& g7 V* i) g  Y# k- r% m6 r- a
  }9 @; F  N: p# s1 y1 {
}
% m7 y! U$ P+ `' J/ J7 G
; D# f# n$ Y+ p( k) l6 [( [void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
; o* c/ X- P2 {{
3 R: F9 D+ }( f) g/ s
1 d+ A: {3 @' x/ F* J  V4 L8 [- v6 P  if(huart->Instance==USART2)
" C6 w4 r: t; L/ X9 s1 x9 k  {
$ a1 d4 P" J% p. E  S    /* Peripheral clock disable */# T$ P/ r  k/ \+ \: ~
    __USART2_CLK_DISABLE();
* e6 }; t4 k. ~  u0 F6 u0 \  " ^9 {4 {+ z. r8 O9 j# J( e
    /**USART2 GPIO Configuration   9 a8 g& e  _; K# r* g6 P$ ]
    PA2     ------> USART2_TX
4 U% {# v$ m, J% X: w; i) j    PA3     ------> USART2_RX
3 @% {: [: K# y    */
: V# l4 g  S7 J  |! w    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
7 [! |( @9 ?' v7 J2 {2 _7 g8 Q
8 E- c8 z, T  J1 w# \- \+ x    /* Peripheral DMA DeInit*/5 D2 T0 B4 M- b. Q
    HAL_DMA_DeInit(huart->hdmarx);7 y' m2 S" W& x' A
    HAL_DMA_DeInit(huart->hdmatx);
4 O* {' ^7 S, Z$ |( _* |  }7 ~+ j# Q) |! p) r9 b
}1 a) ~- o: I0 w; n; l- \+ d! }
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------, u$ T/ N" {& C  u1 A
mpu6050.c* M& t' s# Z2 }( [/ J
#include "stm32l0xx_hal.h"
8 N: T  J4 o5 Z6 W/ k' c( ?8 }% p#include "MPU6050.h"
* o7 f& h' U; P! F% ^) ~/ i
) F3 x' D% R/ L* b//各坐标轴上静止偏差(重力,角速度)
# `" d; e. E7 B: u. \' F- Oint16_t offsetAccelX = -195;
/ T' I4 u4 z; r7 w$ fint16_t offsetAccelY = 560;  a5 ]" C- M8 h+ R& D3 w0 ^' \. i
int16_t offsetAccelZ = -169;0 T2 ]$ n0 V$ ^; V

( ~# c* A! x1 b0 c& Wint16_t offsetGyroX = 12;  x# u- Y6 l4 K2 r% l/ p
int16_t offsetGyroY = 33;
6 D  n$ P& z2 i, Rint16_t offsetGyroZ = 4;
5 b) u# q5 ~; M6 h! m8 K4 b7 z2 |5 W9 z6 T+ Z
extern I2C_HandleTypeDef hi2cx;
) {* T/ \, l5 L$ @" ?- M# s7 `9 }9 `$ l2 ?' {0 C" {
//**************************************
$ @/ Q9 f, z& C4 o//向I2C设备写入一个字节数据
; R' h$ d: ^" y, O8 }//**************************************9 Q1 O* M% t. j1 L& N; k
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
, S- w8 ^5 v" d6 i1 E3 x{  r# i/ _# }: o
    uint8_t rxData[2] = {REG_Address,REG_data};
- n% N: @/ j2 w! y$ S; \    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)1 G$ j1 b  l. [: M
    {
5 t! a' x' p2 S        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
* A: n9 y8 a/ y' q. w8 e+ J0 x        {}
3 z7 `1 B/ @/ x" J    }
* U6 O  e* U/ f  i}& b* R1 Z% ^2 P  C. n3 U  S
//**************************************. N' P; m: p3 f" V' V( ]. }
//从I2C设备读取一个字节数据5 o" {; H# X. F3 q: r& p1 z
//**************************************
* l9 \' I, L: h( Z0 h+ C( Iuint8_t Single_ReadI2C(uint8_t REG_Address)$ f6 z. C8 L4 h% B& ^# Z* {
{  ], F0 b- g9 e' {
    uint8_t REG_data;
% d. O- k% I, p    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)1 K2 e% k. R! b$ W- m) w$ t
    {
$ _9 L+ w0 J) X3 }        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF); W$ r$ T8 O7 o9 j) O
        {}
% \+ y( X* U/ r! r/ \. G    }
) g; |8 T- R# X$ Z6 x* I   3 M7 B; G% p) s9 E- t
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)  u3 N% D) h4 X# C! O
    {  B" M+ Y, I( [
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)$ O! Q, S8 v% E1 {& z
        {}
% Q" i* x. B& R    }5 ]' P9 M. L- w5 d8 l2 g
    return REG_data;1 `9 e3 Y2 d3 s2 D: {
}8 |6 Y7 _$ t' q* o; [
//**************************************. `# m' p" t0 ?' d6 i
//初始化MPU6050/ n9 M. x( y( e* J
//**************************************
3 D) \) ~9 y7 O7 E' fvoid InitMPU6050()
) y9 S: [' ^# Q{
0 }3 E1 M" _) P% l% I    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
5 v4 }; ]# T/ s( l+ T& X& R
( ?  X7 L' T/ l4 h    Single_WriteI2C(SMPLRT_DIV, 0x07);" F# Z% x) }9 ^8 `

/ U7 L2 @' b( J, s) t- A) h' K$ `    Single_WriteI2C(CONFIG, 0x06);2 K7 f& P' A$ h- e) }

3 H; u, |3 V+ ~, ?    Single_WriteI2C(GYRO_CONFIG, 0x18);
/ R" @- x7 m% [+ z8 |& `* j4 g+ _) G4 U, g8 {( `
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
  I" n5 A$ B" N" b}
  l; I. J1 f5 H) v3 c1 \9 I  Q//**************************************  H* f$ q% o% b( ?& F
//合成数据
' G* M  f' i8 o7 n3 w//**************************************0 X0 `' L) B. Z; z3 k, O. K
int16_t GetMPUOutValue(uint8_t REG_Address)$ r7 g0 T" Z9 x% I
{
- {6 s% @; m' J4 j    int16_t result;1 F' A0 U& X% n: I- r% m0 y1 ^
    uint8_t H,L;9 Q* D" p. g) j$ E3 S
    H=Single_ReadI2C(REG_Address);
4 ?5 f# Y3 Q$ `& }1 w    L=Single_ReadI2C(REG_Address+1);, p- e" C( V1 X2 D  ?# A
    result = (H<<8)+L;2 e+ o* Y7 ~; P* \5 |
    return result;   //合成数据$ G) `# ?2 a3 h# Y
}$ M9 r$ W- ?6 i; e: e6 e4 N
# G/ t; {$ Q/ \  C
//**************************************- n8 v9 a" t2 n
//取某一轴上的加速度数据" G$ r7 f) ], p& C9 Z% \* k
//*************************************** c* i! q; l8 K% [' R
int16_t GetAccelValue(char axis)
5 V9 @+ |! ^. l2 g$ A* w{0 V3 L0 U# m" y6 H5 N6 m$ ]
    int16_t result = 0;
: w) N' h& S* a, c    switch(axis)
) Z6 D, J. i5 r# a2 Q    {5 {6 x% x8 k& m& {
        case 'x':
; N* o: D' _6 `# n  g8 `        case 'X':
2 k# \- P6 q  T( D$ F        {
% [% Z' _. V& }  ~0 L# _5 F            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;4 z  ^7 j. B+ v8 \2 d! s
        }! F( ^" z" E) \9 m
        break;
+ j$ a" u5 g0 ^( Z  F0 ]        case 'y':
8 l6 @; ^: s4 ^# q9 h6 K        case 'Y':& j; Q1 U% `/ I% x% t
        {
5 w: j& e- j- \# j) i* q1 D            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;; b& R. Q; m# D8 a! Y, a
        }
; [! d+ Z& |4 j" T        break;
  H. b0 f4 W- A% v- U, h7 S" B$ O+ p        case 'z':6 [- `. M# Z: F5 `5 e
        case 'Z':1 t8 {/ U9 J1 Z' o" U0 n& V/ V
        {$ b2 W& X. @- ]
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;3 e. L, J+ k1 c- L9 ?# a( S$ M
        }
, n, ]: v# o3 x8 K% k  R( ^0 h        break;
0 M5 ], r% g( T. a, @    }
! C1 z& P8 \8 }* A; W2 }& t1 b    return result;+ }/ g2 z9 Z; C$ C6 P" X8 x$ T# D
}
/ W8 z/ P  ]: M: Y" V) e! n6 {9 B; p$ W9 X) z1 l7 S9 t  H! l: f1 I4 U
//**************************************( o% |% s- Q0 F9 q( }
//取某一轴上的角速度数据
" s# E6 E( `) u9 r- L//**************************************( |9 z( ^) E! o6 s/ f1 {
int16_t GetGyroValue(char axis)  n6 J+ W" k- E# I
{8 {2 |% X- T- Y  Q# i& a# a5 z9 l
    int16_t result = 0;5 Y& {+ g( N/ z# U8 T0 y" l( }! O5 O
    switch(axis)% Y/ c, P: P5 y8 x5 }. N1 s8 s
    {* l0 p, J6 G& }' f
        case 'x':* v9 i* e" Q7 c  `* h: {1 U* P
        case 'X':
4 D, n' h* H. y  A% [        {4 P) P3 l4 Z1 O/ f) `
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;+ o. ~3 N4 B  C  R+ V
        }
( p8 _' v( v( e' O        break;# ]- \$ M0 n* }/ E8 t: X  c0 T% k
        case 'y':
6 K+ d' a4 c/ H        case 'Y':$ }) a! u3 k! s! s, T  _: |
        {, J, H+ W0 b1 H! x  ^
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;& h2 U/ O9 N, n' M
        }
, ^3 H# G+ ]$ X, @8 P' a. y$ q        break;
- V5 g$ G/ X( a0 s" L/ e        case 'z':9 ^+ J- r+ \# `4 y+ m5 Y
        case 'Z':+ w) N7 U. M% \6 t
        {" S0 M2 E( [0 p  E+ E) x
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
9 I- X$ J  k. X3 l' G5 X; f' D        }
# ]8 s/ w& i- r0 {( p, P        break;
$ e" l4 l; L& w    }& }8 S: g/ {, b( O$ y, r' Z
    return result;1 @0 W! c! z( T" T. b- c
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void), y, Q9 \: o) `1 [& J5 i3 M
{# V/ D: U, F% m5 M3 U7 r5 v; H

! D. g- f1 i( x, s$ D1 L4 G$ ?' B# Q* h  /* USER CODE BEGIN 1 */; [6 Y5 w' I# N) p
' l. l& ?! ~" H
  /* USER CODE END 1 */0 u" A3 F! u1 n8 o* z! _, g

' J* V2 F2 ^  I0 y& ?/ z  /* MCU Configuration----------------------------------------------------------*/3 ~1 c$ i% p- D$ ?/ e5 K

/ r0 a1 @3 G: |$ y# f  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */9 I, o$ E3 ^! R+ m
  HAL_Init();; j; J  L% Y$ j3 ^  J
. \4 F0 q1 @! x8 R3 H1 _+ v6 V$ b1 p( |
  /* Configure the system clock */" ]. F1 b9 A. \; U& m: |, ~
  SystemClock_Config();
7 k, t- \& ^) `! `% }+ C- ^0 ~( {& g6 p( N( Q7 O7 M
  /* System interrupt init*/
- b6 k* Y8 p1 W& j* z; |  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);. E( [% N; R, Q0 F

1 G  G: p  y' e/ Q% V# S  /* Initialize all configured peripherals */2 \, o( w& e# r
  MX_GPIO_Init();
% B! q1 j: G: R/ L% l: h  MX_DMA_Init();
  K6 v8 H4 b8 q2 _) K8 j    MX_I2C1_Init();
4 [3 w: L& f9 x. E& M    MX_TIM2_Init();
4 m- w' g" D6 ^7 A/ E; M/ V  MX_USART2_UART_Init();
. }& \5 e; V$ X- E5 h. A    InitMPU6050();
9 `. F+ s8 y& @# K
! h4 ~) S: g: C! N  a. s3 Z  D  /* USER CODE BEGIN 2 */
, H7 V- p. ]) \: |+ F/ t/ g( [# A    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
- r9 O6 |& T/ N" i% F7 W    HAL_TIM_Base_Start_IT(&htim2);: L& ]& J0 [/ X, ~
  /* USER CODE END 2 */6 f% I) l5 ^+ i$ I
8 S7 }. \; v% N! ]4 ?
  /* USER CODE BEGIN 3 */' y: H+ ?0 ?( W8 z- P% _
  /* Infinite loop */
4 M5 x% {! ?$ d4 x% T  while (1)2 \' t4 J( U: p9 I% v3 g
  {
. A7 t2 F, ^4 i7 d8 Q        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
) v; H  Y1 s; O6 O9 Z! p- M* ~        VisualScopeAngleOutput();5 x8 G# g0 I' i8 }
        HAL_Delay(100);9 |0 V. x* ?' s! @' \& D
  }
9 h2 r4 B4 z! e% Z3 C5 R/ [% W  /* USER CODE END 3 */
/ c+ |1 |7 N0 p/ x5 t. L$ d- z% t
4 N6 N2 _/ v; q% i- T' |}
4 e% H) m" {; H, ]' V8 C
) a# }: }  v, A' O4 {; M/** System Clock Configuration- `: e! E) d# I, j& o; K, x5 z
*/. {" h  @8 C* P% t' ^" X% C
void SystemClock_Config(void)
2 ^. J% P% i/ Q{
/ M- j; ]- I+ S, R* g1 w* V
& R! v3 {' O3 ^. V( w& o  RCC_ClkInitTypeDef RCC_ClkInitStruct;. n4 e+ g3 ~7 Q* k9 [
  RCC_PeriphCLKInitTypeDef PeriphClkInit;5 C& d; Q& @) g9 E
  RCC_OscInitTypeDef RCC_OscInitStruct;
; K" J  i: \/ e0 B8 G' ^5 Z$ x. h" Z7 ~) q1 E6 |: S0 M* @, w" z
  __PWR_CLK_ENABLE();
  J. L1 Z" n0 Q- u) ]+ ]  ~0 i/ Q1 S: Q4 J* k9 t
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);! L/ ~5 n+ S. U9 h
! {0 U9 W: m% |% V3 S8 q3 Y- k3 c
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;  p0 y4 Y. A. n( B  R9 x1 h
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;: h" I  v) q: `  R/ U5 a
  RCC_OscInitStruct.HSICalibrationValue = 16;
. ^0 b: c# U2 s# A  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
' ]9 N6 R4 T' e) F! |+ @- ~  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;- y1 q" \% K* b# u/ _- N/ v
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
& w. |1 `7 K& T8 v% [  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;9 ]0 R0 D$ X! H
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
1 L& i5 S3 q4 S( v! b
( O/ a; [( Q; k3 k  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;" m5 d, I7 W) }0 q* f0 c
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;7 j' V0 I& N+ H( J; r) t1 V
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;: [1 I, r  \/ F3 L
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
# y$ [6 q* r% L" C  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;9 @, u1 b! ^4 F5 [% }
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);5 m! V0 z8 X' Q/ q7 _6 l8 Z, V
9 t0 }! d8 f/ \& G
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;+ d/ e( x& W7 F
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;) f( b5 d8 L7 v8 J
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
: R- A; X6 K" |* u6 y" P7 ?6 d& t/ r  h: E" v9 ?
  __SYSCFG_CLK_ENABLE();
6 e% n, c2 N3 c! k2 b3 i# f! y0 k6 H! B+ {1 W% z: `+ [
}
0 \+ H" E2 w/ e6 W* Z! i% w
2 g; y% H" G& ~) e  w/* USER CODE BEGIN 4 */
  C+ ?& m9 O! i, }6 }+ nvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
0 u  C, i4 L' L; D{
/ ]2 V% Z- b' z# i    if(huart->Instance == USART2)
+ u$ {; b4 w, X4 X3 Z    {
: V; ~: t6 Z1 f3 F' U; R, @5 |* ^        memcpy(txBuffer,rxBuffer,RXSIZE);. s) |& J/ s9 _
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);3 x5 J, {: {& |* G: B
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
4 J( Q9 D& R( |) d- E    }
+ i2 N% ^% s8 L! X! R1 M}9 o3 K- h$ e* H/ Z7 E" L. M
& s9 U5 ^1 A/ R0 F" n
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
) J4 y$ s1 J( Q" k{
/ U- a& m# _5 J# N, m6 S" a; @     N0 X- D9 l, c4 M2 B, z. h
}* E$ t% l) a% \1 `" ?4 z

; O" M8 Y% I* t" @7 `3 tvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
4 V1 W4 i3 S9 v* y{3 E9 o. R) b4 S/ A; d
    int32_t GyroValue;( b4 {$ a6 J  c# t2 Q
   
4 P4 ~8 u- E# |; X1 H( A5 G* x    Calc_AngleAccel();
; r4 }. ~; I% B. s3 C    GyroValue = Calc_AngleGyro();7 h# ^( V) R% G6 p6 Y) R0 P
    ComplementFilter(GyroValue);7 O# z0 z/ n9 m2 S
}
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
! W$ w0 N8 z# S& Z* U) b楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
8 U* g0 R9 K- u. e5 T  K
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
: n" X0 N2 T1 }( }楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

- X6 j# t" j( D; q' @如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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+ l$ X' v/ P. N$ Z
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

0 w7 l6 t- c9 ]; Q) R2 V6 q- w+ e好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
6 Z: J: q" q" U1 n请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08  Y" B) H+ A% h8 m; P
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?) J( c) y3 A9 v# W9 t! W
请问应该注意什么地 ...
+ B+ I& E' G3 h6 u& W; c  ]5 g7 h3 z
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版