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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
; k& Y. a- i' ?% ?7 r-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------8 }: K3 O0 d) f0 U
main.c  S$ I4 h- i0 ~& ~) j: e
#include "stm32l0xx_hal.h"
4 i  y% ]6 u+ p# W6 O( A" s; |#include "dma.h"
( `1 _9 U' D2 Q- P" n#include "i2c.h"
0 {1 s) [6 q& C4 i; `) M. P. b#include "tim.h"# A4 P: \6 R/ K
#include "usart.h"& N# ~* r! a7 {( d- R: }* V, P7 p
#include "gpio.h". _* i( U6 n# f0 B
#include "mpu6050.h"
* \9 N" h$ B  e2 a#include "visualscope.h"
0 ^6 I8 H6 M; h3 z& s& G# T! e5 V
#include <string.h>
) M; Q% ?2 w0 ]* d" T( x% Q, @#include <math.h>1 s& E3 P# b- B/ G# v( D

- F6 `3 ]& I, N* t! W/* Private variables ---------------------------------------------------------*/
3 Z. d% W1 x1 I4 }( `#define RXSIZE 80 }! K& K2 B* h0 m! ]
#define TXSIZE 8' w# |0 h% V4 x
uint8_t rxBuffer[RXSIZE];+ c# |  x2 v# |6 R; }$ j" i$ X2 e
uint8_t txBuffer[TXSIZE];6 V- O" D  b; `
& V: G# O" T0 u
float Angle_accel = 0;7 A- c" O' y1 p" e& L
float Angle_gyro = 0;/ d) X& Y/ Y1 [/ j+ ~
float Angle_comp = 0;
) A4 p- r  D. b2 b0 h; n  Buint8_t outAngleData[10];# |% m' q$ {# v, h. P" T" n
/* USER CODE BEGIN 0 */6 q( f: h* s% U$ k( b/ H

6 ^: w9 A$ Z4 Y3 V/*---------------------------------------------------------------------------------------------------------*/
* ]+ c+ ?6 j7 E: w7 N( g/*  重力加速度算出的角度                                                                                       */; u9 C4 ~4 t9 ?5 I( w
/*---------------------------------------------------------------------------------------------------------*/1 w* w1 [, F& z4 X4 z3 X8 v
int32_t Calc_AngleAccel(): ]0 D  r; J9 n) S
{
; h# J. H9 N2 B1 q% w- S; T% h    int32_t value = 0;
8 V+ \) B( B6 K  |4 t7 r   
& t! K6 {; G9 K. w    value = GetAccelValue('x');
6 a" E- W5 Y4 z" v/ X  E& U    if(value > 16384)+ ~# h! v% f, z
        Angle_accel = -(asin(1) * 180 / 3.1415296);& S' m1 T( l$ W* [
    else# a- {! {4 Y% P4 e/ C4 ?
        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
$ k" u* M% |: a; t  S- l' }1 k, G6 |   
) e7 O3 T* N8 Z    return value;" H- l' P& m9 l8 Z) F
}
7 A. E$ j* M- s' H1 H6 I4 A9 T9 M- {3 H+ r% P" b; p; O  f
/*---------------------------------------------------------------------------------------------------------*/
$ V, O3 F" Q  {4 _/*   角速度算出来的角度(积分)                                                                                     */5 n  q6 [/ q1 B" y# Q& t
/*---------------------------------------------------------------------------------------------------------*/9 M% z6 p3 y/ I0 M8 E
int32_t Calc_AngleGyro()
# Y4 ~- u- l3 V5 _5 S1 C{
3 \1 O0 `$ }) L7 J# L- H, l    int32_t value = 0;% P  ^0 l- V7 k/ ?: u' P5 o
4 y2 ^. u0 F2 o3 W3 Q2 X$ V4 F1 L. P
    value = GetGyroValue('y');5 b2 `- F9 y6 Z7 ]7 V' A) Y
    Angle_gyro += (value / 16.384 * 0.01);
/ |, {, ~! t( ]% H+ @3 F: e   
/ Z  o2 k8 j  P    return value;
% o; x( `5 M- ]2 a5 S) n+ _}/ F4 `4 l  Y" ^5 k

. h7 x2 \4 e: v/ L, s/*---------------------------------------------------------------------------------------------------------*/; H7 ?) H7 q$ V" r
/*   互补滤波求角度                                                                                     */
  j! r+ A. C9 y4 g$ I) T5 k/*---------------------------------------------------------------------------------------------------------*/
# Y/ J% _1 Q5 u/ W& T; J9 Efloat ComplementFilter(int32_t simpleGyro); {) D% S" u. t4 |/ n3 C9 S
{# @% X9 S$ B. T
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
% z6 C4 \; v) v9 E; ]   
1 ?9 ]3 ?1 ?0 a; c1 A1 z2 i    return Angle_comp;3 S, L! x& {/ c1 p, \! x% k
}4 Q4 I  k0 p8 v: m2 j! ]9 A
6 q# f" N+ A4 \1 W; O7 a0 h
/*---------------------------------------------------------------------------------------------------------*/
& |  L! X0 Z2 D$ {) c' w/*   输出角度至上位机                                                                                     */
; }; O# Y4 f/ G3 \; ]& R7 W/*---------------------------------------------------------------------------------------------------------*/
% c" i: [$ l3 _5 ~6 P, O0 T& Kvoid VisualScopeAngleOutput()3 S6 H2 F* Z/ I1 z8 v, w  d0 v
{7 H0 E& _! p- W# f* s' j, M
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;, l/ q. O9 p, c, W8 ]" O5 q) u
    uint16_t crcValue;, D6 s3 J4 O- S; P  l) N. ?
   
