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

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

[复制链接]
党国特派员 发布时间:2015-1-6 13:21
拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:
5 B, @: ]0 l: X1 l2 ?; r-------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------
1 N: P* J! z7 n8 p  K* Vmain.c. k' U3 x  F2 n5 k% S. m
#include "stm32l0xx_hal.h"
1 |' y' V; L, Z3 R#include "dma.h"
$ Q3 P2 v5 V3 B) T- y( F. f7 s#include "i2c.h"1 R# Z/ y, Y$ @5 G5 [3 Q( r7 l0 C
#include "tim.h"
; ~8 I& P! y. `. |5 V#include "usart.h"
- g; k5 o. h0 ^' j9 I7 i#include "gpio.h"$ X0 ~9 f# m; a% J9 |0 d
#include "mpu6050.h"* b- m* K. D, O6 G# t
#include "visualscope.h"7 @+ [6 Y8 F( Z0 K, A

1 C* O: E, F8 {' k1 A#include <string.h>
3 U4 [+ Z1 k( v! X) _$ D#include <math.h># }# @5 W  p* y5 r* x2 q3 |

* @( D4 p) j- S6 R8 w9 ]2 t: B/* Private variables ---------------------------------------------------------*/( k9 d; k/ X; Y* S% S( [' N
#define RXSIZE 8/ Q. @9 [3 d% \; C- M
#define TXSIZE 8
* ?$ N, O9 o' vuint8_t rxBuffer[RXSIZE];7 k2 A% c+ C8 s( U
uint8_t txBuffer[TXSIZE];
$ l8 W8 ?, {7 J0 p% l" U1 J+ p1 y2 w0 K/ M7 n
float Angle_accel = 0;* B! u  U& Z# B/ E) g1 `( U
float Angle_gyro = 0;3 q/ T4 K. x5 }, m3 n9 c
float Angle_comp = 0;
: x5 F( C1 p( b6 m! y/ Luint8_t outAngleData[10];2 w- v1 e/ h7 i, F
/* USER CODE BEGIN 0 */, n+ B& t% o) w& s! g5 W
% h& t" m: d* ~3 D% f: U
/*---------------------------------------------------------------------------------------------------------*/* B9 @, |4 q3 }9 P8 }. y' d- T
/*  重力加速度算出的角度                                                                                       */
+ i4 g$ x! _  s7 i/ D5 ^/*---------------------------------------------------------------------------------------------------------*/( R- p4 Y2 q' t
int32_t Calc_AngleAccel()# P6 H+ f9 W9 f2 _2 G
{& ~. H: x; \/ l5 H  v
    int32_t value = 0;
0 m) y! V# Z5 a* ?$ Z0 ~: J   
+ q3 _4 V  p, E4 B    value = GetAccelValue('x');
4 g( ^9 p; q5 t! F3 X    if(value > 16384)0 [8 `* j* C6 l% H
        Angle_accel = -(asin(1) * 180 / 3.1415296);/ ]$ {; K7 y* P, ~2 k
    else
  L) J( E6 `& A5 V+ S7 Q' U        Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296);
' k; K  U" x2 \+ ^    ) a% D" t; |6 p
    return value;
( y% F- C. ?3 Z4 t$ h}$ F# b" O' @6 J! I/ o5 T

2 g) A" z! }8 ~; J5 b- d8 R* R; w( V/*---------------------------------------------------------------------------------------------------------*/
0 d1 w) ~' L/ {/*   角速度算出来的角度(积分)                                                                                     */
3 U* W/ }% H0 R+ x( z) R6 s0 Z/*---------------------------------------------------------------------------------------------------------*/
# J6 i, s7 a% @' c$ g" wint32_t Calc_AngleGyro()
' C) C8 o7 \/ L) e0 r" ]) {{
. V8 I* D/ D" Z0 n5 F  }7 W    int32_t value = 0;& u8 {) N8 t- R9 W

