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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
% R5 N! ?. C5 r+ S8 H-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------3 x, B; ]6 p. b3 \6 `3 p
main.c
4 D, D8 A5 n& ]# l' O' o" L#include "stm32l0xx_hal.h"
- B9 l7 C7 j  O$ C% f4 t#include "dma.h"
! ^# q" ?7 c# @0 l1 R#include "i2c.h"6 i$ Q! ^$ V1 g' P
#include "tim.h"9 I& }5 l6 T5 N9 d+ [
#include "usart.h"0 J# Y. r; d7 M7 m! \. v8 n
#include "gpio.h"$ v- j2 K" ]( }4 j3 |3 E- v- T& ^- A
#include "mpu6050.h"
( E- [6 j0 D! w: Y' W4 z6 N" S#include "visualscope.h"6 w! g! E8 o+ t; W9 c
' z& H: T2 R2 T9 i- K
#include <string.h>
. P6 J2 j: H: h; ^" N) K" S7 s#include <math.h>, P- w, _3 k' N$ Y! a1 c
7 h' n' J6 J  a) M, k  l$ e/ ^& J
/* Private variables ---------------------------------------------------------*/- \8 R! `7 J8 I. J" e5 @
#define RXSIZE 81 V$ l8 q. n* M1 g
#define TXSIZE 83 a+ `7 B- ~6 o1 Q" @
uint8_t rxBuffer[RXSIZE];# Q" L5 Y! Q, {/ `
uint8_t txBuffer[TXSIZE];3 z( f4 O$ ^9 m* H# d

- Z" ]- s1 P1 G. Ifloat Angle_accel = 0;3 A1 d3 I- ]( B/ W& t
float Angle_gyro = 0;
9 ?; e  F5 S# \; H' [float Angle_comp = 0;" I0 M1 j- x  T6 |
uint8_t outAngleData[10];  Z2 x" [% C  M9 p
/* USER CODE BEGIN 0 */& {; z/ F* c& h6 B7 S
, d8 U0 x+ K" s% z7 V: Y
/*---------------------------------------------------------------------------------------------------------*/& l6 q/ X9 I/ `$ V/ x2 s
/*  重力加速度算出的角度                                                                                       */
& U5 R: d, N# r# B- U+ E/ V" n/*---------------------------------------------------------------------------------------------------------*/
7 z( D+ J: f8 R& O" Uint32_t Calc_AngleAccel()
! ?" z) p9 K$ ?! d) h( y; s5 Z; v{
- N0 |4 @+ G4 I, [0 n+ E+ B    int32_t value = 0;
2 z6 f% R8 [* M    6 S5 \1 |: Q) W( ?2 |3 A8 J
    value = GetAccelValue('x');& F) e# p/ _5 ]& w8 ^; w1 U) @
    if(value > 16384)
3 G+ j. E- L3 O0 i        Angle_accel = -(asin(1) * 180 / 3.1415296);
2 g* j: e7 c- o. k+ N9 {    else9 Z$ N$ t, ?- Z0 @- h0 ?; Q
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
$ W5 K6 W9 q0 j8 @5 F1 _    " H  R. g& y* \7 M: N
    return value;
  V+ {' ]. t% P/ x* {}( `1 y  N' {) C5 k9 b
& G& |, S  K/ Q: G# c
/*---------------------------------------------------------------------------------------------------------*/: |6 Z. y0 h9 R! t) [. _( x
/*   角速度算出来的角度(积分)                                                                                     */
* z( |1 v. U: g/*---------------------------------------------------------------------------------------------------------*/9 F4 A6 J( t% m% I- R2 T; n
int32_t Calc_AngleGyro()
5 G4 w$ V3 V0 ?& _, R8 T( }) K{
7 m- @' g, D4 q, U    int32_t value = 0;
) M( Z( W. X+ W5 Q- K3 H- v1 @' m! {  _2 R0 `# i, L0 k. C! C
    value = GetGyroValue('y');, J' l5 O/ B, P6 l2 }; v
    Angle_gyro += (value / 16.384 * 0.01);
3 |' X$ S$ u. F: v+ `    4 H- v% T- n. a, ]
    return value;7 `2 A3 _8 A% q4 Q: I
}. _5 s2 C% H6 F  `6 W- B8 _$ A

4 ]$ j; T- b" R9 ]* N+ B/*---------------------------------------------------------------------------------------------------------*/% m9 a' c& J7 s* X" D. e' z9 v
/*   互补滤波求角度                                                                                     */1 [0 |$ J7 L2 M. \" v0 A, |
/*---------------------------------------------------------------------------------------------------------*/3 E! O+ I4 X" |6 j2 q& d
float ComplementFilter(int32_t simpleGyro)
/ Q: e" b/ F5 B{
0 g& c7 J0 Q9 i- |1 ?, p% m5 D! t    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;% q) g; P' O7 |
    $ a6 F* s2 D2 Y( P
    return Angle_comp;- G7 g5 B, e1 w- n, L. N! R% l
}
6 i% B5 ~+ d! l8 f! ?, V' i' T2 e7 T) k! f. d; |1 j0 ~6 |$ b  N
/*---------------------------------------------------------------------------------------------------------*/) U: x$ S/ ~& R3 r3 f
/*   输出角度至上位机                                                                                     */. B3 |+ y2 P7 w: |. i# z  |0 p
/*---------------------------------------------------------------------------------------------------------*/
7 D, A! l! `/ V9 }void VisualScopeAngleOutput()9 e' c$ ?9 _8 P$ [
{2 C. Y3 V; {6 f, S& E( x7 A
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;& |2 X! a8 _6 H, d3 C& O( T5 c( H7 v
    uint16_t crcValue;
8 ~9 o9 n' }  `' Q   
. S7 V/ r5 I& }2 j4 C    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
& o) @: b; x4 a. ?' _! [( G  l    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
$ V/ d$ h$ H9 C5 \    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);
/ n; U" p/ v0 g5 d# }' U    ) o- S' y) J& I+ ~/ A6 A" g- t
    outAngleData[0] = AngleValue_Accel & 0xFF;! C8 V; n% J2 Y1 ?! E" L: A
    outAngleData[1] = AngleValue_Accel >> 8;: W+ e! ^( n3 k7 D
    outAngleData[2] = AngleValue_Gyro & 0xFF;
. T6 w# b+ R. P. q" U$ H  U( S( H    outAngleData[3] = AngleValue_Gyro >> 8;
& z  J6 G) m. D4 J6 Z( H    outAngleData[4] = AngleValue_Comp & 0xFF;
. ]0 ~7 _' b4 Z: X/ ~; ]/ E7 M: E    outAngleData[5] = AngleValue_Comp >> 8;0 S6 D6 e3 t9 v1 I. V6 ], f7 |3 F
    //计算CRC