8 X# u% k# l- f# _% m    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);  _, Z( y+ H1 Y5 a
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);. z& ^- h! p+ P
    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);1 J  M* |" A6 U5 b
   
2 W% w  j' B! I+ ?) E& ~7 |    outAngleData[0] = AngleValue_Accel & 0xFF;
4 c& V& o% c5 k' A; G* m7 M    outAngleData[1] = AngleValue_Accel >> 8;
: k+ c5 ?" I- @7 W( m    outAngleData[2] = AngleValue_Gyro & 0xFF;9 V. o2 T1 X) o! z% X
    outAngleData[3] = AngleValue_Gyro >> 8;
; L* ^, F' s- U5 X3 x3 s; D; V    outAngleData[4] = AngleValue_Comp & 0xFF;
% c2 X5 a) ^0 p0 G    outAngleData[5] = AngleValue_Comp >> 8;2 i3 I- l7 O2 w' Z+ V* h3 z3 k+ b
    //计算CRC  v$ z( p3 |" }6 \5 Y) D
    crcValue =  CRC_CHECK(outAngleData,8);
+ y: V6 z$ J  \' b2 G" k    outAngleData[8] = crcValue & 0xFF;
$ U4 @% ]  W5 L( M1 x    outAngleData[9] = crcValue >> 8;7 m9 I5 a: Z3 O+ {
    //发送至上位机% `6 T$ y3 j, \& j# M- i/ |
    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));
+ I7 q+ R1 f( t9 l}
* i5 ?, n" H8 l8 A" {/* USER CODE END 0 */
# o" N/ ]! W+ ]( b9 s9 r7 D) `! Y/ S0 p; `
/* Private function prototypes -----------------------------------------------*/
: @; K5 Z+ b# Y/ N5 Q. |void SystemClock_Config(void);! M' d$ ]/ s* r8 M. ]
, h) z/ S. O& T& O1 h! x
. J% @2 X; Z3 l
硬件连接图:; @) Y3 Q# P' W- i/ g
1.jpg
, Z" G/ Z5 d# B" `波形图:
5 _$ O( z5 J! I5 a9 J" w& @6 r9 e 2.jpg ! f. M, k7 ^3 y, m- f+ o7 E) K
最后加一个视频:
+ e8 z( f9 s0 B+ G* B# d0 ]/ FSTM32L053 演示
# q4 u& F0 K  B# M
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C* C% F1 h3 x$ u6 D
#include "i2c.h": V" Z5 v3 H6 D  I

# D2 q+ S$ l/ r5 l#include "gpio.h"
$ L  w. g% D8 y. ^( W) m' j, n: n0 r
/* USER CODE BEGIN 0 */# x$ ?& u, w! d; A
+ v+ h4 @: S' p
/* USER CODE END 0 */
2 M# N  ^9 |. k# J/ U- R4 @: M
3 u9 }, Y  j  ^: p. L- `; hI2C_HandleTypeDef hi2cx;
% q# u, o, _+ s. S4 e
4 R6 V/ p& P- v: G  \! O/* I2C1 init function */
6 b" @3 o- G$ r' \7 n$ Lvoid MX_I2C1_Init(void)' w3 o+ y* y, [$ x/ y0 I. J; }
{
1 B+ A  ~7 P8 V) a6 h* _& o
9 g* u0 P* R" T1 H2 S  hi2cx.Instance = I2C1;
/ _/ G6 L: |# _. N: {/ h3 N. U  hi2cx.Init.Timing = 0x20D22930;' r* ~( F* a8 H% O# n
  hi2cx.Init.OwnAddress1 = 0;
