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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:5 p- O$ h( Y. G
-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
3 p0 w5 t7 n+ \1 u/ ^. b( n& d" Umain.c. F% [) \' W4 {6 h! J3 V
#include "stm32l0xx_hal.h"! t6 o& b) Z9 X( r0 }: n
#include "dma.h"
; A2 Q3 z- T3 O( W7 v- |- |* N9 Q#include "i2c.h"
, j, F/ A" K/ A% w8 Z" w! ^#include "tim.h"- P& V4 m+ c$ H* p8 B4 h
#include "usart.h"
' Z/ j* h; S0 D% r" M& K# M#include "gpio.h"
* {/ q5 ^0 h) T: b% N5 x#include "mpu6050.h"; S. D0 S0 b* S9 Q" e( V  a
#include "visualscope.h"$ _7 J" \! z" l+ F+ Q" k) W

" C8 \( r( m$ k) u" ?2 H' Z1 b#include <string.h>
/ O8 |6 F/ |7 B& B1 R1 h1 J#include <math.h>6 v4 U/ s2 _6 t2 V) \/ f+ C& {
, D! r8 Z6 q7 z$ f9 `9 P
/* Private variables ---------------------------------------------------------*/0 [) R- a1 v3 ^% g. J
#define RXSIZE 88 C3 W7 c1 ]$ l7 N3 L7 b& j
#define TXSIZE 8" p$ W; J3 \" l8 ~3 I3 l4 c0 k
uint8_t rxBuffer[RXSIZE];
  J& W) I, @$ e8 P; k( L8 Vuint8_t txBuffer[TXSIZE];7 f4 ?, c' G0 h* s6 J* o) u) a

! {7 t# ?& R. _float Angle_accel = 0;
6 j6 F9 ^9 y, T1 x( f  Xfloat Angle_gyro = 0;4 h7 p# J  N0 s7 I
float Angle_comp = 0;
5 e- I2 f6 y( K& |- muint8_t outAngleData[10];
4 V% L  V& u5 A( |3 A/* USER CODE BEGIN 0 */  t3 r. |6 v* K# ^! A& P- L3 j7 k
3 b. r9 g% _: [8 ]0 z
/*---------------------------------------------------------------------------------------------------------*/
$ J2 O9 \7 h0 \  f( N5 y8 K/*  重力加速度算出的角度                                                                                       */$ {8 c" y* V% C; U9 w
/*---------------------------------------------------------------------------------------------------------*/
# q* T, M" \# g) ~  C$ Dint32_t Calc_AngleAccel()! w! y8 Y8 k$ H' i
{
- g9 j1 P* O* `0 D" {0 c    int32_t value = 0;! \8 N8 v5 T4 O8 _% J+ w
    # Y3 ]  c3 _: l% e, \8 z7 U
    value = GetAccelValue('x');
5 r2 v1 f9 E! d$ l2 S    if(value > 16384)
' Y3 [; s; J8 G2 m4 P        Angle_accel = -(asin(1) * 180 / 3.1415296);1 C  T: S7 ~4 v0 m$ K; X$ O/ z
    else. m- O5 w. D+ x; H  d9 t
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
. l( Q1 [! a$ t2 c   
% E5 @2 I) t1 i* {5 v    return value;2 {; _: r5 ^" N0 Y. Q
}
/ [3 \/ G. l: p/ r3 p
2 O$ D7 |: U, c" ]/*---------------------------------------------------------------------------------------------------------*/7 s/ I/ x( }2 N" k
/*   角速度算出来的角度(积分)                                                                                     */8 k5 r  v# a% M1 ~, v( g
/*---------------------------------------------------------------------------------------------------------*/
) `# j; d( n$ ^, b" ]2 W4 R* Z! cint32_t Calc_AngleGyro()
+ I! |3 z3 d; _{& w1 P( J) E( O4 o& ?* @' C
    int32_t value = 0;
% E8 L3 R/ b& f' B  Y7 N7 V! d1 Q- w7 Q6 a
    value = GetGyroValue('y');2 O" K+ _& R+ Z8 {4 L# _
    Angle_gyro += (value / 16.384 * 0.01);( L4 t$ X$ `/ ?+ n5 c
    & d4 G" k# o3 [2 l# a( t
    return value;
, [+ Y+ V5 h9 q/ q" }}6 H1 D: @" u' I$ V/ Q7 ^6 _9 h
8 D6 Y# M' D: \$ B! ^
/*---------------------------------------------------------------------------------------------------------*/
& z/ d3 [8 l8 p& }. u. V! ^/*   互补滤波求角度                                                                                     */
$ b( t, a0 [" ?* _/*---------------------------------------------------------------------------------------------------------*/! U# N, ], S) {) O
float ComplementFilter(int32_t simpleGyro)
. N4 C0 u( t' |+ a{
2 @+ j7 k9 {# o. _. T/ d    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
/ b6 g; k6 x/ I+ i    9 I. m) N  Y$ e+ [
    return Angle_comp;$ Z, R3 `. E7 q+ K
}2 \; U8 `4 Y; i* @5 i

* c/ D8 Y9 I- ~5 t. r; J% o/*---------------------------------------------------------------------------------------------------------*/
! j5 z( I! s5 P+ }0 Y+ m2 Q$ C6 n/*   输出角度至上位机                                                                                     */, {! x; z" }3 P3 e$ w; u" B# ~1 z
/*---------------------------------------------------------------------------------------------------------*/
7 l( s0 w2 P( V. e/ Zvoid VisualScopeAngleOutput(). g9 e( L# C9 z
{- A; v+ @$ t. t- u3 ]5 v$ P% V
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;5 |3 w2 N! k- j
    uint16_t crcValue;
. n8 i+ j( w5 [' E/ x3 B* p   
5 V- s% f1 h4 v# _2 g    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);
' g0 _8 ^' C& b    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);- U6 j) ~% J% j; \
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);8 q* x" ?8 A& O5 f% I
   
7 E) |. ?! x" l6 W' }    outAngleData[0] = AngleValue_Accel & 0xFF;1 |* _5 B* F1 ~0 ^
    outAngleData[1] = AngleValue_Accel >> 8;
! R( P* ]* I- B- R% \* x5 i& [' h3 L    outAngleData[2] = AngleValue_Gyro & 0xFF;! ]; ^) [9 v) O2 \
    outAngleData[3] = AngleValue_Gyro >> 8;# k  U6 [0 z* O0 h* V$ q7 e
    outAngleData[4] = AngleValue_Comp & 0xFF;
1 c* W8 D$ f0 s6 f( S; n    outAngleData[5] = AngleValue_Comp >> 8;
. D# [3 E: q# U, F/ f/ _    //计算CRC; T) F# w6 ^, r/ l: W4 f- P
    crcValue =  CRC_CHECK(outAngleData,8);) s% Z- ^: @4 ]6 U4 q; [
    outAngleData[8] = crcValue & 0xFF;5 C+ \2 J/ b7 t3 g) {  f& V
    outAngleData[9] = crcValue >> 8;4 X+ s' G9 F' a, J* i
    //发送至上位机/ n% P# w( A2 \  ^3 _1 a
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
. t+ F" ]# x) L. v9 w}$ F& y; _/ z" X
/* USER CODE END 0 */* n4 u7 Y& i# |) u& {* u7 _
) Z$ L$ y# @8 X+ I2 y
/* Private function prototypes -----------------------------------------------*/
# }! T2 q( F. G1 [$ |' H8 F1 f# Wvoid SystemClock_Config(void);+ w6 k9 k' x' [4 |% h9 t& ~2 V
5 ^; Y- N; R5 O# m

# O: [: X) l# ]8 A( A硬件连接图:
/ i' i) m2 X* L5 T 1.jpg 7 w4 ?) i' M, z
波形图:
% o& M; f2 G; f* P$ K/ d 2.jpg : f0 ]2 F( Y: O/ N
最后加一个视频:; u! {# F+ H; ?  x
STM32L053 演示6 ]( @, T7 M4 T2 d/ [7 A
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C
6 K7 g6 S/ d" v#include "i2c.h"
' g2 y0 v* r" `9 T& F$ X" W5 p( u# o6 t4 t! k3 d
#include "gpio.h"# o2 T5 Q; z% j7 A

) s) w: u/ k/ K/ s9 V/* USER CODE BEGIN 0 */
( u5 ?, j+ z! U' s$ ?- K
: `) S- `1 k& }/* USER CODE END 0 */
0 `( Q7 I" @0 W6 v, Y0 v8 |4 J  a! B( P8 k/ T, Y7 o) W
I2C_HandleTypeDef hi2cx;
" m* ^; {3 |% Z: j2 M& G. @4 _) Y5 R
/* I2C1 init function */
  T5 t* x/ A1 Q  E2 Z( n8 Hvoid MX_I2C1_Init(void)4 E+ P" _- n& [$ R7 Q8 e" E0 z: o! D
{2 `& N; k9 m1 Q# \

1 {; H3 z7 b5 X% _  \" n  hi2cx.Instance = I2C1;' s. V2 E/ K) _8 a6 ?" x  L) o
  hi2cx.Init.Timing = 0x20D22930;/ W; X9 z& k. u5 X) y- c- \( Z
  hi2cx.Init.OwnAddress1 = 0;
  L- u% o5 V7 C( q% m; e  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;9 ^; c& M7 H0 b& k, L2 ]. g0 }
  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
4 K/ e- _" E7 ^8 `  hi2cx.Init.OwnAddress2 = 0;! f' F8 [/ q( M2 a. a
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;. w2 w( f! V" A
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
/ X1 [$ D( f% B; a) q0 z  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;2 q+ c) V' |, |8 t/ u
  HAL_I2C_Init(&hi2cx);
" x/ F: O7 m" k- C# k8 k: m) Q9 h% F" Y8 Q; Y2 I: D9 R
    /**Configure Analogue filter6 c6 M/ U" K7 }( ]" M
    */3 t( ?2 [' E6 v# ?$ N
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);( A+ w) p. h, M, ^1 m( ^: O

+ x& {7 f, H4 d" N( X}% t% r2 E. u3 u4 j* a# o

5 N$ V6 [7 x& O" m& E- Kvoid HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)' p7 p5 J! |3 m4 `7 y" M- b1 I
{5 H+ V6 F; v6 x

: R# n+ j7 G8 _. S+ K4 P  GPIO_InitTypeDef GPIO_InitStruct;
( b5 z& L% Y# j9 H  if(hi2c->Instance==I2C1)% K0 c5 c- \4 @: S5 g
  {
! N! h7 P, S: D0 C& g    /* Peripheral clock enable */
  q+ b5 V) P- \    __I2C1_CLK_ENABLE();
, {8 M& A* F" E. K4 u1 }  
' |; R" I1 T7 R+ P    /**I2C1 GPIO Configuration   
; h6 `; l, {" C' J% D! J' I    PB6     ------> I2C1_SCL1 w# I1 t8 U: s
    PB7     ------> I2C1_SDA) @4 U. w6 Q' H7 S1 d) R
    */
3 N6 B! s6 z2 r" f+ m    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;$ n" {! }" k3 \9 o" k' |
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;$ r! C/ E9 @& l2 B
    GPIO_InitStruct.Pull = GPIO_NOPULL;
+ P# x* R! S. n2 K6 c  m# A- [  Y    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;3 y, L; Q: t6 B) ]+ I; w0 G, [( [* l7 V
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;( M! d) e# I6 k; D( q9 G6 y3 H0 J
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
6 F! \5 S$ r& S+ [8 V6 _5 _
: u0 n" U* b5 {7 K  }8 m  i  J4 R0 a4 Z7 o
}' K& [+ w7 K+ p  m5 p/ v
- P2 w( v* g6 f& r- W( v1 n
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)5 f) u& E, x& Y# U* U  k
{# l$ N6 F2 ~0 L1 D7 J" N# J6 m
9 w9 ~: z) x1 ?  a- r: q0 R
  if(hi2c->Instance==I2C1)
: U9 U8 ?2 J2 N3 j  {+ |8 k+ c# k. \: Z9 i7 j
    /* Peripheral clock disable */
# a3 s, P2 T6 b+ X& p: N$ y5 K6 Y    __I2C1_CLK_DISABLE();: T9 H9 [& J' G, j" r
  
, X1 T- Y- Q/ G  c, G  [    /**I2C1 GPIO Configuration   4 {1 x& r/ p5 F1 i6 c
    PB6     ------> I2C1_SCL
: i8 u* k3 L6 p$ o    PB7     ------> I2C1_SDA
0 i. \; ]7 y8 q& {* Q    */2 J" J) }% \. m& N
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
9 n$ H! ]1 w7 A2 ~- w
: H5 L& _0 L  S) I  }
" p( u5 T, l7 A' c8 R9 P8 W7 e}
7 t6 p: D' U6 z6 ~1 U------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
, t3 y5 s) G  t% ~+ Susart.c
* E! p5 C* m% p" n: N' M' o, s: ^#include "usart.h"
; q9 r; p' g, _! V  l7 s( J. X4 I2 @) z- O
#include "gpio.h"! {# h. K& ?+ r
#include "dma.h"
5 }5 M$ j6 X5 q9 X' ]3 D
0 q# V0 I  o2 @/ ?  l8 l& ?/* USER CODE BEGIN 0 */: h. J5 k- ]$ @0 ~& F9 {. K6 M+ N
( E& b) |6 I1 C+ s  G
/* USER CODE END 0 */$ s6 ]* W: q* _

  V1 i+ Y6 s4 mUART_HandleTypeDef huart2;4 P! |( Z2 @9 D0 Q* t
DMA_HandleTypeDef hdma_usart2_rx;4 z( M1 w; p) J7 y1 P
DMA_HandleTypeDef hdma_usart2_tx;
; s( f; a. R+ H/ U- W/ a  `' j! S4 Z  _. V
/* USART2 init function */! J1 O' n7 N* {9 k
) {6 f: C+ E5 [9 y
void MX_USART2_UART_Init(void)
& a3 w" b* z  A+ K+ o  b{+ y, S! w- }5 [; P. _3 _

5 B( h7 e" M3 N0 i+ d# x  huart2.Instance = USART2;
9 t; |2 Y& ?( n* |- L3 F7 M$ m  huart2.Init.BaudRate = 9600;
0 n! g+ ^  Q3 A4 b8 R% l  huart2.Init.WordLength = UART_WORDLENGTH_8B;- c' E: w, ^9 _  N- J/ n
  huart2.Init.StopBits = UART_STOPBITS_1;& p5 I0 `6 I$ P5 v0 `
  huart2.Init.Parity = UART_PARITY_NONE;7 L& w9 N9 C/ L3 N  d# J8 L
  huart2.Init.Mode = UART_MODE_TX_RX;
6 r6 o. _3 P  N% D6 j  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
) U4 P3 z  Z, C* ]( A  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  Z  ~' A' V5 L! U  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;. C! Z' N5 ]" q  ]6 h, w
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;  ~9 ~, g% B7 ]" E. w( V5 Q
  HAL_UART_Init(&huart2);7 t! x" `$ Q  G2 ~& _( W" \, v

, {9 }8 q2 P9 t9 _7 U8 J}7 u+ d1 B7 G9 O. e

: }+ I3 k- X" l' Dvoid HAL_UART_MspInit(UART_HandleTypeDef* huart)* b. h* b* I$ d: W" }# r
{
* t' e; B( b/ U; X: M# _: e9 x, w8 E% L% z% q( B
  GPIO_InitTypeDef GPIO_InitStruct;' t( f8 S# |" D9 h0 i' v
  if(huart->Instance==USART2)) z: Y' D- R2 @. V* U- l
  {
; ]3 F2 H+ P: Z" J    /* Peripheral clock enable */
7 Z$ U& c% N$ T( v    __USART2_CLK_ENABLE();
# N' f. g: R. \# O9 k  & N: H2 K- A. ~5 h; [6 i" z
    /**USART2 GPIO Configuration   ; g4 w1 H; ^# {" Z
    PA2     ------> USART2_TX/ y# K7 N1 s5 y. l2 H# g$ h) e
    PA3     ------> USART2_RX$ N7 Y6 Y  f! d9 l* g# \
    */
- K! {0 i7 D# w2 v4 X( f6 {. M. Y    GPIO_InitStruct.Pin = GPIO_PIN_2;
% z) G5 ^( \2 J( t% E9 y    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
& P8 i5 N! c, T$ ~) m    GPIO_InitStruct.Pull = GPIO_NOPULL;
5 D' q! ~% j( A4 l( [+ z    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
- L8 M, Z( E/ i! K    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
% F+ m! m' d) _" c  L7 F" e( {    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);& z4 {+ k% z0 R7 Z1 K) Z
4 M, K$ K$ ?) j2 U5 p
    GPIO_InitStruct.Pin = GPIO_PIN_3;. q% P& L+ g% y" D/ v) Q2 q
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
2 D1 s. K) {; U  f    GPIO_InitStruct.Pull = GPIO_NOPULL;
9 S4 D9 z6 P2 b( N  ^% I; d    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;3 ?3 b/ |1 b  w0 w5 K
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
2 R5 i. o& ~5 `# o: \9 F    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
1 ^* k/ F& A* q4 T& z3 i  ~
9 j5 @) B. B; \. U/ a    /* Peripheral DMA init*/
% f7 [7 A% Q0 }- N6 n( k& T% D  8 L% u- e- V( t+ L' O
    hdma_usart2_rx.Instance = DMA1_Channel5;
. @  E+ b/ ~5 E  Z' X8 W    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;0 W' x: g* t- x5 d
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
9 z+ w9 I' l2 j# r+ u8 m    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  i, h# t, D) T: H0 a9 s/ o) I6 B    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;; i7 y( l* X& \+ y
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;- a0 s  r9 x6 C* Q& {2 O  S. m1 m
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
/ e; y- J1 l, s4 _    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
5 j7 ^( U) j5 H' Q9 q8 p# `# R    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
. \! y4 i" X5 {% f8 K5 G% r    HAL_DMA_Init(&hdma_usart2_rx);+ |2 ], c, J4 s/ m4 P# {0 i
! X1 ?# e, ~" x, i
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
/ f1 |1 y! M' G. O/ t1 L! n+ {6 l: N5 ~3 M
    hdma_usart2_tx.Instance = DMA1_Channel4;  @7 q) O! s' |+ w/ b
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;* N6 K/ h1 N& _) @
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
3 Q' |+ U! t% m6 L' |4 I+ E+ V* G    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;  u/ b+ S8 x4 i% `9 W
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
0 O3 d8 s' H$ b- X5 O    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
' i. f7 J7 i# g    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;1 h5 ~( W6 B8 f! W6 X" x/ e) V
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;7 i, G' M  Z% N
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
( p) m% j& U8 F8 o1 |1 _5 L) y" k! F2 y    HAL_DMA_Init(&hdma_usart2_tx);3 [' y. j" W% B: f2 O5 }
3 ?: j2 p! n1 ]  U: c
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);+ D" S! l+ y9 s* M
2 D* |! w) U  y$ P
  }5 E# x5 y, X' G$ m8 g3 h
}
6 [3 R2 D; m7 }" G/ u  }  m. v0 w% t' J" x" q5 @. h
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
* ?  ^3 o; k* a# s6 u{8 S, n3 s. E! a

- T9 _( h- w5 i0 a% R3 Q0 V  if(huart->Instance==USART2)* H* M$ `0 o! w- b
  {
6 U! W: F/ m2 v" L& y. [    /* Peripheral clock disable */
$ C* _! T( T# c* I6 Y& E) z    __USART2_CLK_DISABLE();) X' X, N6 `% ?" x, P5 Q  V. N! H
  / b: _) l0 _+ i# b# C& p  F) B1 I: ]
    /**USART2 GPIO Configuration   ; f# A. I, _1 T- l/ e7 K% B% x
    PA2     ------> USART2_TX, c. G4 B$ T% D5 h( }) N2 r
    PA3     ------> USART2_RX
' t' l6 J: I7 @2 Z/ d0 l    */1 o6 F  V: R6 k4 `% P
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
' H! o. ]* f9 E: B3 c  R; W4 T9 I1 F, j: Z
    /* Peripheral DMA DeInit*/5 a* I# e/ J' a. ~# w/ i5 `
    HAL_DMA_DeInit(huart->hdmarx);
7 J5 V- m- k1 ~. x; A6 J    HAL_DMA_DeInit(huart->hdmatx);
" j9 E; g2 p5 m0 k) @! a  }. M# |- n2 w+ j) A: J
}/ q- q6 M1 s# ~7 Q
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------- Q: Z1 w, \* }, f1 @
mpu6050.c" I: }( I% f! d* M* G" o
#include "stm32l0xx_hal.h"' @, V8 P- U* s' l; U3 }5 J! d- f
#include "MPU6050.h"
7 S* }- _9 Z& g4 N& Y( Z7 L( x% `1 a
//各坐标轴上静止偏差(重力,角速度): b7 Q! b& X" [
int16_t offsetAccelX = -195;0 L# A, L# l; Q' `; Q
int16_t offsetAccelY = 560;" _8 I2 Q+ Z" R' q# b4 ~# b, s
int16_t offsetAccelZ = -169;9 }3 K  c( o& X  A# W

: L; }7 Q7 \9 r9 n  q1 Bint16_t offsetGyroX = 12;$ H: j6 m& t' U, i4 _: g* v
int16_t offsetGyroY = 33;# \+ r3 f( X# Y3 x' I4 l
int16_t offsetGyroZ = 4;8 z3 X: w, w! ~3 ~: g

2 j& k, f) b+ l8 E( Yextern I2C_HandleTypeDef hi2cx;
: I5 a) k/ U# {$ M4 B# l( F, w
( P0 S! d8 E1 O2 U% M//**************************************
! S2 x( m1 E) k1 W6 F, R" A//向I2C设备写入一个字节数据
3 o4 c3 m0 M6 P4 E- u; i//**************************************
8 z# l$ F0 c$ I9 Evoid Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
. q, T4 _  j: v. p6 h# t{+ r/ c6 p  M6 _
    uint8_t rxData[2] = {REG_Address,REG_data};* k9 B0 C$ k) Z3 @# J* x# D
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)/ @  s4 S0 G* H) g4 K; {) [  s
    {
- s( U9 s# Q9 V/ t5 V# k        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
) W9 Y$ b3 J7 ?! k        {}9 j5 ]* H3 o9 O- A' f: Z
    }
% o9 z6 m8 E3 A; J}
$ R* }: @9 F3 m- W$ E//**************************************
; `3 @. W7 Z( x$ q' M' T; @7 n9 C//从I2C设备读取一个字节数据8 S& b3 {1 ^7 J1 V# X1 n5 p* m
//**************************************
$ u2 _$ i8 P) s* z0 F2 juint8_t Single_ReadI2C(uint8_t REG_Address)
) Q, R1 O0 q5 j* z7 r" v  N{7 L; T  B$ p8 A5 k/ N
    uint8_t REG_data;
* X( s0 t8 E; Q; Y, z$ V    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)3 U, O% v& z6 N9 [1 W. I( L
    {
4 i$ ]0 \9 @$ C5 X: r; M1 o# Y        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
0 G. x% K/ r/ S  a        {}
$ b; b2 O$ j0 {8 N- r3 T2 G% s    }; ^% q. X5 b1 I$ |0 z1 u
   ) A& r6 ]: n* t7 a- `
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)6 X6 X% C, N# }
    {
( ^3 K, n, w8 y6 R0 O        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
' W' G5 ^9 {  z7 _& D4 |# i% m        {}0 P- @* l5 l# l0 z- f8 D
    }
5 L, f$ A% h5 K! P7 z) B    return REG_data;& P; ~( N. S5 O
}! E; f* G2 }& }" m0 V7 o
//**************************************1 E( U8 P4 b( u! h4 E; x
//初始化MPU6050
( }% C" D! S, M0 j, A8 {: Y//**************************************& q1 P8 a$ s% ]0 u
void InitMPU6050()
  ]  o3 q8 d( [. \# [{9 h0 t4 \* g/ k8 M" c6 f1 L# R
    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
& c- |: _0 \  i4 I4 x$ C: S* t# v2 z5 R7 K! j6 U
    Single_WriteI2C(SMPLRT_DIV, 0x07);
7 Z% b  X) r' G! y3 B' c+ ?1 n1 @" O8 ]3 P* {) d" v/ `
    Single_WriteI2C(CONFIG, 0x06);
# s; A' g+ {0 M" i1 l+ n% o4 p6 H2 X) Y# h, K
    Single_WriteI2C(GYRO_CONFIG, 0x18);
- a; f. G/ g3 Z6 f7 Y
" Q0 }0 \( W0 |( b; ^: ?0 H    Single_WriteI2C(ACCEL_CONFIG, 0x01);1 r/ W* _. D7 e; _. h
}
) v7 ?& i& Q6 s7 w//**************************************9 k0 Y6 e/ C% r7 B/ {1 t
//合成数据
- T7 W  m" H% x2 q9 [# F7 M//**************************************' S4 n/ `! G' D& c1 P: C& [
int16_t GetMPUOutValue(uint8_t REG_Address)& z" {9 e# U' S7 `8 t. n
{* C8 h$ d9 h) E3 s5 h: B
    int16_t result;) v) Z3 Q0 M  u5 j* Z5 l6 I, L! E
    uint8_t H,L;2 b7 N8 Q" ~1 f' a! e1 g
    H=Single_ReadI2C(REG_Address);
5 I$ G- w% F1 a' j7 W    L=Single_ReadI2C(REG_Address+1);
. M7 T/ p/ L; I( G    result = (H<<8)+L;6 E% J0 E* \4 d
    return result;   //合成数据7 A" N3 D' S/ D0 V" b% M1 U
}  @( w- b& ]4 {, R/ ~7 V
) o4 U. v" K# h/ r
//**************************************
. L; d7 ?0 m4 W  _4 [4 v* R//取某一轴上的加速度数据
  W& ?% N' z" n//**************************************
* Y' Q8 B+ ]1 [0 r" Qint16_t GetAccelValue(char axis); X8 B# P* v+ N
{
! ^- j$ U: H: ~3 k. G% N! W    int16_t result = 0;. h4 @: R! {$ G* O# c
    switch(axis)
& g% E/ Y! }3 o" \5 x7 k! L    {
  G* S! y6 m2 x" f9 C        case 'x':
: k1 Y3 n  T7 K" D# M  Q        case 'X':3 h. O4 T2 U$ m0 i- q8 P9 D7 h
        {+ o2 `1 b+ s# R$ ~% c
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;9 x/ `$ ^" p8 [7 n) V+ v
        }
3 Z4 P5 \! _* t  F9 a$ R: V1 g        break;: e) P8 E5 U9 Z* R5 Y2 I, T* X
        case 'y':
8 `( K/ O" ^3 c8 b6 |3 `2 Z: B        case 'Y':! u- Z7 N# \& m
        {
5 g: `+ b0 c+ w! G( J1 K            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;: s- V( B0 E7 e" P0 A% u) Z0 J
        }
. t9 m! u" ~3 Y        break;
' T) f7 T# W1 D        case 'z':
4 R2 n  \! P3 h$ k- a, F" H% S        case 'Z':
" Z1 R- Q3 w- ?$ Q/ [' U. y8 U        {
/ ]% a6 U( U1 I. T4 U4 u            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
3 C) Z  t, s2 X2 ^( E; z        }! \9 L6 I6 ^  L4 j2 I* r, L
        break;% B0 x, a2 ?) T  w% }
    }7 E: @. Q% S0 [% [2 j2 G
    return result;
2 b5 R1 Q# c# o1 w. t9 |+ f$ @}# c5 }/ @) d6 n9 T$ y+ T* S' X  Z

; @* P# C) I, P# ^$ P//**************************************7 ?8 S! ?, e$ X& [( e9 D
//取某一轴上的角速度数据& X- ]  i# {8 \3 O2 s
//**************************************" X5 I6 I6 @" W6 S: I4 h6 |$ O
int16_t GetGyroValue(char axis)% n1 ~. \2 W7 I6 q5 N1 l
{5 I+ Z. ], A& W9 g1 t+ m$ r- z+ I
    int16_t result = 0;$ K8 \5 G' |# O4 ]! P7 V
    switch(axis)3 G% `. U8 g3 o. t8 ^
    {
4 r* ], N6 [- b0 W        case 'x':
+ u. {* K* e, ?+ p" J+ }+ f; y        case 'X':1 y  v  a& Q# O5 z0 u6 F( T) b
        {$ ?" d, b2 n9 V4 U2 i0 `. }. E3 f& t9 Z3 X
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
% K* i4 N2 e0 @0 E        }
+ ]# p+ i+ E: z* s7 t        break;, u. p! S  l: o! e
        case 'y':& y% G0 {8 |% F" |
        case 'Y':- B0 P% ?7 F7 A
        {9 h+ J1 @  R4 V4 O) P
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;$ L. z, I& B9 x( ~: f
        }
" C$ T. e6 [% ^& L1 J, R1 Z2 z        break;
' U" V6 x7 r, Z1 E8 [: e        case 'z':
2 e3 U) W. v5 U6 J  i! ^# L        case 'Z':. B: o0 S* H( v% B( A
        {
# f: w  f1 L# z  ~5 }            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;# n% S/ k7 A" y6 `
        }5 {: F. F0 n* l& n3 d1 m
        break;
" p) c0 o" ~2 m6 U; e. x) q    }
2 V& W5 T$ N; r% |    return result;
2 U+ u$ Z3 f& V* f# A3 {4 o}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
7 {& {3 f6 b* A8 j5 p" W# R4 n{3 g" i. l- s3 ~+ i

2 [9 O8 Y. p" b/ g" \* H  /* USER CODE BEGIN 1 */6 ^. b# q" S5 `* u

1 ^6 w1 z' D( ]  R8 X  /* USER CODE END 1 */
. \+ d3 D4 ]  }0 r& k/ s
, D9 B" `: I7 |# x4 _  /* MCU Configuration----------------------------------------------------------*/9 U3 C, j$ k" Q# m2 n
0 N& r- V: y" |
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
$ Z8 a4 t2 v6 `  HAL_Init();
8 \  G) l) X) X* {6 z, q0 ]9 S: u" P  U0 ~  Z) k
  /* Configure the system clock */1 t7 m! ?" g& D5 D, ?5 z# b! v. R
  SystemClock_Config();
- @8 O: f5 [  R" a0 d! `6 \, f/ Q# a! q
  /* System interrupt init*/
: R, E& w$ p6 N" e1 C) D: C: T  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);# i% Z/ g4 A  Y% Q4 n7 Y

7 z& H& o1 R, \( u4 S: r  /* Initialize all configured peripherals */
2 u" R. x# q2 K' e% m; v  MX_GPIO_Init();
. c/ {) S4 U2 m/ _; N7 l& d  MX_DMA_Init();8 Z) \% F0 M* J! {. y
    MX_I2C1_Init();% ]5 g+ x% i0 I( c
    MX_TIM2_Init();0 B' p- }4 E1 b4 G( I
  MX_USART2_UART_Init();
, V4 e8 a8 |0 f: ]: p( b5 p    InitMPU6050();
: N: x) V2 M1 c5 n5 i3 K
8 Q4 S4 m9 Q% k9 z  /* USER CODE BEGIN 2 */
: E5 \; G( j* f- I9 }6 e    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
3 B/ u" b* s- i7 a    HAL_TIM_Base_Start_IT(&htim2);5 o1 i% ]7 R  h. P5 {; d
  /* USER CODE END 2 */
1 O$ Q0 P) }2 B8 L: }, C  I) Y; c; {" s4 U( j+ I
  /* USER CODE BEGIN 3 */
* ?& w/ X8 ?/ Q* f1 }  /* Infinite loop */8 ^: c4 o% H8 M
  while (1)1 m0 l; o4 ^4 l+ z  R- F
  {
# h; v$ n, X2 A% b' n        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);5 f) D! D6 ~) m
        VisualScopeAngleOutput();4 b" d& t- w, K
        HAL_Delay(100);
  ?6 _( j  q  T" X5 v  }- x( O6 w9 w0 N: J
  /* USER CODE END 3 */) J. ?9 ?! P' a2 O$ b; }
* `$ V6 l8 g) }; e- |
}
/ N# e) K5 x/ i: c9 j+ S, N1 F: }+ Z- q: {' k5 @- }
/** System Clock Configuration
4 g1 S5 D/ V0 @$ N& Q*/5 ]9 c; c1 ^4 u9 U/ E; Q  m* [
void SystemClock_Config(void); q$ p6 E( `9 o- M
{
" I8 Q0 ]+ Z, s5 r/ c4 H+ b* Z7 B8 j7 f+ N: ~  W
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
1 j: c0 @( w+ L8 T$ f2 p  RCC_PeriphCLKInitTypeDef PeriphClkInit;2 s, v7 @4 ^$ t/ Y2 J5 [; U& A* K
  RCC_OscInitTypeDef RCC_OscInitStruct;
$ Y& H4 g3 }: @9 O+ k3 h
& b' E$ U, b+ l  X7 J! A  __PWR_CLK_ENABLE();% r7 o/ ]4 M7 K
- w! }9 j3 n3 Q1 V% ^, i7 S* ~; a7 C9 h
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
5 x. W; O: N# k: e+ G4 }
" c5 E8 p1 w; T) s* c  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
# g% N; \- _4 m$ z3 C; i* T1 l4 t  RCC_OscInitStruct.HSIState = RCC_HSI_ON;5 O7 t0 U7 l0 y$ R
  RCC_OscInitStruct.HSICalibrationValue = 16;/ k! m  _$ P- {- p  o
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
: h/ P# |/ \  @/ ~  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
7 s) `: e4 ^" D5 n, n  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
* R" M0 M# x: c+ R) v, X  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
9 F' e' F8 @' |  HAL_RCC_OscConfig(&RCC_OscInitStruct);; p2 U1 i2 a5 ~9 [: i3 `4 M
0 l, M. y+ L- N# g1 E7 x
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
/ v4 F2 S1 ^$ [/ {9 ]8 y9 |. H' y  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
9 z- |7 g# A. _; U- w# B& T, ^" \' e  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;9 P$ \" Y8 ~, A0 D8 S/ J
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
; V7 M# e( i0 x& P& s, \7 s# j- C  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
$ L4 \% n0 s6 s1 u1 q6 L9 Z% _$ g  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);+ h$ Z- M. z! |- P! c& x

2 @3 l* n8 b) P6 b  u- y  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;  p  R! D3 O0 c; I0 t3 X
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
& l' B, E: t9 y  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
$ O( r) L& }; S( P8 M" K
% C( M0 a+ K! [" Z* X! @  __SYSCFG_CLK_ENABLE();6 y" j* n9 U" M! E, m. t
0 g; t$ N# h/ n+ x5 Z1 v  i
}8 X# j1 A! o, R2 v

( ]5 \. I, I2 P$ z5 s+ M) N/* USER CODE BEGIN 4 */
( t( T/ D7 ~" _2 P3 Nvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/ u0 t3 c3 N. K* l: v- n; u2 F{  h: y" n6 ~# v! o7 A# z1 G0 o
    if(huart->Instance == USART2): P0 F9 U6 o* C' B, e. S- G0 U
    {
* c0 ^' [* j' c2 V% t- k( L        memcpy(txBuffer,rxBuffer,RXSIZE);1 X! [2 p% X; h! D# `+ h
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
+ P4 L- I2 G! u0 ~        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
& K: {2 O0 x( p. F! F8 E/ O0 ^    }
( m3 A/ `$ W1 s  n+ ^}4 M' @  S; X% ]  J6 a$ u* @8 Y

2 v3 q* W/ M5 i& s% kvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)9 }. N3 t0 f2 r* v8 p
{
8 }: Z+ `6 p( B3 t   
0 A. Q: H) U( E* E& ~& e}/ Q7 x/ z+ C* M  c( l( V! _- T2 h5 ~
( O, D6 a- }  @5 h
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)" S* s8 _; o( R" a5 E" I0 e  K; M
{
2 H# k9 R# W3 f5 R    int32_t GyroValue;  f% J3 E/ s% K& H
   2 D! T1 U; t, [
    Calc_AngleAccel();
1 }0 c4 T0 P' t2 H8 N    GyroValue = Calc_AngleGyro();
4 r) h/ G0 f" }: q/ S  l    ComplementFilter(GyroValue);$ A# L9 X7 u: g7 j
}
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
9 d; T  n% r9 q1 O8 |1 M1 c楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

! c% d& E- p. w  K2 o使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00/ l* y; `+ q# u5 r
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

8 q5 Y) M8 x# u: w  H0 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
9 K7 T" d$ w# M; J1 r如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。

& J# s0 b6 V! f1 m2 F- ?好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?: V1 W3 U# @) f: F1 \, d% \
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08! @% u: W0 h) x4 c3 N) a
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?5 ?$ o, [5 V# X8 d7 s: A
请问应该注意什么地 ...

5 y9 H8 S3 O. {, p- a4 |, F我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版