& d( p% f$ P# n6 z6 A0 l4 o& ^    crcValue =  CRC_CHECK(outAngleData,8);- V8 Y. \+ Y- P# c+ H+ v% O- m
    outAngleData[8] = crcValue & 0xFF;
# b7 z& U4 e. z& J    outAngleData[9] = crcValue >> 8;4 i% Y. p4 r8 l& \
    //发送至上位机1 Z  o2 d9 q6 z# ?1 r) J' l0 d
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));5 y8 Y: J2 Q. I" ~# L
}
) E5 m. V+ P9 q3 T/* USER CODE END 0 */9 W- a% }+ Y1 R* L) I/ C

: T4 \0 m( \$ X$ g6 i( p/* Private function prototypes -----------------------------------------------*/
1 I# _9 [) O; |* f( q# uvoid SystemClock_Config(void);9 @& ]- B' r; W* J2 d0 e

" {' k8 D) F: p5 }' l
! @. B# H5 l8 \: ]4 W2 J& X硬件连接图:
" ^$ w4 {; l2 O. U 1.jpg " ?' _5 D6 M4 N3 R% [
波形图:$ \* z( z6 Z& {0 G) l' C
2.jpg
( w* S; G7 ^" `! [5 r% {5 a. K) d最后加一个视频:
6 X" O  W5 m, s3 @" g# S% sSTM32L053 演示: i$ y8 ~) F1 {/ N+ F
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
- N3 k2 H. {4 I9 p- I+ |#include "i2c.h"1 G$ ?! f# U4 p

1 d' E2 ^/ H6 }#include "gpio.h"
# X2 G- @* h3 e8 O2 _. R" C+ L+ ~. s$ q: Q, K6 Q
/* USER CODE BEGIN 0 */- f: l* z9 V6 T  U' x6 ]

" ^1 N7 m$ V4 K" G0 H/* USER CODE END 0 */, A* }+ E: H- {) K9 n* j
, l) Q9 q) L/ O) I  l
I2C_HandleTypeDef hi2cx;
+ Z( }9 g  I! ]* v, v) ]: d
2 n& O: S1 R0 s5 H" I/* I2C1 init function */
; Z1 z. A: q; D7 ovoid MX_I2C1_Init(void)6 \5 L( F% z8 h# a7 H6 {4 p. P
{
, o& u1 e/ E  _
5 X2 g& M! I( N# @% Q/ `  hi2cx.Instance = I2C1;
1 {5 u( ]. y' w  hi2cx.Init.Timing = 0x20D22930;" I' g' F. L1 I1 ^
  hi2cx.Init.OwnAddress1 = 0;
9 D2 s  q5 W8 R  }/ G  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;& a7 \  ]7 J0 t' y' L% [
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;" {. Q9 }# b0 i8 q6 s# r  y+ f
  hi2cx.Init.OwnAddress2 = 0;
/ @! p0 ^  |7 v8 B  e0 x3 t$ S  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
$ \; b! @6 {3 C4 d( z  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;, s2 d- r& R/ k5 A
  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;8 B0 e" y  }! \% Y4 I, x
  HAL_I2C_Init(&hi2cx);
5 y% m8 p' }9 R0 a  ]1 Z1 ?- E. i5 s, U, D- u7 g  O
    /**Configure Analogue filter
+ e/ r: w3 z3 B- `4 R6 J7 M1 R    */$ n1 y7 Z' o& F* v' h+ E
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
" W# P8 H% A9 R# X6 D3 ^5 H9 s) R+ x6 p2 {5 w* B+ _
}
( v' ?# K2 v# {; |0 m
7 i2 r  A) t% H9 S6 Bvoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
: c2 M$ x7 u8 v" W, x{
6 q1 ]1 g3 s, j5 V/ N9 H( p8 Z# ?# ]# f7 ^: d( r
  GPIO_InitTypeDef GPIO_InitStruct;
% k. V+ R$ D+ ^, F. Y  if(hi2c->Instance==I2C1)
0 X5 e8 g' k* I- l# d$ w- {  {
+ T& ?4 @4 N5 |. J  L3 j0 I    /* Peripheral clock enable */
5 q7 X& B9 b+ n    __I2C1_CLK_ENABLE();
% P5 h& e/ D: t. u( t  
3 \# O! ^& g; i) e) ]    /**I2C1 GPIO Configuration   
. ]1 s0 W+ W$ S/ a6 Y+ v# z    PB6     ------> I2C1_SCL
3 u3 @6 s# t$ k) n    PB7     ------> I2C1_SDA2 ~% r# Y5 g1 R& \/ V7 v% f' f* ~
    */9 ]6 H3 @, V; l- ]& e% J9 y7 L# R
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;4 L0 L& S! Y6 e4 Y& v/ G: D
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
8 t2 t9 {9 b% l, H5 K0 m    GPIO_InitStruct.Pull = GPIO_NOPULL;; U9 i4 i+ g  Y5 e1 U6 N
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;" T4 _* @2 P" G) J
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;# s+ C  f9 m5 T$ o- [7 e/ Z
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);# Z) Q9 {: W* d8 j

2 F. l4 C$ ?& I8 y1 a4 r- t  }" z5 ?4 S1 @* ]' @" g. O/ ^
}! L5 f0 e& k, _
  u6 f( t8 O' W# |! x
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
" J( u3 N& S, r" ]4 i' ]1 K{
( ^7 r4 c0 y! p3 {" S( ]
! p0 E! y6 P  P/ p+ j! ]- C  l' |  if(hi2c->Instance==I2C1)
8 e5 p9 z+ f3 ]  {
, q9 _8 f% H( z    /* Peripheral clock disable */
% v8 N' P9 |! I; I  t, g    __I2C1_CLK_DISABLE();% [2 V, s) k: m7 b
  
% }" n/ P. W2 S# H$ W/ G! _# ^    /**I2C1 GPIO Configuration   % A( Z, W7 b+ d/ `1 c2 d0 U3 x4 }
    PB6     ------> I2C1_SCL9 E. `6 A. y% u# _
    PB7     ------> I2C1_SDA
* g5 n3 l5 J9 Z  Y5 D! g+ ]# r    */; J' z% j8 l3 f' q2 {. E  h
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
% A: I  T( V- Z# e% }' a  v- A* K6 l2 V9 O! l7 m, a& B; y: X
  }
% E$ y' O# m: m. ^; _* m  @  y}& ?' p' w4 m) H+ P
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------- B: t) P! d$ L2 y$ J+ l
usart.c  D$ o0 C& g4 F& O$ S
#include "usart.h"
* }% f' r8 d9 N4 ~9 p0 R5 z0 E
  ^  b4 W; E# `  [2 b+ }. q, d3 S; z#include "gpio.h"- G1 ?2 ^2 H3 I5 n
#include "dma.h"$ P  I6 E9 g5 W8 G/ I  S6 v9 ]  u

6 w+ z$ X/ M6 z. ?$ n5 I; ?" {/* USER CODE BEGIN 0 */6 F, Q3 e, b, I% \; T% q1 x

  Z# {3 m* H: y$ M( u* c7 ?, L/* USER CODE END 0 */
% C2 q) q9 b0 t7 w+ q$ k6 }1 Z! {+ b4 s$ [. s
UART_HandleTypeDef huart2;* F& \, O+ p: ]6 R
DMA_HandleTypeDef hdma_usart2_rx;1 M( w0 f* f  r  {+ j* F
DMA_HandleTypeDef hdma_usart2_tx;) `" {* O# C- z* f& d7 P* q; k) C

, v, Z  E$ j( }0 p/ F0 t4 R/* USART2 init function */
& `$ U! o' {7 l6 G3 q5 {7 z4 C% ~+ I$ r5 Q
void MX_USART2_UART_Init(void)
8 Q5 U' Q1 S2 b{
  @) j6 n# U. g3 R; \- g% }
5 X1 @. y5 _$ b7 ?* K' k8 a- X  huart2.Instance = USART2;
# ~& \/ s: s, Y5 [# {5 _  huart2.Init.BaudRate = 9600;' D' u2 d5 `" A5 _7 e) z! w
  huart2.Init.WordLength = UART_WORDLENGTH_8B;# _2 j. W; C' r3 Q3 V( [$ I
  huart2.Init.StopBits = UART_STOPBITS_1;
0 E0 }# C3 E" f2 C  huart2.Init.Parity = UART_PARITY_NONE;
$ o4 K' W3 s. C  huart2.Init.Mode = UART_MODE_TX_RX;
- v8 C  ]6 K3 {/ C& E4 R  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;2 C/ N! T  F- |4 V
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
, q1 o. e' p1 c' N$ `  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;4 g. i2 M9 L( M1 o+ l4 g
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;3 I- L4 [- x# }$ ^6 T( k
  HAL_UART_Init(&huart2);
( v) |1 B3 U4 Y  r& Z' [
6 r$ q: ^* a. s+ Y}% T9 H! t" H- ~1 r& f/ _
; _0 \( {& }: L
void HAL_UART_MspInit(UART_HandleTypeDef* huart)1 c2 s2 F8 d6 N9 F, b5 f* K
{+ i  W5 T! s+ R

; S: G, g! Y2 d  GPIO_InitTypeDef GPIO_InitStruct;& P0 C4 ~& m7 W3 e9 k0 I9 W
  if(huart->Instance==USART2)
  W% E. ^/ G" y5 B% r5 E  {+ k( i, G/ Q7 W8 r# U
    /* Peripheral clock enable */
6 d; ^+ \* b1 f    __USART2_CLK_ENABLE();0 J' h' \7 a/ K  ^9 N! h* o# g& V; X4 K
  & J9 ~, e6 a  R7 @( b/ ?7 E+ q
    /**USART2 GPIO Configuration   4 b  u. P2 l" E4 S  j' a4 h+ }# G
    PA2     ------> USART2_TX
) ]8 f; [( E) X, y% t8 P3 o  W% ~$ Z4 L    PA3     ------> USART2_RX" ^" I1 x2 t# ^
    */
' Z4 U& V, w( t    GPIO_InitStruct.Pin = GPIO_PIN_2;
2 R! ?* W, Y) k! y* e$ M6 @    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;* C/ Q$ A2 l4 [0 O8 ?0 w# Z: T
    GPIO_InitStruct.Pull = GPIO_NOPULL;8 d; F0 W, ^/ E8 c
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;  W! b2 w/ w% K2 e0 c9 ?2 k
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
7 `. F- C! Q5 \3 j4 o% C# e    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
: u' n1 V8 }+ |5 C% P) g0 }9 o0 F6 y" I: m/ x" g# ^
    GPIO_InitStruct.Pin = GPIO_PIN_3;6 A* n  \( V" y( R6 k) I
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;) i) l2 R; w9 d9 u; K. Y- B8 e0 o( i
    GPIO_InitStruct.Pull = GPIO_NOPULL;3 `) V: F8 C5 w' D9 o) c8 L
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;3 ~. E* ^& r3 Z/ o8 d
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;' @. p, v+ W/ }1 \. d) m4 w
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
, k" f- }# F! z: Y( X+ l( _
: r% Y1 @" c. y4 [6 P    /* Peripheral DMA init*/
; J7 `% _7 e- \9 j) o5 D  
9 Y, h3 {- A6 P" y) ]    hdma_usart2_rx.Instance = DMA1_Channel5;, D; d  X: }: n# v$ H7 z. z
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
' a+ G7 |' i1 c+ _; M/ x! X    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;) B4 R0 W5 v% z3 J
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;! @: y; Q0 Y  H% l$ s$ ^7 F
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
0 l9 S6 S7 m+ I. b! ?    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;  U+ f4 X% r+ @( ^6 p8 M
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ }0 X1 V+ j  R! m4 m    hdma_usart2_rx.Init.Mode = DMA_NORMAL;/ D/ F) N( ~. _  g
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
% x7 J4 \. C9 F3 p; C1 f: P    HAL_DMA_Init(&hdma_usart2_rx);1 ^  Y4 Z- R7 d5 o6 ^. Y
7 V) p6 _- T2 g# q- p9 P  O
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);: U) P. U0 m2 V9 U, A
; r8 f1 k6 ]* o
    hdma_usart2_tx.Instance = DMA1_Channel4;/ h! D: U; s0 R* M4 r
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;) E% F" Z' k! Z9 R7 D4 g, t
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;% @- K' l. H8 ?* O7 F
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;! h7 h9 M" l9 p, u" Z2 y. W7 {- g
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
. R3 Q4 r5 a* K3 [    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
2 k0 H) C7 l; Q# v9 C    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
% S+ B8 a0 T8 m) E    hdma_usart2_tx.Init.Mode = DMA_NORMAL;+ y: X% d! D7 J: L- D- n
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
: E& s, X, D5 U0 p1 n    HAL_DMA_Init(&hdma_usart2_tx);
* g' q% |+ O  O5 P- g
) R% ^; X: s+ D1 a    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);+ p- l4 U2 g7 f) H* z3 a! x* u6 f6 M1 r( C

, K6 [  R+ v' g- a0 E" |  }# \9 E* F. C8 C7 _7 H
}: D$ c/ o9 K1 X+ l% _' t
+ @8 [( O9 {1 l$ s# m
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
. l- ?' \3 m$ G{3 ]% w! d( i: K* q  h
/ I1 @4 j: T% P5 H  N2 n$ e
  if(huart->Instance==USART2)$ |; F# B* H  _/ Q/ N! U  {
  {  u2 c; k, o& \9 `; Y, p
    /* Peripheral clock disable */& D; l9 l& c3 r& ^8 I9 z, v0 Y
    __USART2_CLK_DISABLE();
8 s. I$ t# }. ]: q9 e# h  
8 t, X. h+ c9 ]1 g7 w* Q; z    /**USART2 GPIO Configuration   : C% s4 i6 P6 p) d
    PA2     ------> USART2_TX
; S: |1 `( N4 ^) M+ g. n* Q5 @/ D    PA3     ------> USART2_RX
3 f' x5 Z" p1 i# N    */7 J' S; {0 @3 x* z' h% h
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
' R5 e" s1 O) U/ _+ a5 D4 k4 I; U  T6 E! i' m* Q8 [5 ~) [
    /* Peripheral DMA DeInit*/, ?9 ~7 E+ D+ V/ @4 s( }# q
    HAL_DMA_DeInit(huart->hdmarx);
2 y  l# z! L" O+ a% T! M7 H$ W6 J    HAL_DMA_DeInit(huart->hdmatx);  A  V# U/ ~: L( T# B9 q6 ?: _2 h
  }7 F' S. b% w2 r. d$ d/ ~2 X5 T
}" |+ B7 Y- }* o, g0 ^
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
$ V# C$ c( n, g, }5 xmpu6050.c
3 u) f, B1 ^- u3 s) [9 w#include "stm32l0xx_hal.h"8 V3 Q- s+ x1 X0 j4 T
#include "MPU6050.h"
: h' e3 b6 {! T. L$ g) U! k/ T: Z  r, b, L) X4 g& y: s. _9 G
//各坐标轴上静止偏差(重力,角速度)2 Z  v/ A' F2 F' M  E! L+ ]& d1 r
int16_t offsetAccelX = -195;; }/ D6 d, t0 K2 e& ~
int16_t offsetAccelY = 560;, }0 h6 F+ ?  p. |" E6 F2 ~. J
int16_t offsetAccelZ = -169;
( {0 v& j9 g2 u1 Q1 z# j9 c, V9 U+ Y- r, H& j9 s4 \0 z
int16_t offsetGyroX = 12;! I; n9 H: ~8 |
int16_t offsetGyroY = 33;
9 o/ c/ x9 h7 m( A1 O! nint16_t offsetGyroZ = 4;
0 e+ ^8 i* m3 B1 [5 h# w9 f7 a7 O3 B) N3 ~
extern I2C_HandleTypeDef hi2cx;
: S3 u5 j4 E# k/ X8 Z# Q( n% \
% _& v" [* n- S//**************************************
+ o, H1 N7 t+ v$ }  i  E6 l/ R//向I2C设备写入一个字节数据
/ v( @8 _, S) |  l7 D/ Z$ p//**************************************; i" Q) f( s' z) o' |
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)1 c4 U" ?/ @6 F8 x1 x# T5 Y
{
8 X  y9 R; x( E/ e    uint8_t rxData[2] = {REG_Address,REG_data};
) U+ `2 [* S) {% \7 x    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
; h! w8 l" {. c- m' F5 h9 w    {
# D# g) N6 V  f, S* O' ]- u        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
/ w  v  U1 L0 K( b$ k: |3 Q# S+ g9 X        {}
/ R7 x$ ^( e( H& R# W: @- k    }4 _( j7 l/ i1 _2 ?. A/ ^  c
}
6 O: l) K% C: l0 Z5 X//**************************************
# z5 V% d7 S- c4 ^//从I2C设备读取一个字节数据
6 ^5 d+ |$ @' X//**************************************: ^6 B  a& M% Z/ P
uint8_t Single_ReadI2C(uint8_t REG_Address); S* y& _: s9 R0 |
{
( H$ T, Y  ^9 W  y: o$ L2 ?+ |& \    uint8_t REG_data;; D, A: Q0 c4 @0 ~
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)1 l3 c; K- g( x& H
    {4 u* B0 l& P( g6 z/ I* A
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
) j0 ^1 B8 A- D& [2 h        {}
4 j! C- Z3 ]6 {0 c: K' H- y+ T: L2 Z    }  I& _: U; R) Z% N7 |
   
# [7 Q! Q$ a4 h: p- o6 X; T, O, i* V/ {    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)% V8 c2 E. D# P& |; L
    {
' g& h- f% {6 e' T4 ~8 W        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
) f! u* X) ?6 ]  u        {}
# n; N4 e9 x! Y( o; {* A5 Q    }6 Q- c6 L2 Y" D7 u- \% P
    return REG_data;
& K" R0 X9 I2 E0 @( ~3 S% P}
, p7 q$ ~9 @' G//**************************************
  q8 X( J* a6 L; ?' Y5 }//初始化MPU6050
* o2 i, a- Q% H- R. }//*************************************** f0 Y4 ^/ s3 E  R
void InitMPU6050()
% b$ }4 ]+ e- ^' I/ o, l{+ P" m: c$ |, b) K% F: {+ {
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态$ B7 h' T$ X4 a; s% o! ?
; @" U4 @: B, G$ u) v
    Single_WriteI2C(SMPLRT_DIV, 0x07);
4 O  }; J* k% @+ l9 L( l4 D$ ^8 c4 U  h! X2 h: z- y& _
    Single_WriteI2C(CONFIG, 0x06);
' v- k. `+ G# U( C# M; e
1 H% R4 d; D* Q7 H+ \! A# i1 L    Single_WriteI2C(GYRO_CONFIG, 0x18);( y# v  x4 j9 r, }
) B( r' a2 m* Y% S) C. x
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
: T/ G' f9 d3 t( i' _}  e. \. {9 v* D6 A
//**************************************1 h  n( J; p" b! F/ Z. c, ^
//合成数据" w) @9 }" i: m# _0 J% \/ Y* P
//**************************************
0 P2 t' D' D( `int16_t GetMPUOutValue(uint8_t REG_Address)
( E) c1 k3 W. j0 m{
$ B+ q, K$ Z/ X! ?6 n/ h& R4 y    int16_t result;
9 N+ m3 X2 {0 c5 }3 _6 V4 j1 K    uint8_t H,L;' z0 f% Y( S- p
    H=Single_ReadI2C(REG_Address);
/ D( L) c, D9 T) S+ B    L=Single_ReadI2C(REG_Address+1);
* S7 J$ B* b4 O$ r2 [1 S    result = (H<<8)+L;" w3 t7 N" t: v; G' b
    return result;   //合成数据* a5 N, c1 Q. N
}
8 ^& k8 N! n, N: I/ K* [7 n/ M
/ Q, v' q$ h- j! \9 \" B//**************************************
2 g" Z% s' Q; [7 t; n, k7 T//取某一轴上的加速度数据
' z) e5 ~: o: a! H5 {* ^//**************************************
# b+ a) I& r: \int16_t GetAccelValue(char axis)1 ?7 F4 D4 J$ @! z7 d
{
0 l$ d' P3 ?6 V/ c; u0 J    int16_t result = 0;  L; ]  X% e3 P+ x" t' d
    switch(axis)/ j& j- n; C' X3 p6 L6 v3 ]! q
    {
3 w% B* |$ j0 y  k, s) v        case 'x':
! ~0 f$ D, M+ J4 o( z/ U, a        case 'X':% H$ Y$ b' h4 [- u( L/ v
        {
4 F2 t/ e0 D( R$ Q  ^! [7 }            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;# h! y) `* S$ b+ g5 Z
        }
0 D5 b- I# P+ B' [        break;2 D, n' E5 b& ^4 P; L
        case 'y':" d+ C9 V* T# R% l5 b
        case 'Y':
; {# w0 f* y, c* z        {: }. ?$ f2 s, d& q
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;/ G4 a/ R4 X' m
        }3 E0 T4 f' ~$ s
        break;2 X& z  K/ P6 Y4 L, {/ C& j' D
        case 'z':
  j4 J7 |2 F4 f5 W        case 'Z':
' B8 r! k6 V- R8 e' A2 g& T# }        {! l7 H. d& U5 \5 b& g) u/ A
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
% L. r5 }  X9 X, `+ r% t" P1 Z/ i        }' t7 B  e! [, J- M; C
        break;
1 @6 v8 G. V; z1 m; Q' U+ k- G    }+ I# t' i3 ?; `. f3 X
    return result;
& @* w" s! R1 \$ M}
( a" h5 v! B/ Q2 l5 e, M
3 Q; z% L# X( d: R6 X3 H//**************************************
/ R) D: z# t% A3 q6 _6 N1 B4 U. L//取某一轴上的角速度数据
9 U' }) e( z- Q4 Z, t$ G8 Z# g//**************************************
) y, {7 B, C  p  r  m' M/ z' {int16_t GetGyroValue(char axis)
' {! [; C) Q! \% N1 Q0 O  ^{  f) \) M, H3 r% q4 \8 U6 Q
    int16_t result = 0;* c5 v7 R) o9 Z  J! z+ K; h6 \
    switch(axis)- o7 b+ |: @3 B' R' `8 J
    {
: w$ q0 U, P3 u% _% G        case 'x':
2 B6 A+ d# N' L# X: u- g        case 'X':/ z5 B' \9 j) Z; m
        {7 o& l7 Y: n" q4 @
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
; d9 }$ M* a6 I$ ^' o- j        }0 n7 b% g2 c8 I7 {/ j' f1 |( t
        break;
% g' L, G8 `! ]+ l$ E        case 'y':! C) o1 t  u  }
        case 'Y':5 t% r5 N7 D' ^) j, c
        {
% M! w: v! C; _2 h; t* k- z& c            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;# f6 L/ h% v* G2 ~# r
        }
4 s' B6 r! Q( m1 B/ u/ N        break;, b% Y& @" g3 I1 m- e9 \4 S: c4 f
        case 'z':% m7 e* m5 v! W1 P
        case 'Z':' o0 g( d) t# s9 H# ]/ S2 f, D' S8 K! L$ G
        {
: @5 O! v( _" G: T            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;5 j% [, Q- {* G
        }5 g' J" h6 v& }6 Y6 V7 o
        break;
% k+ Y* R7 b2 Y# S% S6 \( d& |  v    }% G+ A* @8 q: p$ g
    return result;
5 P! o6 \  `1 H7 _% F/ H1 E}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)  P4 y. T+ N+ C2 k" R" V) a
{7 n. w7 }" G* Z9 _0 K) G

5 L  j4 T% z9 s$ L7 _& u# J  /* USER CODE BEGIN 1 */
) W0 A* Y: ^7 q0 e& h1 O3 S/ [' q" z) K- U
  /* USER CODE END 1 */
3 H& l+ ~/ j$ D; O3 B" D% }+ V
2 C. t0 O; F# `; H3 n! _  /* MCU Configuration----------------------------------------------------------*// [- z! F; v, c0 ~+ p
, b) {8 j  c+ O6 g
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */, m8 G, n! S3 v. K  c5 A" C+ M7 A
  HAL_Init();% [5 x# P8 Q, F
- _  K" e( V! r
  /* Configure the system clock */, b: ~& {. s( Y7 \% x' ^# g' U1 k# {3 P
  SystemClock_Config();3 J9 o) m% z9 J
. q3 ^. ^' u6 c; u
  /* System interrupt init*/
& X& d* J" z- f  S% r. d8 ^% ?+ o: w  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
: t6 V  X0 D7 b, r) B# a
9 h9 N. B% g- d% X- S/ V* J( ]% d  /* Initialize all configured peripherals */$ x( O6 V8 L# y5 l9 {3 d0 e
  MX_GPIO_Init();
* n! j- c, ?/ B# p. U5 k& X  MX_DMA_Init();2 z9 r! h; {) l( v7 v' ]
    MX_I2C1_Init();) z" p1 c3 z3 S6 v, ]2 s4 T
    MX_TIM2_Init();  ]4 U" x' H, Y3 Z: m! h" m- ^
  MX_USART2_UART_Init();  q! u/ ]; t' n3 [3 F7 a
    InitMPU6050();
9 B" y% F7 ?- Y* `+ z  a
1 Y5 Y: v7 K" B1 G  /* USER CODE BEGIN 2 */
7 G9 p2 T# L3 |- Z1 C3 N: S    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);& g/ g  m6 W0 x& m1 c' A. i  C
    HAL_TIM_Base_Start_IT(&htim2);
9 t4 H- D1 `0 P  /* USER CODE END 2 */% ?: q! C8 z. C
7 i6 I# M+ S7 ~. v& P& {  P
  /* USER CODE BEGIN 3 */
1 o  q, B. n8 g, B$ q! m- n6 W  /* Infinite loop */
  \  I( J+ j! h. @& x; y+ x& ?  while (1)1 l. v9 Y! k/ L" [( `2 O* B
  {
* }! E7 ?9 t- y6 [# O        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
: f# h# G7 h2 }6 l/ w- k# `/ }        VisualScopeAngleOutput();" r+ Y/ ^2 J4 q9 f( `7 I4 p
        HAL_Delay(100);
. O: W* q; E& _* B. p# n( T  }
2 J& G" V5 F8 S& S/ X! }, O  /* USER CODE END 3 */
' F! Q9 m# x3 {
& a  G5 J" x3 y}. O9 q6 |) n4 S! s

6 e: I9 P: i' ]% Z2 `3 f/** System Clock Configuration0 m$ E6 O5 j/ l" X0 Z$ T2 f
*/1 N3 g  R8 u* W
void SystemClock_Config(void)
9 I7 S) D0 K. Q  M{
1 N1 u4 p2 \$ ?* D" q; }
+ @  p$ N( Q# K2 f: u0 W, T& w! \  RCC_ClkInitTypeDef RCC_ClkInitStruct;
4 l* ~; P$ Q2 m4 R: W  RCC_PeriphCLKInitTypeDef PeriphClkInit;  w. m! F, y/ h( m( S
  RCC_OscInitTypeDef RCC_OscInitStruct;
; u$ k3 I  ]* A* L1 v' Q/ p6 u* b: l  z$ K( Z
  __PWR_CLK_ENABLE();
7 i+ ^" H1 V' z0 v% c" B+ [9 W7 ]+ J2 e6 ]/ Y
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);% j' F- f1 h- G( H

+ s) ~3 b' a! a, U, w" k0 B& q  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
4 Y- K  c# ~" V  }) ~  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ F' x" l# m5 V0 I* ~, k4 Q4 |  RCC_OscInitStruct.HSICalibrationValue = 16;
  g* Y7 z+ D; ~3 g  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;( S' H& _+ D) h- p" E: u
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
! ]! p; y7 P4 W8 p, p  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;/ c' u) R) Y+ R: Z5 d
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
8 l: C1 O; j% I$ C& Q! I  HAL_RCC_OscConfig(&RCC_OscInitStruct);* n4 C: x% r- |( E" @

" O8 D: M2 a" c  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;" I' k9 t- `8 b1 U
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ y/ f% c+ a8 R2 ?  i) [  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;9 d% n$ m- k3 ]4 X" Z3 Y
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;$ e( x% i* @) F" Z) g
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
. w- _: N+ T2 i; S* f  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);, `6 h: r. c6 x6 g6 X- }! b
8 |  m  ?% ]3 ~2 U
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
9 V' t& w7 B; Q3 e3 f3 s  k+ g$ P  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
, H8 z! q4 B9 X. E0 h2 x  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
- I# X1 N/ @/ \- X1 R4 H2 W2 C) ?; q# ~
  __SYSCFG_CLK_ENABLE();. K  a, }7 z7 L8 v3 o

# `8 o8 V2 \# a: H- E# o; T" v}3 u9 R4 R' k: X+ O2 W6 ~7 y
3 m; Q2 c; e! F2 K/ d1 h, g" E
/* USER CODE BEGIN 4 */
5 N: O) i! r) m# Jvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
6 |6 }! \( s* p$ d7 y{% B: B0 [" W+ u
    if(huart->Instance == USART2)% a9 r/ S. V' d# M
    {7 ~* [7 M/ C0 ]+ `
        memcpy(txBuffer,rxBuffer,RXSIZE);
) d* ?1 Q( r* o, S  S* \* u        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);. L' E' [) U" e2 d& Q# |' }# X
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);( {- s8 f' R( R6 Z
    }
3 R8 r& ?8 W* |4 o- t1 c" D}: {1 P6 k$ B& M  _3 i( s
3 R, G8 {- J; N, |9 N. d
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
8 f& ?; k7 H  T* {{3 Q9 }6 {# J. g" E& s3 W1 h/ Q. E1 c7 Z
   
0 d( I4 _6 I$ g* O}  s. Z0 H; P! V7 v1 n
1 \" t/ Y# i$ T1 ~- @( ^- k5 o: l9 o  F
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)/ h/ `2 f2 d1 g& O7 o9 R; c& ]) |
{
6 _" a* y5 J, K; a    int32_t GyroValue;
4 H2 y6 T) q* f0 J   3 }- y+ r, q0 S5 a" Q1 ^- u
    Calc_AngleAccel();4 m( w# }3 }' [
    GyroValue = Calc_AngleGyro();
4 Z6 B* S& u+ O! T2 C    ComplementFilter(GyroValue);: @3 h- P2 W* G( [4 u6 @% C
}
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
) K: A. U; w0 Z- v- j/ W# S楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
0 @; N7 n$ v3 k; x8 K1 U+ {
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00$ ]: D/ h& F1 V5 v! Y; x/ B) k
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
! B- w2 y& K8 s4 i' `9 k' J
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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:213 [/ c: i" p% k; Z4 \2 s. ~6 ?9 h. ?
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

9 d5 ~/ ]3 G+ w% x好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?' ]/ a) t; z' }+ F& p2 ~2 u/ b
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08: w: F: A6 I3 Y2 y4 R" b
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?% l1 q2 u! Y! p0 ?6 u5 R" c
请问应该注意什么地 ...
3 s! z8 y6 r: H" r  ?& U
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版