- n" L# p3 J* w9 ~& o1 _  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
7 p( O. O3 y/ X7 J* `  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
+ V+ z9 [7 W2 n' {2 j  hi2cx.Init.OwnAddress2 = 0;  k1 O% L) ?8 j! Z0 P
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;; D6 V& a: ^5 F  _4 U
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
9 c. _4 z+ m: w. c$ M: ~6 ^8 n  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
/ \! f! b# ?& k/ A  HAL_I2C_Init(&hi2cx);) T# x5 Q, \( Q1 ]3 s

) n* R' n' ~" m4 r: ^% W' c: A    /**Configure Analogue filter
  K* V0 E$ L8 f+ X5 H    */5 L8 n. o& R# b) o$ ^
  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);. N$ ^7 e5 ~3 o  S! X6 b7 \& o
3 v$ I, m. M1 d3 k$ K. u, N/ S# d" z
}
9 \8 O. ?0 q) X, J2 {" F; X) i' r# t; F) N2 t6 \
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)% y+ |3 h; D5 w; l* n9 P
{
& k/ l3 W  d$ A# M5 h  j% [$ G$ o$ ^( _9 M# [
  GPIO_InitTypeDef GPIO_InitStruct;
/ B+ a; s7 d% I' V; _) Q* k: h  if(hi2c->Instance==I2C1)
& d; d0 z" ~6 l1 N8 z" [  {; g3 P- I7 V3 ]5 U; H% w6 |
    /* Peripheral clock enable */
* ]: ~- J+ ?" k" G) x* l# L    __I2C1_CLK_ENABLE();; |' p8 p% Z, b6 O# g$ `( f
  
# `3 N# ^' c1 y, c: w6 u3 _8 f    /**I2C1 GPIO Configuration   
7 V/ F! c1 z6 k4 M    PB6     ------> I2C1_SCL
- L9 O$ C* u+ P9 G/ l: S# A    PB7     ------> I2C1_SDA( \% }+ V8 T' V( n! i' b
    */
+ F4 I0 q) p7 V! X& h, a: W    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;) h: r5 k, y- m0 W9 \7 n0 B! z
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;) H6 |( g5 v0 ^  q) t$ ~- f- ?
    GPIO_InitStruct.Pull = GPIO_NOPULL;! x: T/ B/ R8 S" }/ x
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
: d* r2 k, {! y    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;* \+ B( Y5 N- m3 q3 I
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
0 v$ }$ B. e$ ~% a: D9 t
' [  J$ s+ i% \9 ^) k- s  }& p" Y6 W; A0 s& e- e' ]9 C
}
2 W( X& r* E) g
8 n0 n7 b# B& l4 }void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)2 q# _% t( d8 [% K, j% X% _
{, X" z. |/ {4 i( d2 I

$ W1 g6 ^3 h( X$ N  if(hi2c->Instance==I2C1)
& w3 P% e! M! y& n5 _  {
2 b) d* x. t' `9 v; ]  a    /* Peripheral clock disable */: w& U5 v' K0 x5 X7 r
    __I2C1_CLK_DISABLE();
+ r/ ?9 P& b7 l$ ^  n  
8 @6 ^7 e' Q. J6 C6 [! r6 R    /**I2C1 GPIO Configuration   
( c# y  h% b5 N) a* H; o( s    PB6     ------> I2C1_SCL
" @' I' Q6 x3 I9 d. W0 `: A) x+ Z" U    PB7     ------> I2C1_SDA
  ]- A9 E$ h) M3 Y$ y1 Q    */
2 C2 E/ ~1 R% N& K    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
# i/ Q$ z6 B) ]' v" m/ {
' Y+ F1 A" Q" t) B  }: u- S; N1 F/ L5 x# p0 \
}
' X" G' T& E) w* X------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------& F$ _$ r8 ~" G7 U
usart.c' H+ w" Q3 C' h) ~/ }
#include "usart.h"3 y- [) b8 U3 q. k' Z3 i