6 c2 C1 U( M$ s# X    value = GetGyroValue('y');% y+ s2 M" A1 x5 n& D* `
    Angle_gyro += (value / 16.384 * 0.01);
; a/ c$ c6 J( A' n0 N* P# z+ B6 m    / v- Q8 ~: X8 i% D; b; ?
    return value;7 Y/ s' ?( a8 v! i' J2 r# V6 c9 A+ W/ a
}
" x! ~) ?- M* w2 K/ {
$ ^$ V0 h+ @2 q3 X) K/*---------------------------------------------------------------------------------------------------------*/
9 A3 p7 U: x; @/*   互补滤波求角度                                                                                     */# r! x. {  m5 [, J
/*---------------------------------------------------------------------------------------------------------*/2 n' F1 D5 Y! d. A( i4 E! R
float ComplementFilter(int32_t simpleGyro)( [- v% X" d, c0 v# G! c& ?
{( P1 x- H7 P( ?3 V
    Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;
/ E& t' f* h) s; a& w/ D7 L   
, e0 B0 V1 y! J7 g: k    return Angle_comp;( ]4 Y0 X3 D; {+ a) z6 U
}8 E  L5 `2 ]9 Q" \3 T+ ?

5 M4 k! o/ h9 X6 K6 e+ O/ L+ f6 k/*---------------------------------------------------------------------------------------------------------*/- m7 P$ V. c/ Z+ D+ W2 Z* {
/*   输出角度至上位机                                                                                     */
  J" z( H0 n% p2 M6 o/*---------------------------------------------------------------------------------------------------------*/
$ _' i" E& k; F2 p. I3 Rvoid VisualScopeAngleOutput(): y% m) \) Y$ n+ k
{0 l8 k5 H8 e/ `% b
    int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;
& l" o% ]8 [. e  [! t2 e    uint16_t crcValue;: P: N" R! @7 [: h+ H0 x  N1 n, L
   
. m6 q: M6 c5 Z$ c9 m    AngleValue_Accel = ceil(Angle_accel * 10 -0.5);: r' k2 N- p3 K4 q' @' `
    AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);
; _" ^, w* C% _9 W$ |. s, M    AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);  @( y% O2 J' C! s
   
$ z# u4 u- {+ j6 r, I4 r    outAngleData[0] = AngleValue_Accel & 0xFF;% J* M! Q" ^( Z% M2 e8 X! A) z. G5 _
    outAngleData[1] = AngleValue_Accel >> 8;
- ~; l! }. i* l6 ]5 a7 _4 w    outAngleData[2] = AngleValue_Gyro & 0xFF;
2 B6 `8 A3 `8 ~! ^    outAngleData[3] = AngleValue_Gyro >> 8;, F  a1 U) j# o
    outAngleData[4] = AngleValue_Comp & 0xFF;! s6 N: u9 w1 w. K9 q0 Y7 J
    outAngleData[5] = AngleValue_Comp >> 8;- d  Z7 h4 Z+ A& a' X
    //计算CRC
: G: n5 M  H+ g    crcValue =  CRC_CHECK(outAngleData,8);
$ N  \8 \( U* A+ N4 u3 d    outAngleData[8] = crcValue & 0xFF;
% f$ z: M& z3 S5 {6 o  S    outAngleData[9] = crcValue >> 8;  c2 d1 q2 D* k+ u! M! @9 S
    //发送至上位机
  M, J0 U- k- r6 U; [( \+ [    HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));$ Z0 x: _# j0 K% g9 k
}" K- `% h0 F9 y8 {3 q& V: ^' R
/* USER CODE END 0 */: R1 T; D: O& U) H

  G7 R6 ]2 j: u* ]9 r: j; F7 G/* Private function prototypes -----------------------------------------------*/
% T' r  o: {4 Mvoid SystemClock_Config(void);
+ d; d& z, x0 ^. t
; Z& U" k, G6 o3 a% x- X9 P' P, h: l7 q  D4 p
硬件连接图:
& Z* v7 K& n3 w; A2 S 1.jpg 6 C8 r+ F; b: u( h
波形图:0 O  M; i  X- u; ]! G
2.jpg ; M# k3 S. s1 i2 u+ y6 L
最后加一个视频:1 \. }2 |  c0 D. ]
STM32L053 演示
5 P$ Y6 f% H8 [; t
1 收藏 17 评论75 发布时间:2015-1-6 13:21

举报

75个回答
党国特派员 回答时间:2015-1-6 13:22:04
I2C.C# F: e( y0 U# ~& c* ~7 b& p8 Y
#include "i2c.h"
! ^) F# g, t" p
$ f$ K: x* p8 Y$ Q, Z, X, }#include "gpio.h"
+ P+ ^9 K" s2 g, [' ~3 t
, f" b, {+ s; I: o* a/* USER CODE BEGIN 0 */
- [: O3 k  C& `& |* h
9 j6 \6 ^" [& h* `; B& Z5 r/* USER CODE END 0 */
5 S% c$ g, `" k1 R) S# p' ]8 W) e5 V
I2C_HandleTypeDef hi2cx;; A/ _, y' V. E4 y3 o& u& O4 ]* T" R( J

$ _/ \- ~  n1 b3 o' [# Z1 r& E/* I2C1 init function */) h0 T  Y! q7 Q
void MX_I2C1_Init(void)
6 ]) J+ {* m( z$ W8 z* b) Y/ H{
1 D9 B+ x( v/ N7 {8 h
9 W, d% k6 `% C8 T+ g. h  hi2cx.Instance = I2C1;: x0 v5 H4 L4 m. s
  hi2cx.Init.Timing = 0x20D22930;* i4 E. m0 k3 b8 S  ?4 }
  hi2cx.Init.OwnAddress1 = 0;
