拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- A9 C9 {$ y- `5 X/ G8 z main.c) J! b$ y' y9 q- ^" @4 k #include "stm32l0xx_hal.h", v; D$ b* ?! `4 M. K- u! q #include "dma.h" #include "i2c.h"+ n6 M0 s. ~$ o( S4 o #include "tim.h"$ f9 \( O4 K J( @: V' w #include "usart.h" #include "gpio.h" #include "mpu6050.h"0 {- ^1 q' w) `; |) I #include "visualscope.h" ' J$ \/ {" [% f5 _& j, m; K #include <string.h>" `& h( O p& m& q #include <math.h> + N( e4 H8 P: Z3 k9 ` /* Private variables ---------------------------------------------------------*/ #define RXSIZE 8: r8 g. |3 D& y# Z) q1 t5 }6 a #define TXSIZE 82 |# O- J- N7 }( a7 G8 a uint8_t rxBuffer[RXSIZE]; uint8_t txBuffer[TXSIZE];0 I7 | ~- l E! X# Z float Angle_accel = 0; float Angle_gyro = 0;1 e9 y, J0 C' } v- r" U float Angle_comp = 0;) R! g# J8 U) G J" B/ W$ G1 b6 @ uint8_t outAngleData[10];. g6 p( o! q- e$ X, e# H! Y& h: N /* USER CODE BEGIN 0 */ ) c+ Z& K) ]8 W' N+ _1 n /*---------------------------------------------------------------------------------------------------------*/ /* 重力加速度算出的角度 */2 S, Z7 y7 H. z' ]- }0 m$ M /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel() {' @- q* a* a9 {7 Z int32_t value = 0;0 u. V3 K6 L ^0 B: {! F ( p5 S2 H* C j) A5 z# B+ U value = GetAccelValue('x');( |0 ?. ~; f% G if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296); else% r% w6 d$ j! l% |) w Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); return value; }/ a7 F1 q* L3 H5 g7 `1 d /*---------------------------------------------------------------------------------------------------------*/- g9 n) T' q! z0 A4 J" Z5 x5 M5 K /* 角速度算出来的角度(积分) */2 u7 Q# j' |( m! V /*---------------------------------------------------------------------------------------------------------*/, a5 m0 c \1 h( i$ G int32_t Calc_AngleGyro()0 ?# s3 R# J( |3 h, N' ] { int32_t value = 0; c; [, ?& t% ?0 o/ G9 U value = GetGyroValue('y'); Angle_gyro += (value / 16.384 * 0.01); return value; }# X/ Y* K$ z: i# y, [* g 6 p7 U1 e- |. v- @4 J6 g5 h /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */% V2 Q& p1 ]% y4 L /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro)3 h; p ?9 D0 Y! I* j' @. Y6 m {) \) |8 G6 m8 M8 [' J Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;% g# P$ U3 [3 l6 U0 b& B( M$ r$ C 8 I+ \7 a# A1 M5 p6 L4 \4 e return Angle_comp;) z% J/ R5 j7 C- i) b |1 Q- e( i" h+ b }; F% u; X* [; N; a/ _3 |8 @ , l, C8 c2 R5 Y! m! a) W( A+ h /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */ /*---------------------------------------------------------------------------------------------------------*// l! e/ y! R& Y void VisualScopeAngleOutput() {4 o ~( m: {; s7 l! ?0 W int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;4 P7 `# {5 D( V/ E: g) O. {+ C uint16_t crcValue; AngleValue_Accel = ceil(Angle_accel * 10 -0.5);7 l( W; s5 Z& G9 ~6 k: U AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);; i0 }. @: I, y# j( o* p AngleValue_Comp = ceil(Angle_comp * 10 - 0.5);1 h2 N) K6 g( a% _6 H6 T outAngleData[0] = AngleValue_Accel & 0xFF;$ b0 ~* Z! D3 v% e7 t, [- a& | outAngleData[1] = AngleValue_Accel >> 8;: r* [* V9 d, K+ @$ g* g0 N- @ outAngleData[2] = AngleValue_Gyro & 0xFF;% V9 \: |0 w, a- Q, F outAngleData[3] = AngleValue_Gyro >> 8;7 b4 t" }8 p% K outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8; //计算CRC crcValue = CRC_CHECK(outAngleData,8);- n- U1 u, M- V) w- v outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8; //发送至上位机 HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData)); } /* USER CODE END 0 */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); ) I- I- I1 S3 r6 {0 h) r 硬件连接图:7 |% I8 @) T8 r8 J4 [ f1 B 波形图: 最后加一个视频: STM32L053 演示& \: T, i9 ?2 ]8 [: T+ o) }& ?3 h |
意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS
【STM32MP135-DK】裸机移植shell
【STM32MP13DK】 在Linux主机上交叉编译一个Hello Word应用
STM32MP135F-DK 开箱&开发环境搭建&硬件设计分析
意法半导体在意大利建SiC整合制造厂
轻松地实现ClassB在STM32CubeIDE上的移植
ST历史小知识(6)- 与世界共同塑造美好明天
ST历史小知识(5)- SiC衬底进一步发展
ST历史小知识(4)- 投资未来
ST历史小知识(3) - 布局新兴半导体工艺
#include "i2c.h"
0 X0 u" z1 J d
#include "gpio.h"8 s4 I( h+ Z# [( \4 M
0 _2 }, e. D5 {* p# d2 \. i, X
/* USER CODE BEGIN 0 */
* j4 P- P0 i; |- U5 Z
/* USER CODE END 0 */2 V# s: [9 U, |3 U1 W L
; y3 |" |; C! `' _* w- z. e
I2C_HandleTypeDef hi2cx;$ w. j0 l% ^ b* }, z
/* I2C1 init function */% a& @9 w# b( Q5 Y! M+ [9 R- @8 k6 X, }
void MX_I2C1_Init(void)! f4 S# m5 T& s8 z
{6 ]0 @; I; t) C1 C( `: P; Z
hi2cx.Instance = I2C1;; \( P1 U( ~" m
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0;" S: N# Z% Z; i
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;+ P) I2 _# y- b* _" r
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;2 x) n% c2 O' p6 C/ X
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);
/**Configure Analogue filter w- F$ e7 a7 v1 N& A
*/
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
a; @9 n( Y! s8 W% v& @' a9 r
}7 O' n0 j8 J) G q. [% ? G
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)3 Q" D9 m" G% z' D- F* B
{2 _ x. I4 N. x6 M: j. j5 i7 B
GPIO_InitTypeDef GPIO_InitStruct;5 T* {4 B* o9 F% D4 Y
if(hi2c->Instance==I2C1)
{
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();$ o/ h: ^! Y1 ^
2 ?! r7 v+ j/ w: ?6 W, S
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/5 |" I3 p( Q0 i6 G' S; n8 o
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;; N* I. O0 k3 a% y4 j
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;4 ?9 g. }" W, a( F
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1; [9 U* c) y& K% O$ [& h: M4 `
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);4 m- }5 ?% m% R. L7 [
}
}& Y3 p0 m3 @/ Z1 Q/ x- J5 q
# K, H7 ~, w3 S& t0 Y0 ], _# S
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)) x3 _9 J a6 P4 l
{
if(hi2c->Instance==I2C1)/ q* N9 f4 K4 ^& P; Y
{" E- n0 F' _3 q/ w+ o8 G- T
/* Peripheral clock disable */2 q; k& `( r5 P' X7 G' y8 C( n
__I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/+ X7 c' t2 B5 @9 }
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);$ m* B ^# b8 Y/ D3 i
}2 M: y3 c5 U" W6 K6 \& I1 }
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
usart.c
#include "usart.h"
#include "gpio.h"$ K1 c6 C9 _, V$ Z
#include "dma.h"5 _: ]# p( s8 U) R1 C% B
2 R4 J" G' Y$ w) k
/* USER CODE BEGIN 0 */
, U) d" E# P H% u. c
/* USER CODE END 0 */" T3 P: m3 l% s5 j" B" y
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;1 F; B) t# H8 E# x7 z7 K4 U
DMA_HandleTypeDef hdma_usart2_tx;8 G# P" s* f6 I0 B: G
e8 h; d8 {! g
/* USART2 init function */
$ i( g9 T. a6 S8 u! w+ `1 t5 f4 K
void MX_USART2_UART_Init(void). b! i0 n4 X' \% S" ^1 C
{
- `1 _" f9 ^" w; ~7 C; h
huart2.Instance = USART2;' j9 Y" H5 |: p3 v0 g4 X/ }* L) O
huart2.Init.BaudRate = 9600;- D& Y; d$ {. {0 X9 O
huart2.Init.WordLength = UART_WORDLENGTH_8B;* C" k; N# S: n! O3 X
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;1 L5 W: ~4 s- i( P
huart2.Init.Mode = UART_MODE_TX_RX;4 a& [2 N9 ?) n+ u5 K4 e
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;( ?( o; T, w! {0 c/ B
huart2.Init.OverSampling = UART_OVERSAMPLING_16;4 i! c7 B2 b# z+ B+ c
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;: S/ _: G" A8 d
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;2 v+ q: ^8 E, q4 O2 Z" s
HAL_UART_Init(&huart2);! Q" h. u$ [- O: o9 Y
}5 E+ b1 F$ g2 N: t) {3 D @$ B
- D/ L4 u- t3 B& ?$ f
void HAL_UART_MspInit(UART_HandleTypeDef* huart)) c! c8 B" D- m: x4 Z% h3 s; O
{& |" V2 P2 b, D a [7 l
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)- `* G4 ?# o& r
{7 t' b: y9 T; T7 C8 X. Z0 H
/* Peripheral clock enable */' ^8 V2 N7 L* `" @2 ~
__USART2_CLK_ENABLE();; M% g3 \1 G: N! m& c4 q/ h) V
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX# v7 J2 I8 i+ U% t8 R
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;7 C+ w3 u3 z! K: p
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;6 u9 i/ R. L: ^ {$ ^, k4 H) R
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);2 t! |) \$ ?! ^+ e; _
" g5 H# e" J8 o# Q# I h# i
GPIO_InitStruct.Pin = GPIO_PIN_3;4 R" ^" r: G. H$ ~2 I) U' f
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);4 {, j9 W4 h8 A+ `8 y& ?% P
/* Peripheral DMA init*/: x5 ?4 v4 S) ~' Z7 D2 K
hdma_usart2_rx.Instance = DMA1_Channel5; I; p' c3 K# ?0 {
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;2 s$ r ]; G1 n2 Y- p5 z
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;' r2 ~ {: d; w8 o
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;3 t9 H! ~2 }2 y% Q9 _$ h! n
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;; Q% y) F: Y$ Z
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;7 f3 c$ D( i1 T$ x5 z( D
hdma_usart2_rx.Init.Mode = DMA_NORMAL;. r& Q8 v& n) d3 G% A& O
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;+ |8 i8 ]! n7 l& S2 E
HAL_DMA_Init(&hdma_usart2_rx);# W( l. }1 o* X2 `2 n
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);; t- y# a; g2 _3 r+ u
hdma_usart2_tx.Instance = DMA1_Channel4;
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;0 u$ s- C- l' o
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;1 A& W1 ^9 L1 [6 Q* N6 i
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;6 I) I$ `5 R, P% @
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);/ _% a. y4 T% b+ }6 a3 s
% o( {5 v8 {3 E _. I6 E
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{6 {$ B+ ^3 K' B3 r* t
) W6 J# a0 m8 I c' a& d9 A
if(huart->Instance==USART2)
{( d' @% P3 P w2 h
/* Peripheral clock disable */; ~1 }. V" f1 W* j+ w) v" V) G
__USART2_CLK_DISABLE();. ]/ h) M# J1 i. l; O( j8 J$ A
) k4 \# A% J# X$ Y2 |9 S4 i" e
/**USART2 GPIO Configuration ) M! D$ A( F- p' R* M9 s. |
PA2 ------> USART2_TX
PA3 ------> USART2_RX" G2 Z) Y) o* }$ J9 d
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);- }( @/ v w, C1 B% I1 B
/* Peripheral DMA DeInit*/7 ~( v5 A! U8 ^/ p$ ]9 u/ r
HAL_DMA_DeInit(huart->hdmarx);, |, R1 y& B) S. j* s7 p
HAL_DMA_DeInit(huart->hdmatx);
}$ S- J; ^! E3 x( d# n, @
}5 @2 m& C. G/ [# d& o. l% M- }
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ q' z8 o2 e7 \4 h
mpu6050.c
#include "stm32l0xx_hal.h". e1 U/ P- l) i
#include "MPU6050.h"
//各坐标轴上静止偏差(重力,角速度)
int16_t offsetAccelX = -195;
int16_t offsetAccelY = 560;5 c: L: y' D9 A7 ^' T
int16_t offsetAccelZ = -169;7 F4 k0 Q0 ?9 {( _9 l/ Y5 D5 j
* ?; U& U- S* l, ^5 P5 K% T" ]
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;( u: K* O/ q8 ~" ]) e2 R
int16_t offsetGyroZ = 4;
extern I2C_HandleTypeDef hi2cx;
//**************************************6 [* w) w' }/ o4 H# a& N. f4 c7 L
//向I2C设备写入一个字节数据
//**************************************" n. Z8 N! X( U1 S- h8 I
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{3 F/ ^) j$ W0 o; H: F$ {* V4 s2 t
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)% x8 A/ N' E/ D& [
{}& T$ z) ~' c6 f
} ?9 K4 n S0 w: a$ w: y
}; \! y8 C5 N8 T; ~- o, b
//**************************************0 Q& c; k+ I, B
//从I2C设备读取一个字节数据6 |$ g4 X2 b+ q. }& a2 Z+ _
//**************************************
uint8_t Single_ReadI2C(uint8_t REG_Address)6 V+ j+ H6 b4 Q, ]& V
{2 F8 o4 J, K) y7 l0 y
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)2 e, u" y! p% p1 f
{% S% }4 h) t+ a+ C0 f( B
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)- k" V3 R+ k5 _* g' J2 g
{}- G) p! D1 Q' q/ j' G8 Y+ \% _" t
}6 U. ?; H v) F9 R' O+ E
- x. ]5 ^0 M1 e' ~" B
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)* ^7 a0 l# T1 ^) C( L4 ]6 H) N
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF): I3 H! @" W) _% G
{}
}+ R) F; O7 M6 y( o& C- x: N
return REG_data;- o8 ]- ^' v. u- M* h
}/ y- g% C, Q. U7 a* d. U3 j( Y
//**************************************4 Q- W7 m. H! ?1 I! X
//初始化MPU60502 \" \0 P. c L- e8 ~
//**************************************
void InitMPU6050()
{0 F! V3 n* N+ j3 C: x
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态1 m; @; z+ S" | ^) F
Single_WriteI2C(SMPLRT_DIV, 0x07);3 B) ?: S" U/ N* B: x
Single_WriteI2C(CONFIG, 0x06);0 o( G1 G0 `, P) h+ U2 O
6 b) P" \& Y- `* _- B' z3 ]
Single_WriteI2C(GYRO_CONFIG, 0x18);
* L4 I$ Y. h! m; n r7 B6 B: k
Single_WriteI2C(ACCEL_CONFIG, 0x01);# g3 F4 L2 B& G$ s+ w1 m
}
//**************************************' C( F9 C( L" w
//合成数据& ^7 m( Z% J0 A; I
//**************************************3 k( p" g3 h" q, v7 p% |- y
int16_t GetMPUOutValue(uint8_t REG_Address)
{
int16_t result;% ~- r0 F% l9 Z4 Q3 l
uint8_t H,L;* O1 y \4 ]* m+ }. ]
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;
return result; //合成数据/ u1 {- W- w4 [1 L, C, q% T ]2 e
}" M3 M" A7 a- [( E0 D: p
( z' O/ X5 D1 B+ i6 q- P, ] ~
//**************************************: h* X9 F2 X* B
//取某一轴上的加速度数据3 a* ~8 [- g H, R2 N( `' Z5 f3 y
//*************************************** r, r- r s, z/ X! b7 M* u
int16_t GetAccelValue(char axis)
{
int16_t result = 0;
switch(axis)4 D2 x4 ~9 c1 M/ g- u! L% |( I* p
{
case 'x':
case 'X':
{7 f" F, C7 @: k* O. I5 F& k5 S
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;: x3 E# s: l: S( h; d. t
}
break;
case 'y':
case 'Y':
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;5 B4 e9 B( X+ V' v! C4 g$ ^
}$ i/ u `/ b+ M. i+ ~
break;
case 'z':
case 'Z':
{/ N2 u+ P. u9 T( L! {7 B
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}5 h3 G) r5 r. b. V
break;# M. A1 t/ ^& o8 r) Q" F
}) j# K4 G9 h# `; z- H
return result;) g% M* _ y o1 I
}) ?% a% }/ I' X7 s0 Z. A
( ~ [2 g) d O1 ^0 j
//**************************************# y1 W5 b$ L0 B' h( \
//取某一轴上的角速度数据. G4 d# h! @5 s* g3 v
//**************************************- ]0 R" w" g/ s: f# T
int16_t GetGyroValue(char axis)
{
int16_t result = 0;2 h, X& E+ M. {% e* w! B: m
switch(axis)
{
case 'x':' _1 z* D1 l M2 X7 I# a
case 'X':
{- T, [& S! T# e8 E$ }
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;) ?/ y) T6 V6 I& S" t$ {
}' v! H5 N- F2 s7 `0 J2 l2 Y
break;
case 'y':
case 'Y': k4 g' K9 S* |" {. H0 J
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;* V2 P! z& ]5 l- C2 a
}$ q& V$ z! Q# Z, M
break;
case 'z':+ L1 ?; c2 I2 n: r( V# N
case 'Z':
{
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;" J& L% H U0 {) F: n7 I1 S
}' f% D2 {2 `) ^
break;
}8 @& r; y1 o9 ^1 f9 m
return result;
}
评分
查看全部评分
{4 [4 }8 v, h' z3 f
3 C5 _( R5 @ A. e9 C$ ^
/* USER CODE BEGIN 1 */
/ o) N$ } Y# G7 Z; k' X/ _
/* USER CODE END 1 */" N3 `1 |9 Z' O8 Y8 o( B/ U2 d
3 j! l% d2 d1 I
/* MCU Configuration----------------------------------------------------------*/1 @3 V' w7 [$ {# }
8 ~5 H5 q- V- W9 s1 b4 z$ o
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();3 Q0 o% u' G7 D7 l$ V& `
! M* q2 R$ [' E# t' V% v8 K$ w5 W: K
/* Configure the system clock */
SystemClock_Config();, _, G2 x8 A0 o* f
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
1 x( w! S0 f( F$ n! t3 ^3 l" Q, c
/* Initialize all configured peripherals */
MX_GPIO_Init();' A; A; F6 J- h2 Z/ c1 s4 Y
MX_DMA_Init();
MX_I2C1_Init();! Z7 K4 e9 _8 r' V8 ^* H; e7 M
MX_TIM2_Init();
MX_USART2_UART_Init();' z- I" I i$ I1 Y( t: z8 H
InitMPU6050();
' a. n3 S3 p+ ^1 ?
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
HAL_TIM_Base_Start_IT(&htim2);( G% D0 B# u, a0 L
/* USER CODE END 2 */
+ T7 `( h, F, B' w4 v7 F! ^* U! E/ d" ~
/* USER CODE BEGIN 3 */
/* Infinite loop */7 x# ]& J. h) y. P& S4 ?9 x
while (1)
{, c" f T4 W: W
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);; m. G- X3 q8 H+ ^. K7 V7 l( y
VisualScopeAngleOutput();
HAL_Delay(100);
}
/* USER CODE END 3 */# u: [$ B7 P' }; y g
}
; b4 ~ U2 C) r- h% I4 p. n
/** System Clock Configuration
*/6 F# _6 }& W1 M# h8 t
void SystemClock_Config(void)
{' a0 k% \' C0 V2 `( S
RCC_ClkInitTypeDef RCC_ClkInitStruct;/ {' @6 N- o- A# i; s5 W. Q
RCC_PeriphCLKInitTypeDef PeriphClkInit;9 U" Q( }! i8 x
RCC_OscInitTypeDef RCC_OscInitStruct;
$ y" Q( T0 B0 V, v
__PWR_CLK_ENABLE();* b8 M% ~9 X' }; ]( j! g1 z/ v
! R3 U* \3 o+ k- c% n2 a3 M, i
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;% Q* X8 s" B& l# q. A) P3 b% I
RCC_OscInitStruct.HSIState = RCC_HSI_ON;+ s1 o, e% u# o
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
8 V: v2 _' M3 w+ P9 b
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;6 c0 A7 K6 M# l% O
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;. n+ i+ x8 ?% H6 @
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;. K, ]9 z, X" T
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
) m0 p+ a1 P. t, l4 c
__SYSCFG_CLK_ENABLE();
}; `3 D: V J" }. u( D/ ^; I3 O& O
/ t1 R. c( O+ p3 k3 p4 l; Y) P1 i
/* USER CODE BEGIN 4 */9 Q7 ?) e$ m0 P' L8 g
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)! M0 D, S$ P0 f7 s6 L' ^& O
{( N H ^3 c- P s; g
if(huart->Instance == USART2)
{
memcpy(txBuffer,rxBuffer,RXSIZE);) B( Z6 J1 V0 L* k# d+ i
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}0 |7 M% [% E* t* u
}3 ]: r8 R% \6 M
5 r# z8 j; W- x! p4 |# _
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)( ^& _7 v. U1 u/ t. D( i: h
{
" _6 ?2 z& L3 _5 d' h! F8 i- Y
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{5 D _# F6 F) h2 j2 _
int32_t GyroValue;1 [8 }8 x' q9 `. d3 N" |
4 v+ L$ n: G$ X; q
Calc_AngleAccel(); E. J3 h" I9 w3 M7 s# j% V% @
GyroValue = Calc_AngleGyro();7 o; A1 a* T) }% S
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。