2 k3 J( z) w+ ]0 l#include "gpio.h"
% M  I% P& [6 g#include "dma.h"9 S; E! C2 }& W4 I; L" O2 f

0 M7 l& F) f: g5 t  t- A- W/* USER CODE BEGIN 0 */
8 \- ]* O4 w" V
% f/ ]+ [: ~' q( h/* USER CODE END 0 */
  z( r4 [, O. f( L8 k/ d$ h
8 i: T% X1 p; A4 [' E% KUART_HandleTypeDef huart2;
: I, I+ ^0 j/ e! F6 iDMA_HandleTypeDef hdma_usart2_rx;
4 u% R+ X/ P7 k. |DMA_HandleTypeDef hdma_usart2_tx;' h, O+ s* F7 H; e8 d& j+ v! Y
0 v! _% Z  x' Q( m  P" j
/* USART2 init function */" p7 R! J" H; `

6 o3 u; x0 p) Q- Kvoid MX_USART2_UART_Init(void)
7 l2 W* L9 A8 q9 [{
8 |/ m9 [- _% m" Z  i& K0 _6 J- q+ M' O/ ~! a: s
  huart2.Instance = USART2;
6 _4 J3 i& F& {  huart2.Init.BaudRate = 9600;
  I! R" D% @- `% U5 T% @8 C  huart2.Init.WordLength = UART_WORDLENGTH_8B;
0 ~+ N4 o4 j; M0 K( R) @; h  huart2.Init.StopBits = UART_STOPBITS_1;
! x6 Q! F5 E( W& g  huart2.Init.Parity = UART_PARITY_NONE;
7 h. ~$ g! l0 R% H. H  huart2.Init.Mode = UART_MODE_TX_RX;
$ G! Z$ h; s; L; @. b* l  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
& M( F7 R8 z+ Q* _  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
. _7 R8 r+ g) [, }  C  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;7 r& W! @8 p" w$ b
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
2 R, b; I$ r' a: S3 o  HAL_UART_Init(&huart2);* q3 ]7 k) G% o# q; {

( y  e2 l8 q! y3 @2 f, d8 V! n}
- u1 X; \3 i; o* l: b- X
* ^" g. T+ j2 I7 G- m+ ?" ?void HAL_UART_MspInit(UART_HandleTypeDef* huart)
. t% r2 v: M$ g4 |{
0 @* m4 k' L" x4 l) ]8 A1 k5 U
) E0 }; L! W' C& T  GPIO_InitTypeDef GPIO_InitStruct;: \  J* _" F& F$ e# Q/ ~' n
  if(huart->Instance==USART2)
! X2 X) }- Y' T( @  {
7 d1 ]9 ]( C6 z$ p$ V    /* Peripheral clock enable */3 ~0 x8 L2 ~& \9 ]7 f' t9 T0 d; c# R
    __USART2_CLK_ENABLE();
7 [* e5 a2 `6 Y# q' B& l8 ~  5 d! ?# p9 k3 ?2 A9 X, H1 p
    /**USART2 GPIO Configuration   ( e: Z$ ]0 Y3 s6 U% p. U. ~
    PA2     ------> USART2_TX
, P3 e; R% Z& ~# U! I& {' |    PA3     ------> USART2_RX
  V) K# n. D: A. \% R    */- a, T' x5 c! @3 D! _1 d, w1 }
    GPIO_InitStruct.Pin = GPIO_PIN_2;& @) o, ?- k/ }. w; d; x& P$ e3 H
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
. z; \- m( L3 ]( Q" L1 J) w& |, |    GPIO_InitStruct.Pull = GPIO_NOPULL;* M- G0 h! f4 Y
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;' N2 E9 y2 E8 _7 O& N3 o
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
. i/ J% k: h; ^/ b    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
. _0 D! S' F+ S1 J
/ b4 z* n" ^0 u& G, N* E    GPIO_InitStruct.Pin = GPIO_PIN_3;/ `) I1 P1 R. w, |
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;/ i  ]1 j: U+ J: x6 G  j5 O6 e
    GPIO_InitStruct.Pull = GPIO_NOPULL;
; p( B, B9 l$ I3 s    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
! F8 ^' b7 H: y. n* K. K% D% q# P    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;& F/ P1 w3 c3 m0 b7 Q
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);6 K8 ]5 q$ x" ~8 e

' M6 ]& L8 R. G: f: ]' [1 r    /* Peripheral DMA init*/) V; H: J! @8 N5 r$ [" z- n" N+ H
  ( B6 T1 q$ ?" ]& z. E
    hdma_usart2_rx.Instance = DMA1_Channel5;: N' ]' d' l; \
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
% w/ N; K7 m; d- V' t8 V6 Q' W    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
; R; i2 x% R8 U1 a    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
" p. S/ f# z9 q$ X    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;/ d2 H  Z$ c  N4 w5 {. l
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
3 x/ G7 d6 q7 O2 y    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;" Y+ i. E7 k4 E& c
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
4 ~& `. z+ h) j7 t' m$ p: t    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
$ q# t. r, c( t    HAL_DMA_Init(&hdma_usart2_rx);
6 k8 t( P% A3 Y, ^6 [, l9 R" M9 j- ^, o/ X
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
# q  m5 c  V! I: s( D2 e8 F7 s: G/ n7 k: j
    hdma_usart2_tx.Instance = DMA1_Channel4;$ e( x! H* w7 K$ g, |/ S# B. Q
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
4 ~9 l5 K9 J2 ~  q    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
1 h1 ~* B; J7 N5 ?$ ~' c  o    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  S+ ]8 w1 v$ E    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;, I! L3 E; v  S
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
0 r3 N' j( M% [1 K+ l) i    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
6 |" Z7 Z$ {0 g) W    hdma_usart2_tx.Init.Mode = DMA_NORMAL;4 C( A+ I& D7 e7 R. j
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
' o9 ~3 F- @' ^' y4 \6 Y    HAL_DMA_Init(&hdma_usart2_tx);7 W( Y- l9 ~" g: I- A

( F- ?# e0 v4 M    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);9 d( k$ G* {. `7 L& R' b: j
9 s+ o, Z) M% J' t
  }