0 A2 T: w: `3 c# ]# s  hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
$ c/ X. g# l( r- c: Z  j, Y  hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;0 v3 j- Y0 o% L/ x9 @2 _! [  [
  hi2cx.Init.OwnAddress2 = 0;$ f9 r8 O$ W" x9 C4 U! K. E& h' O
  hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;; Q% y2 J. u7 e
  hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
- J% f+ C# Y9 o  hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
1 A# x5 ?; y$ Z# U- \  HAL_I2C_Init(&hi2cx);- H2 a4 O3 E  i& C
- w$ A" F! }% j' c0 P7 j7 @+ e
    /**Configure Analogue filter& r3 l( o# j1 T' N! f3 c( a+ W# R8 h
    */
8 u3 ]6 l& U) H4 q' v& b$ j  HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);: p5 c, ^9 J5 \5 m

' j9 O, n, c+ o6 H}
% K" L/ z0 q) X; y' Z# O$ N8 X- B# T
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)# p0 _( ~) P, c/ ^
{
0 `: ^9 f. x( d
) x7 N: O- u: ?  GPIO_InitTypeDef GPIO_InitStruct;
  v$ o$ B9 Z5 }6 A  if(hi2c->Instance==I2C1)! K( m9 O2 v$ f$ P# [) F
  {$ _2 a# [2 A* j. c& Y2 ?
    /* Peripheral clock enable */
1 l8 q9 C2 P+ ^7 v3 o    __I2C1_CLK_ENABLE();% h; |' \. Z( O1 p. S: y6 O( W
  8 |+ z8 F$ ~3 h4 m' d9 _
    /**I2C1 GPIO Configuration   - F$ k8 [& J' _2 N4 {
    PB6     ------> I2C1_SCL* v3 z/ B. F' P4 t
    PB7     ------> I2C1_SDA
- w. K5 k: S9 ^4 a    */
% z. v4 ~1 h& P% U' @    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;$ u6 L9 E' w7 c+ e, y9 m( O1 H
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;; x, |' F: T& @' s* E+ W
    GPIO_InitStruct.Pull = GPIO_NOPULL;& r6 M' ^: y8 f3 N# n5 Q/ E# v( F
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
/ Y8 M' y3 |' L, P" Q$ K0 I    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;" d1 h; x. f# N6 ]5 h
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);2 W) u' O9 S$ S

1 J7 q% H0 P( e) {+ M- p! F" j% n  }3 N) Z6 N) g' w2 {
}  ~2 l9 Q0 c1 Y7 _9 u
. D7 q+ _& W( J; k6 F
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
4 z, N9 F% L5 j( P3 v' w" e4 {! H{' a3 v$ y) B8 b0 T! [. a: s

* p2 S  M; a0 d% C6 u, b  V  if(hi2c->Instance==I2C1)
- g2 N, D1 t3 q& n& O% ~, S- T  {) I9 u/ g! @( B! _- [: {" s
    /* Peripheral clock disable */0 a9 A* H: p$ ^' j
    __I2C1_CLK_DISABLE();* H- }6 h' I3 @4 c
  0 m* e# g; C, k8 z4 w
    /**I2C1 GPIO Configuration   
3 [1 _% W  K/ I% g    PB6     ------> I2C1_SCL
! R1 B" {' K0 Z4 L    PB7     ------> I2C1_SDA
( `& F2 m5 p5 i6 E  g6 d. b- M0 Q    */
4 c  @: O3 h; G# C    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);7 m6 _3 w- _7 K  U1 l, l8 k; X
7 Y7 o& K: r9 B- j
  }
0 {; j* E: {& u6 e4 Q# t5 |! y}0 c" x: \8 f. F' N0 }' ]
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------3 o( [1 V- J3 n
usart.c% Y, b' U* W7 _3 V5 ^- @: n
#include "usart.h"
3 g- Y7 i- L8 h7 l7 V9 _0 E
3 `) N% I7 j6 s0 Q; k#include "gpio.h"0 N$ l, D: r$ e9 ~+ }$ K  C- {. l
#include "dma.h"
$ F) M8 D& P# W! J% i  r5 [9 U# i1 L- O, d' H
/* USER CODE BEGIN 0 */& C# c( T+ a( }/ D" i0 `
9 Y, E1 H% }  S6 H. h
/* USER CODE END 0 */& x6 y# u8 }4 q8 v: I( P- Z

2 L2 U8 J$ P! ?+ WUART_HandleTypeDef huart2;
2 ?- Q) v/ o0 X% [0 K( M6 V7 gDMA_HandleTypeDef hdma_usart2_rx;3 p. W, x$ R; Z  a- P  O
DMA_HandleTypeDef hdma_usart2_tx;
; i$ j* m2 X4 N+ g8 r& G. T
* Y. B  K0 y4 f! L0 _$ A4 \% j/* USART2 init function */: `; v3 o& q% x9 D9 T8 u: l8 T
  r  j9 a* T/ l2 a  U9 Y4 g3 Z
void MX_USART2_UART_Init(void)) b3 i* R6 _( N% d' l- J. [
{; Y) {1 Z( U4 c7 E$ Q
# v9 b* |9 `% d- n  F" i- x& t
  huart2.Instance = USART2;
' h7 r9 v# C9 V  @  huart2.Init.BaudRate = 9600;
% a* V4 s$ o+ j& P4 g/ a0 l  huart2.Init.WordLength = UART_WORDLENGTH_8B;
1 Z# U" _4 ?/ ^  huart2.Init.StopBits = UART_STOPBITS_1;
0 r6 R0 s" Z1 o; y  huart2.Init.Parity = UART_PARITY_NONE;* J5 |* ^1 X6 b1 I* E- w! P
  huart2.Init.Mode = UART_MODE_TX_RX;
' Z- M! @0 R" m5 ^+ d  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;" s  r- q! Q  _( w3 k
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;! ]0 G5 j# W+ e8 ~! v; x1 R
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
, S$ d- E3 ~- i$ c; Y' \( ~  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;' {; w4 x8 G3 G3 m
  HAL_UART_Init(&huart2);
# u& r. Z. a+ w: O% n2 [0 y
* q0 ]( Y" k0 F. U) z; S}
$ @' z5 Y; {  E) f" J! d3 `0 ]1 m; i
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
0 a* m" G* C' X/ L9 j{$ q$ d6 c3 z+ C7 N7 ~" j# q

' U8 \# P& L/ `  GPIO_InitTypeDef GPIO_InitStruct;0 b7 A8 I% e) Y3 K
  if(huart->Instance==USART2)) Y3 t- h' O  s# q  C9 ?
  {
1 g  e; j4 h$ Q' p! B6 {    /* Peripheral clock enable */4 D4 d& T3 E) P! C8 j8 u
    __USART2_CLK_ENABLE();
/ D) i1 L# A* v: I. O9 S  1 A  @/ y0 G- A* P# D+ N" ]! N6 ~; ~
    /**USART2 GPIO Configuration   9 D5 G1 t6 ?) V& P; h  @
    PA2     ------> USART2_TX7 C- c! V! {, S
    PA3     ------> USART2_RX6 b) b  Y/ }5 ~* [
    */
# }2 T  @" U! K    GPIO_InitStruct.Pin = GPIO_PIN_2;
, R& U/ c# X% A" k7 g) E    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;/ h" b  y* f+ m; R  |" F3 c
    GPIO_InitStruct.Pull = GPIO_NOPULL;
4 C: r# D! q' U6 S    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;; ]8 n$ y! u$ r& G
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
: g8 j5 u6 V0 }5 T9 t6 n    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);: [. m6 |3 \1 D! H; [  ^
# [$ R" e( W& u+ z0 `
    GPIO_InitStruct.Pin = GPIO_PIN_3;- J7 i8 i$ W0 E& d8 D) b; `
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
( ~% K3 J3 Q( Y( R    GPIO_InitStruct.Pull = GPIO_NOPULL;- z2 x% f% H/ i1 O6 B
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;: D; A* y) w2 G* k3 A
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;9 {" h! s5 U: B' n8 x
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);9 y( I( w  D8 V2 z1 a

+ K* P" {) {% u7 Y% z    /* Peripheral DMA init*/: E! i% Q5 _* U8 u& r8 d& t
  % d% r2 w, ]; D& W
    hdma_usart2_rx.Instance = DMA1_Channel5;1 l+ n- X/ T5 p9 z5 @) T4 `  n/ O
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;( `1 V1 H  M; _8 N3 v
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;* n2 P- b4 ~5 C( A$ R; Y
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;! |+ I# k6 `. A& h) J
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;' D! I& V$ H% b- d3 `$ P4 Q' B$ a
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
7 N6 |6 D- w+ d1 E    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
; n: c. C2 j/ Q; C, \, U, g    hdma_usart2_rx.Init.Mode = DMA_NORMAL;) E( m- K3 q9 n% B" F8 g4 ^
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;- x7 N( S5 ~" i9 U" F$ Z1 E, V
    HAL_DMA_Init(&hdma_usart2_rx);+ V, d8 l! y6 J5 n% q. }

) k* y% J6 t3 U/ n! Z    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);  W& t: X# z" \
/ _* G  F- Y4 _8 C) r
    hdma_usart2_tx.Instance = DMA1_Channel4;
! p' L  x) k3 b; h    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;+ V, y4 Z3 F5 g
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
6 c" E% u7 `" x$ m6 J" t9 g    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;7 C; d- v0 I# q! f0 k3 P
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;' @+ }2 _6 b1 R- \4 n" }
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;3 i1 M8 G4 y+ g: V
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
/ i# x! k( I" \# V' q! ~    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
4 @7 _0 [+ O0 M  p2 T    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;& _9 r% m1 C2 r7 v, S
    HAL_DMA_Init(&hdma_usart2_tx);" I' y; U3 j" @9 s. b4 g
  S; P8 }  a" n/ C4 h
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
% y9 l  q( ^$ t! Q, i' E3 M* t
: S' r8 Y, Z  a! x# u  }
+ N( F7 ^% A: e! K  \! Z}
5 z' i& |6 V* q4 }# P- x: ?6 m( U5 ~8 e/ h
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
3 W* n/ P& ?3 D& l- Q+ v5 A{+ ~! k. `  d% ]+ B. x( k6 i2 Z& R

/ ?/ l! x1 u% B# w8 y; m  if(huart->Instance==USART2)
0 U; x7 t2 O; y- t5 d  {
) f! j* u: k# h; A9 |    /* Peripheral clock disable */  y6 h" P0 U# p' p9 u# Q$ x
    __USART2_CLK_DISABLE();4 _" v$ }% _( W, L+ n
  
! `+ P- i$ v/ b! j0 g2 e    /**USART2 GPIO Configuration   
8 P5 T$ t& N! g$ v/ X1 l1 y9 L    PA2     ------> USART2_TX- @& b! a' m( a% a* i
    PA3     ------> USART2_RX9 d. [% [  C1 u1 r, J' {2 Q6 B
    */
9 ^, G  S, Z; E$ z- ]    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
% ^8 r: ~& C/ A& B& [' z; Y4 j
- o/ p1 `; z* [    /* Peripheral DMA DeInit*/5 @: }2 A- ~* y4 G
    HAL_DMA_DeInit(huart->hdmarx);0 z. m+ f1 R, S+ i  {
    HAL_DMA_DeInit(huart->hdmatx);$ a8 i+ {- q( W4 C- r# b8 w
  }
  t$ m, l+ H& |% G4 O}' \" t1 q. L) M5 u# C) A- h! ~  p
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
6 p8 z* k5 c) L0 pmpu6050.c
1 m' X( w$ I' b; I7 m7 z2 ?7 l4 t, }#include "stm32l0xx_hal.h"; S, \3 g/ T3 x& y7 X
#include "MPU6050.h"
. p; {' S& b% ~9 F. S2 s. Y  ^" Y" p2 [. D/ p/ ?& v+ _4 {, a
//各坐标轴上静止偏差(重力,角速度)6 S9 b& P/ u" R4 E: Y  O
int16_t offsetAccelX = -195;8 V/ t0 a4 O9 B% {; J0 T$ W( p
int16_t offsetAccelY = 560;. l' C6 [; p: }; O
int16_t offsetAccelZ = -169;8 y- |* V2 o4 \' J) R; @* {- C
5 ^2 {9 Z9 C& f7 X( f! p# V( `; }
int16_t offsetGyroX = 12;
0 t8 h1 M! T$ N" [: o. vint16_t offsetGyroY = 33;; y! T9 g' L- {! v1 L
int16_t offsetGyroZ = 4;
9 n0 h3 L( T7 z+ M5 I8 T3 a9 y
- u) z. z, `+ @+ Gextern I2C_HandleTypeDef hi2cx;  C* w( V0 O, ?# e
) G* D% \: }; e
//**************************************
) C6 z2 [) n" e7 d//向I2C设备写入一个字节数据+ Z) X3 Q; [7 p" ^  E: M% S' W
//**************************************" R& j# [3 H8 T% o+ @. |9 t( M
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)) D8 h) o: r' D7 \# p$ e9 E
{/ F3 J  d, S# `9 j
    uint8_t rxData[2] = {REG_Address,REG_data};% ~3 c, V- A5 r
    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
3 n! i4 r, i/ q- t) ]& d! k, x: d8 P    {, E4 |: i3 a, R
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)8 t* x4 C( K" W) Y& e% b+ P2 h
        {}
) W, Q4 w& C# K( p5 y8 f    }3 A6 A) y  W* H/ x5 H! O: K9 _
}
5 c2 q& w: \% c; }: p! N- `//**************************************
* v5 i$ j: Z+ W0 n* C//从I2C设备读取一个字节数据
. B, b2 k( r4 _) e# `* @  i9 i8 E//**************************************
3 o8 d) b5 B; Fuint8_t Single_ReadI2C(uint8_t REG_Address)- j$ Q7 o; a) y8 f
{, O- t  K9 B5 r7 c
    uint8_t REG_data;
( ~7 v$ J% x( X/ F- |3 q    while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK). }7 m, z/ y1 |7 v: ~7 Z; n
    {
  U) }) ?2 x  [2 j- ]; E6 E- ]4 H        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)( ~2 z+ i) o8 A! a, @: P
        {}