2 P& y& ~2 M: |- e' X; p. F}
% j# Y, ]7 W2 `3 n) {- R8 d; J: G, |
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)/ B3 [" u  S+ `# Q3 A3 R3 T+ s
{
: H8 W4 a  [4 M# Z7 S- ]. D- f0 }. t7 w/ I3 Z
  if(huart->Instance==USART2)
, @: q. z/ A0 V" b% S6 |$ l) [' R  {
7 A8 g2 X2 s. `! S9 U% z    /* Peripheral clock disable */" k6 e5 Z% M9 A7 N# Y
    __USART2_CLK_DISABLE();
# w- D# b  R8 {/ z  % A9 ^' ~5 {3 u  Q
    /**USART2 GPIO Configuration   
6 r0 ]. Y" p, K% n9 A3 h1 h/ f$ i    PA2     ------> USART2_TX
5 Q! V3 H% B/ z; c6 o    PA3     ------> USART2_RX
( E; M! P0 i+ `    *// y/ X, ?. ~! f
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/ a" _' i# j' F1 T
3 v+ C5 Z  G5 A; p  r    /* Peripheral DMA DeInit*/
. }  w. Y7 V$ {( e    HAL_DMA_DeInit(huart->hdmarx);
7 |  G% F. u7 J: @7 }1 Y% u& g    HAL_DMA_DeInit(huart->hdmatx);# F1 G! I  U9 [- ?5 L1 M
  }
$ S) v1 E% F. F3 a7 O" }7 \$ d}/ r% e: }+ D( j0 E, [. ^: j
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
$ r0 g& G) a% F; V4 jmpu6050.c1 C9 N/ q: p) h  F
#include "stm32l0xx_hal.h"
* K3 M/ w( c$ s$ A* I#include "MPU6050.h"/ `2 H: F- F8 k' D" E6 N$ S
& T" D7 K. |$ O; X! h! F  s# q3 L% V
//各坐标轴上静止偏差(重力,角速度)% h8 L+ E. E( z; Y  u& p
int16_t offsetAccelX = -195;  p; j$ L4 ?, y2 \& h7 A
int16_t offsetAccelY = 560;2 P( Y1 w9 l: a. A8 d/ n3 W* o
int16_t offsetAccelZ = -169;
) b! p' K- U! B$ c5 |! o" M& v  D) u3 X8 T2 d
int16_t offsetGyroX = 12;4 K' x) J1 t2 N! a9 Z
int16_t offsetGyroY = 33;& Y; n' D# _0 ~  `' {. D
int16_t offsetGyroZ = 4;
% T5 `! y+ E. t2 \4 q1 f: a) b: J2 p, v9 B. J
extern I2C_HandleTypeDef hi2cx;
; s$ }4 A( o, W8 {8 e" j& S& \+ i8 W# [$ e/ _9 ]- J$ j( D3 l
//**************************************+ B0 F- w. ?' i& C( G3 m2 @
//向I2C设备写入一个字节数据
) V1 U0 O1 j( B& A//**************************************/ O4 u' a7 b4 }+ P
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)4 V3 X% H; P* @
{
0 |8 z  ?1 i% r5 w; P: B  Q    uint8_t rxData[2] = {REG_Address,REG_data};" I7 o1 K9 E" f3 I/ L; e  |
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
% _( J8 L* _3 ~( F, l    {
, R. A$ C! f2 J        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
/ @7 e' l/ ?$ X  k7 \: |        {}8 l8 |2 }1 Z; G+ P$ O
    }* E" C: x  l5 k
}
4 P1 M5 a# G) K* W8 b//**************************************  }& B, N2 I0 N+ ~
//从I2C设备读取一个字节数据7 v  O! s  _8 }0 f
//**************************************6 w9 M- ~5 T6 |- e& G
uint8_t Single_ReadI2C(uint8_t REG_Address)6 x, i- A  s0 W& `1 G, C
{& C! p& p) t* u# F6 ]0 _0 B  j
    uint8_t REG_data;( z# T% _* J! x* U  D7 B
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)/ d) b" \7 \, H4 P, P) n
    {
( F& x4 B8 ]. S) a: }        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)/ Y) X1 F& i# e7 J
        {}
5 G5 q6 M' \+ `$ V7 u/ U    }# `& e1 k6 \8 R- y9 i3 X" b
   
; A$ q9 m1 s6 I- @7 K# b    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)' y7 J( b  E2 n' {, n
    {
4 y1 b" u# q6 v        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
+ J6 G( D6 W. `7 a5 d3 z  r  X. M$ a9 [        {}
& p2 [9 V2 k8 H) N5 ~, N    }- q$ \& o0 n0 E& C
    return REG_data;% _( z3 l7 R. |" ?, s% X
}! ^; p1 J0 g  x( J4 e+ z
//**************************************% D( Z- C  ?7 ]
//初始化MPU6050  O4 ]+ S4 L# g6 s7 A$ s
//**************************************
: z; z* i8 m1 |! m8 a* Gvoid InitMPU6050()8 L& @$ R7 U6 `3 J2 |! `
{
" H! h6 t6 Q, o7 s& q4 ~$ E- t7 B    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态
0 F9 d' o$ m. A$ d. q" v4 g# K# X& m0 t
    Single_WriteI2C(SMPLRT_DIV, 0x07);
3 h- L! K9 ]/ s+ Y5 S" f/ f' R5 o7 u. N9 k( |) g0 ]" H# P: F  `* |
    Single_WriteI2C(CONFIG, 0x06);6 d6 ]/ R- r. c1 c

# X& x' I# d. @    Single_WriteI2C(GYRO_CONFIG, 0x18);) [& Z% J6 C5 _- t! a/ L9 s5 J, u; m
4 W* S* a3 G1 q+ v) b  ^
    Single_WriteI2C(ACCEL_CONFIG, 0x01);. [" P: Z( f: u$ q
}
- x  d- p; O5 B//**************************************, r6 z! i7 [9 i) t. D3 U
//合成数据2 ~1 r: X. J; W3 g) C  k) V7 d' |
//**************************************- F9 K8 t, B5 J8 P' u
int16_t GetMPUOutValue(uint8_t REG_Address)
  B: r$ V$ Q9 G" v6 r{
& Q1 F! L# s3 c; e2 W    int16_t result;1 J/ a6 f* z% G  Q" [* \5 K! \6 b
    uint8_t H,L;
+ t9 {& W& y) [, }    H=Single_ReadI2C(REG_Address);4 F6 o: X( @/ ~7 h1 g' J
    L=Single_ReadI2C(REG_Address+1);
, V  q- m: Q  r) F: D    result = (H<<8)+L;1 u- J0 |0 [1 {5 d. d) v5 q
    return result;   //合成数据+ ^  t) c0 C! `3 u
}2 X: u$ R! h# K
/ a, V4 J7 z8 M3 Q% ^
//**************************************
9 B2 n# V( [: R//取某一轴上的加速度数据
' `/ q& j& o! @4 J4 \//**************************************
) t5 A& m( S# C0 \1 ^9 tint16_t GetAccelValue(char axis): K& P9 |  W. Z4 t
{% N; _! t+ s' n
    int16_t result = 0;
4 s% o! e( y- v. E0 j; A    switch(axis)7 T3 R" d- O* O7 E2 M) j) Z
    {- c. O1 Y( k$ H
        case 'x':
9 m. f7 C5 v* Y  d' |        case 'X':
# O  B0 h5 `7 u. g/ k2 X* T3 b        {$ ]1 P( f* ~! F' Z
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
3 r% a$ b1 w3 l- o        }* D7 E3 Q5 w# y
        break;
6 j. e9 T7 v" f/ F4 f, g% x/ X        case 'y':
6 E& }: O+ M' J        case 'Y':
" S8 v: o+ p1 F( s        {  z& C* \8 v; ]5 ?3 c: x
            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;2 o4 {7 Y8 E. O' q
        }" W) |% E* {- C" z4 }0 u$ F
        break;, y% @5 x$ j4 K9 q: P
        case 'z':, Z! C! w0 z$ Z2 u8 R
        case 'Z':
# r) G! I- P+ W0 J9 i. k  `# F        {5 ^3 `  S/ H! {3 H
            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;2 m* g, O8 y6 S& @  A  f; v, W. G
        }
" Q& X0 j1 L$ {7 J* N        break;; R4 @6 A5 h4 K8 }3 r  `9 |
    }% \3 C0 m; y6 b. F1 m# D+ d7 s
    return result;