4 x, [. g- ^1 @    }; Q2 ~% S% J) F  D& e4 @- K/ a
   + P$ E6 g7 ^% T, v! r4 x
    if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
1 U& ]% l* v5 k; g* p' f; e1 @) j    {! [6 j/ |( c" j( m. ^8 ]
        if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)% J7 _% `: ^; m+ q% w+ g; U% Z/ j! |
        {}
) b7 P* D3 ?$ F) o- `5 l2 |! c    }
8 e1 s" T% r, `) i3 d8 v) F; C    return REG_data;8 |5 V1 B; M6 Z( n
}4 a; x7 l7 q7 s& l" s; B
//**************************************
0 ^7 t" [6 q  Y, h//初始化MPU6050
3 ?5 F. b9 q! v) z" p//**************************************
9 W' [3 s6 L) W! ~5 Xvoid InitMPU6050()+ w! T4 Q8 c, N) h
{
* a$ {% C3 D1 {6 q/ v  z    Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠状态7 O- i* k- x: o- @

9 O. t% m2 m& S' M' I    Single_WriteI2C(SMPLRT_DIV, 0x07);
0 D' v- A$ Z. O9 p* `
* }$ P" s: v: K6 a: x5 m: t    Single_WriteI2C(CONFIG, 0x06);
' A; L  D% O- V4 u! y
5 }* x* }8 l, J+ }    Single_WriteI2C(GYRO_CONFIG, 0x18);1 }4 p' ^7 i5 T* @; y/ A! v
, u8 R4 I6 F3 C5 P: L' h# j
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
# m! H% t, G: q1 L: s, r}  q7 S" Q9 j3 \- y3 R" [
//**************************************9 W9 C7 N) O7 [+ D. T
//合成数据1 E% J0 {% t2 A" V/ g- j3 n% w
//**************************************
' u, G- ]; ?* O  w) X) P- `( Jint16_t GetMPUOutValue(uint8_t REG_Address)
9 T; @- i& M& y' s3 j* W{
: N! o: ^( _0 ~1 z6 l4 `    int16_t result;, B. P5 J# V- D- V
    uint8_t H,L;
8 b  T1 p8 y! z    H=Single_ReadI2C(REG_Address);
( x3 `- I% B9 X+ S) A. x6 k% m    L=Single_ReadI2C(REG_Address+1);
7 f( P* K4 R$ z9 X/ z    result = (H<<8)+L;: s$ i& g$ A0 O0 m
    return result;   //合成数据9 d+ @7 |1 b  W! b0 d0 v. L
}) p; C! r0 S% C2 P9 K
9 U- J( J% J& ~7 d( d
//**************************************
1 U$ C9 U& O( t6 N//取某一轴上的加速度数据
  b" R' E5 W$ m+ [7 _+ D) X% x//**************************************, k  s2 g$ N/ D( A. Z' ^
int16_t GetAccelValue(char axis)3 U+ }; p" j7 s( S* r
{9 ~  {. U& G* f) z7 p) L
    int16_t result = 0;
8 y2 ?4 f* l: y- F    switch(axis)
6 k; C6 B2 v2 ?) N; b    {
7 Z- y3 U- r& }1 M        case 'x':: y  \6 F1 y1 F% X: w, V' C: |  _
        case 'X':& C+ [5 I3 {; U: o+ |+ m# W
        {! ~; o  D* G; g
            result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
4 I! C7 Y' ~2 _7 w        }9 ?( G8 F' x1 A, V- i6 |1 f
        break;
# p, u, T5 U; X& v2 H        case 'y':
& F1 ~8 j. m3 U# Q$ K        case 'Y':
7 n3 [4 Y1 ]& t        {
, {( T3 I9 J  E7 ^# `            result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
/ G, U) ^3 f1 ]8 s! n. f0 M        }
0 Q. Q8 y/ ?" m! \4 q8 C        break;2 m% O- k5 U* T$ ]! h3 ]! J
        case 'z':
/ M7 O. Y( h" J. t5 A4 o6 }8 w        case 'Z':3 a0 k( I! P$ N7 F5 H2 m4 {
        {
& ]# Z' J" b+ ~  `            result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
# N* N! M" h8 U$ `! v        }
/ d& O% P/ ]% c( ]- N/ D3 V        break;: m5 K% [3 [+ `7 q0 H
    }5 M/ y+ @+ Z' z
    return result;
/ W% C4 i3 l; C9 z}  ]; b5 l' |/ F& b) x. b
# Q$ V+ L' M3 N6 E; w7 R3 ]
//**************************************8 t! F  @/ Q5 X6 f1 W: j
//取某一轴上的角速度数据- g! D5 S: m. m
//**************************************& F$ A4 |$ k7 ^9 [) h
int16_t GetGyroValue(char axis)* L( t& T, L) S% J1 k9 x+ Y
{3 c) G1 x; j; h/ t' T
    int16_t result = 0;& I! G% b: C) s
    switch(axis), D/ u' L# K( E
    {
5 m, x; \# P$ y7 E* `4 o        case 'x':
+ p: _( E2 z7 W2 n- A7 h- R4 }        case 'X':1 F  S3 S& X* @& O! `, x4 }
        {
4 h0 E, `# G- n  ~* B. ]            result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
6 O' ^. C& N0 C* O6 X6 o9 \/ v' c, G- k        }/ d# l, }; B7 e* x6 N
        break;
) z" A$ S! {8 ?/ I        case 'y':/ t/ T) p" X/ T+ t0 N
        case 'Y':5 j" h( b9 ~- E, X/ N- S
        {4 B& q, Z4 f5 [4 u+ {& {( ?5 U
            result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;! m" H7 ?5 i. ?  n7 L
        }/ Q+ ?' ?8 s( o: H  u- i) ^% X
        break;5 l( T- ]- J8 }
        case 'z':
) y& q1 C3 a- C( ]9 a+ W        case 'Z':
& @% p9 p4 F' `/ |  K8 K        {4 r6 F( v; O! Q4 t) U2 V# k
            result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
& k! O, h7 ]5 ?/ g* k$ j7 U        }) [; k; E& c' g- \% u8 J
        break;
1 z1 F" }( a, k( H    }  ^, X% h8 n& y6 a9 B
    return result;" |, ~2 K7 y  g, I' H/ N$ k* N7 F0 \# I
}

评分

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

查看全部评分

党国特派员 回答时间:2015-1-6 13:21:49
int main(void)
* \4 T1 J; Z+ a: ]$ ?2 m{0 b" \& w4 t/ d0 _
5 Q4 e3 y! ^4 e1 i: s
  /* USER CODE BEGIN 1 */
/ l- M- U' b% B1 r: X
' _8 l' ?5 D2 [, L  /* USER CODE END 1 */, r7 m; w) [- V/ L: `. J

- [" a% \+ V9 n/ m2 H+ H& _3 t7 G; V  /* MCU Configuration----------------------------------------------------------*/
. o9 j- d1 s  N( \# ?# |0 A2 f% v2 R1 n0 F  W9 n) b6 g6 B" Y3 z
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. *// X7 @- ]$ W5 p% i
  HAL_Init();
4 b: Z/ ^" F% d1 W( D- _* p% c$ f( t$ }8 z  E1 X" [
  /* Configure the system clock */
# r5 w$ l# N' v; ^) q  SystemClock_Config();
! ?$ h+ ]' V2 X& E1 X4 y! Q/ q6 N2 F: W+ e* M% S! L
  /* System interrupt init*/
# a* u5 O5 D, H  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+ z/ |- Y9 k1 S( X" [% X" U7 _# a3 p/ u. N
  /* Initialize all configured peripherals */
2 ~; F+ }) L* A& D! X5 }  MX_GPIO_Init();
: }. I0 G) K9 k' g  MX_DMA_Init();
% {0 B& k6 _- g    MX_I2C1_Init();! K6 o' O1 y/ r/ D* Q8 W
    MX_TIM2_Init();) D  E4 y. R) S, @0 y
  MX_USART2_UART_Init();9 x8 d. ?; Q' E1 m
    InitMPU6050();# f- ^! P! ?  J, M9 C1 t- K* Y
+ m7 g  Q  x& E6 m/ P
  /* USER CODE BEGIN 2 */
6 c' f2 q0 B7 j1 ?! r) n8 y    HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);8 h+ |; s" ^$ o# u
    HAL_TIM_Base_Start_IT(&htim2);5 d. f4 `8 g* N$ G7 ]" S
  /* USER CODE END 2 */6 C8 U' t1 a6 R1 G0 D. c

: S, v- F8 {3 s8 a1 K4 h  /* USER CODE BEGIN 3 */
5 |: C6 c1 ?0 w) d) u+ }7 j  /* Infinite loop */' V7 ?2 e4 z5 n  a8 [
  while (1)
- w3 h9 P3 R; T  {2 t2 C/ Y* w" g& d; B% T2 N' T
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);* m  u& @" V2 ~, T8 U& X4 l. m
        VisualScopeAngleOutput();: a  v8 _5 ^% D, x* F4 Z2 m
        HAL_Delay(100);7 X% R5 `) w5 u3 C+ D
  }
$ C* \% p3 Z( o# ?2 z% v+ J$ S, Q  /* USER CODE END 3 */6 f9 G7 O) I/ Q
! {3 c/ q8 s- V: |
}: O0 O! H* V0 i5 j2 l

$ G& E8 N6 @- b1 u- f+ `3 W% J$ ~/** System Clock Configuration
" d( |# u6 y1 v; D+ }*/2 V3 @3 h; _0 H/ `: D
void SystemClock_Config(void)% O% _; P+ B. ]( _/ I8 b
{
" H% l, z& A. j+ L' @- \: c$ {- z
% l) u6 p1 u  [' X; b! s8 L/ f  RCC_ClkInitTypeDef RCC_ClkInitStruct;
" S* {  `2 ~7 U1 J: m" f  RCC_PeriphCLKInitTypeDef PeriphClkInit;
8 U2 K% }/ @) s) s/ v6 A; T. v8 u  RCC_OscInitTypeDef RCC_OscInitStruct;
$ q0 q/ f+ I0 @# T- o
9 B  m3 S, r2 C6 Y9 w  h7 u1 q* e  __PWR_CLK_ENABLE();+ U7 `4 y8 o* K, m  M

3 @3 A' P( Q- ~& Y( ]5 N! m  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
) g1 e4 [# j7 g4 W. X5 q1 Y* d; K, b1 M6 l$ {0 l: _! D2 ?
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;8 M  V8 L5 E4 e% ?
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
) J9 b2 A- ^, M3 F4 K  RCC_OscInitStruct.HSICalibrationValue = 16;6 J+ K! \4 e( a8 M
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
( u5 P4 u" J, }5 ?5 h2 {& O  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
, Z( Z3 w1 v3 n. E( l# y& T' {  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;5 o4 Q, o1 @7 _5 I2 f
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;9 d' Z0 Q; b5 Y' |* E/ |
  HAL_RCC_OscConfig(&RCC_OscInitStruct);  A& j" G0 ^, F+ ]
. ^7 s6 b6 S5 c8 p# }/ J
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;* ]4 U6 k* ?& o4 M2 o9 c( Z
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;9 d6 `- H4 [% A  [7 B
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
' |) }: u* E5 ^  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
5 Q3 M) {7 r% J. O; e$ g( n0 [+ j" ~  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
& g- w* {. U  \6 [' Q! ~8 L% P$ N  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
7 \. v8 t9 G8 Y$ v" t% O6 n* g; [
3 B+ q! B+ P  G7 y0 O5 G# c$ f; f! R  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;. w- T! K9 ?' F! z
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
$ Z7 w3 V" r: N  v  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);* y, B7 c6 l: G" ~* n
9 ]8 V% V  M" M+ M8 `, |
  __SYSCFG_CLK_ENABLE();
4 X% C' p7 c/ U& K3 E# {- _1 F7 z+ W: T
/ W% g; v. F7 n8 e4 Y) l}
# _  m5 q( i5 t) D
* z* H7 o: i/ K' N2 P; ?; |/* USER CODE BEGIN 4 */
6 A+ R, p7 C1 i6 x, ~) C$ Tvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); k6 m# i  J# t$ ^5 |
{
/ v( p" b0 u) w* q& C7 s" S    if(huart->Instance == USART2)
% i2 {3 @- Q1 N& R3 B4 W    {: k; j# A/ {; v3 h4 ]
        memcpy(txBuffer,rxBuffer,RXSIZE);7 \4 |" }9 D% ]8 K; {, h  h
        HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
- a( `7 L. W0 Z6 v) u" u- J# E        HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);# F# \; @# X7 {
    }
2 M$ y/ S8 k/ y+ c}
) }/ v8 q  a9 D$ W) P' K
9 l6 z0 e- v' l7 h2 qvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)* u( c1 W# H$ l
{% s8 B$ a2 n1 N  p( _
   ; T3 o0 R4 h0 E, k4 Z
}
/ V% R. O# Z/ u3 g9 a+ K. G5 K0 K( \" N8 j/ M
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
, e' O8 @: b8 m2 x1 ?9 m{( S" E( V4 F, z: _3 f" t
    int32_t GyroValue;. M* T9 r  p8 U* w0 k
   0 e9 |% O3 L# Q+ j8 O
    Calc_AngleAccel();
- S; G7 J) c" U/ |2 V" M1 w    GyroValue = Calc_AngleGyro();$ {/ r7 ^3 W) w: Z
    ComplementFilter(GyroValue);
$ q' h* M4 C, W  j3 D+ n6 i* 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:006 O- J5 ]& ~* Q5 T
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...

3 \9 Y6 e3 R( y( `  b- \9 r! F4 M使用DMA方式,接收发送数据必须是个固定长度。
党国特派员 回答时间:2015-2-17 09:21:31
星辰一方 发表于 2015-2-16 19:00- @" h7 R5 y+ [
楼主,请教一个使用HAL库UART中断方式接收数据的问题:接收数据时候必须在程序中设定接收长度吗?如数据长 ...
$ ]6 L9 f) c" u  D+ y
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
我夏了夏天 回答时间: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/ z1 U' T% ?# _$ Q4 O
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
2 f3 u) V" L2 @3 O
好的,多谢指点!
rogerkun 回答时间:2015-4-3 22:08:29
楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?( p) L8 T: U7 s: [. @3 V- `: v
请问应该注意什么地方
nocoyou 回答时间:2015-4-4 09:12:05
顶顶顶顶
党国特派员 回答时间:2015-4-4 21:33:35
rogerkun 发表于 2015-4-3 22:08
" k; |$ S& g0 @! ]9 ?2 o楼主,这个工程确认正确吗?问什么 我使用 UART DMA怎么也没办法连续输出和接收数据?
4 s# l: p: k% i( x请问应该注意什么地 ...
0 D1 S7 J" h, o; a: v' u3 b
我使用是没有问题的呀。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版