7 Q/ J. h% M* s: g, E}; f$ }- P$ b3 {3 b) ~
$ a! ]; N. K) D% N& ~3 a% q
//**************************************2 M6 e% Q  M0 d
//取某一轴上的角速度数据9 a& u& ]# q  `) C. Y4 N
//**************************************
# g3 ~+ i/ C; |int16_t GetGyroValue(char axis)  E2 O1 `  a8 X' j+ B
{; o- b' `( |& T2 T3 A, m
    int16_t result = 0;- M  O; r8 f" r/ ~4 l, q
    switch(axis)
6 I4 @6 {/ d3 N! Z/ @8 [% w( ~    {
4 k* ~6 E1 z8 s" o" `' K3 T        case 'x':
! A$ }, p% @! G        case 'X':
* Q+ V2 s! M* }, Y( r( s% _" W; X        {8 p/ U/ i* M$ t. P1 j
            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;6 H4 U9 H6 T) z+ q" S
        }2 k" a4 J  b: x2 R8 w( N+ _1 K
        break;
/ s* u0 W  K% o) u) d        case 'y':
) m; m8 p: j$ {4 u% k& d        case 'Y':
/ X* I$ Q% _( z2 G& P$ w# `4 x2 g        {. N# b; q, V% R1 j4 c: M
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;' o7 _% ^' R( Z& I
        }
# g. S& E5 y1 x/ i        break;0 Q. ?# v3 i! g. p3 Z6 M
        case 'z':$ A" T: F1 u( d+ Q
        case 'Z':
( U; J7 n! E4 k7 T# s        {
6 Q- j( g( v/ a4 a+ Q            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;: P% \3 S, A3 V; ~0 |4 j. ]
        }
0 O! H8 U, {3 A3 {" D        break;
" y& l$ n3 p( y8 m, p8 [3 j$ q$ ?    }  H6 l& K  j7 J6 e9 o
    return result;
# z4 _4 b! ]- X7 W5 n/ d}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)0 m8 q: i4 b) x* `
{" y) I2 r4 @0 w8 f5 l" F/ ^

1 j1 O6 k+ K. W7 c+ T( f4 _  /* USER CODE BEGIN 1 */
% u6 B# g4 |' N6 t8 @; k1 g6 Y; ]; l1 O  Z% \( I2 [
  /* USER CODE END 1 */
& S9 s" w8 q3 R: d0 }
3 e' v, _5 y* m0 v  /* MCU Configuration----------------------------------------------------------*/8 d9 O) v3 }! E5 s9 r4 n5 a
7 |& B& I: g. N9 V/ P2 [. y! A. h
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */4 ]# V8 e. z6 `) @* @- P1 A
  HAL_Init();7 o  ?$ {- P' Q8 a2 p$ |

7 B; A* g# O9 A' i: y/ ~( k! i( }  /* Configure the system clock */
% \# W9 f7 J% ?/ [( ?+ A  SystemClock_Config();
" U0 {: W5 H# a" w8 X+ J; n5 U) b4 S) P4 W4 |) u7 |6 ~
  /* System interrupt init*/
" x, w6 I5 [& Q& U4 g' K" e/ B# C, X0 [  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/ G8 U, K; X; Q. r+ C) g0 d2 Y. w
4 C% c  y+ W% K) ?  E' X  /* Initialize all configured peripherals */
6 Z# G# m: g. d. R, b0 @( O& E  MX_GPIO_Init();4 A; q. S* s! n. r2 }
  MX_DMA_Init();: e. C  i/ L2 L5 m& y# Z' a* E9 D
    MX_I2C1_Init();
! l6 P2 {8 W4 j( q3 g    MX_TIM2_Init();
+ A) r( j' Z% C$ k9 d3 \+ H. E( E8 d  MX_USART2_UART_Init();+ @$ t. Q' `  m& E; t% N
    InitMPU6050();
9 y; T4 z3 {4 Q1 i4 n/ |) \; t
* ]9 \; U. x3 g. U. |- R- N  /* USER CODE BEGIN 2 */0 h1 ]" [3 ?* h6 W2 c
    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
. P! ^. ~1 _! o    HAL_TIM_Base_Start_IT(&htim2);
  R/ |% ^- ?, o" U$ \7 Z  /* USER CODE END 2 */3 n9 [- T, B$ W/ v% L8 p1 U' M/ Q
/ e8 i- H: m/ p  m3 ?5 v
  /* USER CODE BEGIN 3 */
4 U/ `+ }# b7 S+ d1 [; B0 J  /* Infinite loop */, }2 r9 }& j6 C7 `1 w* q  U9 b
  while (1)
) h) ~7 L6 J1 l  x; d  {
7 b+ f# p4 Y  B4 \        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
1 q" H2 i, T1 _4 D' B' O        VisualScopeAngleOutput();
- d  _% Z# W7 f% C3 P% H        HAL_Delay(100);
, u5 O' D. E( I/ X% Z  }
6 ?* X$ D- H  z0 V  /* USER CODE END 3 */8 E( j; w5 f. Z  X( J% p& ]

$ t) q0 c% ~8 ]/ f}
, o8 |$ n$ L, Q0 c& ?
$ b. T8 M5 w7 T0 Q- Q. U* q; H/** System Clock Configuration. E" k$ G7 \* x  e
*/; j5 X; I# o/ Z' @0 G* E* s- J9 h- C
void SystemClock_Config(void)
0 E' o: \* ]; R8 k  @: z{  s: Q* h% }& T9 k- D' _
3 r. D) ]5 J, ^+ g, h9 l, D
  RCC_ClkInitTypeDef RCC_ClkInitStruct;. B1 c: G* f2 J8 G6 H
  RCC_PeriphCLKInitTypeDef PeriphClkInit;5 A- T7 F. {9 S* u7 _' z
  RCC_OscInitTypeDef RCC_OscInitStruct;7 U, g* E- |7 i5 [
3 |+ _* Q! r& X# }2 b9 P" ~
  __PWR_CLK_ENABLE();
% d8 a3 Z: ^- S, L  Z$ s# u* k
- c. W  L2 X1 c* f) }  g  s  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
9 U) P, T, Y  _, f. [$ P4 E! B; E% E( Y7 G/ f" {0 C3 \
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
; W2 Z, a+ U; h+ h  RCC_OscInitStruct.HSIState = RCC_HSI_ON;0 p6 k" z8 z: S# v5 A
  RCC_OscInitStruct.HSICalibrationValue = 16;) R; V2 g& e- n$ L: D$ h& `7 {. k1 @
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
3 i) d% l' p% N, ]  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;. J! h# a5 m& q) H
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;# A1 x8 [5 a7 n8 |$ d4 Y) b% e
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
2 V9 v7 T% g3 s; E: `  HAL_RCC_OscConfig(&RCC_OscInitStruct);5 r9 e9 c7 k( K$ S  D  D1 u" @
5 e/ r% x8 i& I* ]# ^
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
6 P6 b! }& x3 x6 b  {7 p+ ~  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
; Z7 ^8 ?; z. @# J  l& D  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;  B, L. `$ g5 A. k/ ^. N
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  E: X- {# t  F. |. E3 V  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  f' k2 E' _5 G$ h) z6 i8 f  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
; ]+ _$ D& X7 L. e8 z7 A+ K0 H- R1 m- H) \+ S2 V0 o( Q* y5 L9 Y
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;' q1 \0 B4 t7 u, X! W5 K. n2 ?) \5 T
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;$ }, @  U% ^1 |+ l
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);8 Q6 p6 \, Q8 A6 x, i

( l: w% E. L& c  x" U8 W2 I  __SYSCFG_CLK_ENABLE();
: g5 k- g9 E/ M7 G, W
0 A5 _9 F$ U" j5 h6 x4 }/ _" \}9 ~6 W, A/ y1 J! r6 w- |
) O' o8 v, A7 }. j
/* USER CODE BEGIN 4 */
$ H% P" \& g" s6 ?6 cvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/ h" F1 r( }  V8 N# W* |$ l{
2 a8 k$ _* C8 H" m3 z) {% W  ~" k    if(huart->Instance == USART2)
0 h+ K1 s5 ]4 D* j- c) |5 v    {
) K+ ~5 h' L' I' A        memcpy(txBuffer,rxBuffer,RXSIZE);" o, |/ ^) s5 [* O8 q* _
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);* O7 m$ J& f( n' z$ k
        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);6 F; b  j- Y2 z& T# e, Q$ E, D
    }
% c: t7 N* \! ]: y6 n}. U% z, `- Q7 G/ e1 {% X8 \

4 u! t6 q/ G1 @& Xvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
0 O$ R3 g2 c* u# Q, P2 `9 m$ Y{
9 t! ?5 F0 d" {' d   
( l7 b' z; U/ D, x" P7 b}
$ Z9 a2 \8 V  i# A4 F5 ?
- w; y1 P. j( u4 `& M- q3 h: W8 Uvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)0 o! U' {# N' w; E- Z+ U! e
{
! G# g8 q2 z: Q4 l0 l/ U& `" i    int32_t GyroValue;
( Z% C: v- }- a4 Y% E# D   3 H9 q/ @* x( n5 i, b
    Calc_AngleAccel();
6 z: e! y* U2 O9 |8 k, j    GyroValue = Calc_AngleGyro();' K- U3 }/ Y  f1 x) v7 A% j
    ComplementFilter(GyroValue);
: |. q! H0 k$ k1 a}
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
/ @* F" B* i2 ?4 u# s2 t1 _& }. Q楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
9 H: e5 K6 c; K/ n
使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00
7 @8 I+ J/ Q2 r/ R! l楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

/ k% I8 c/ b; [' m8 u) f2 |( D如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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* k( B. Q2 B; |
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
) n$ r  r$ Y0 o1 s( D! M
好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
1 R" s2 h- y6 Z0 \& o1 z请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:088 f' [) B" w. W% ?$ ^# J
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?% o8 l( X" P/ b$ u
请问应该注意什么地 ...
+ _& h0 f' H  Y5 j2 ~. k! c7 ]
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版