拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:4 M% s2 q( f, A! t B -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c$ l8 W z2 \) T8 F% m' J6 P #include "stm32l0xx_hal.h"2 M( D9 I$ ?' E6 M. z* F# o #include "dma.h", S7 J' U; Y- Q4 q; v #include "i2c.h", g4 G! `3 |0 h4 T, k0 s1 s3 f #include "tim.h" #include "usart.h"$ {; e/ n! Q3 i0 u5 L; q #include "gpio.h" #include "mpu6050.h" #include "visualscope.h"4 r2 _( s+ e3 N4 s6 p. {3 G* x #include <string.h> #include <math.h> /* Private variables ---------------------------------------------------------*/. L9 m4 q7 u) R3 M- m' [' e- E4 i #define RXSIZE 8 #define TXSIZE 8 uint8_t rxBuffer[RXSIZE]; y( I6 p: C" v2 i, x( X* S uint8_t txBuffer[TXSIZE];; c4 g6 I5 S5 T* s+ I & O) j1 B# _+ P* Q/ g: B3 o6 Z4 R float Angle_accel = 0; float Angle_gyro = 0; float Angle_comp = 0; uint8_t outAngleData[10]; /* USER CODE BEGIN 0 */ /*---------------------------------------------------------------------------------------------------------*/3 Q" _9 M6 L: b+ i! r /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel() {6 c4 I8 {5 s( _" f, X int32_t value = 0; * Z5 y+ O( z. S) ^: y V3 r value = GetAccelValue('x');3 N0 t' E8 x, x3 _4 C+ V. L if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296);. u6 D) M% h" c1 m4 a/ y: M else4 O. a2 q! o; @9 v& a! @ Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); ; W6 E) u3 h7 I* \5 b return value;# W r1 _+ R# U, F, D5 w& Q0 s5 X } / J) W& P; a* ?3 i+ c /*---------------------------------------------------------------------------------------------------------*/ /* 角速度算出来的角度(积分) */0 V0 e% o4 Z5 K1 V6 Y /*---------------------------------------------------------------------------------------------------------*/. C# c% [' e0 C% ^3 p# ?1 S6 F int32_t Calc_AngleGyro()8 U. [ G# E* h& W3 c { int32_t value = 0;2 F! D% n0 w5 p Z- ] value = GetGyroValue('y'); Angle_gyro += (value / 16.384 * 0.01);2 C0 _4 r% s( F2 r7 Y; l* M- V return value;2 M9 F+ v( \5 P7 X& f: ^ } /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */7 K* ?. u) H Z1 f y2 H /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro) {, q( B+ p) i& X3 m3 E! }3 ? Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;8 t; b9 n6 s1 ~$ c* F+ e return Angle_comp;2 {! @2 O1 W( `& X0 ^/ {6 I. ^, o) D } : `. R+ e4 }6 K /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */% e" D8 M- [& E6 p( f1 B" w& h /*---------------------------------------------------------------------------------------------------------*/ void VisualScopeAngleOutput()# z( D( w& [; f! {8 \; | {5 p6 Q/ b, Y% y) X" b int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;4 I: D3 e" F3 x) S uint16_t crcValue; AngleValue_Accel = ceil(Angle_accel * 10 -0.5); AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);$ P: R5 J1 M1 k AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); / I, u- |0 C; i/ o; }6 `1 X outAngleData[0] = AngleValue_Accel & 0xFF;. h4 ?/ h4 |4 d6 V; V9 T1 h( D. ` outAngleData[1] = AngleValue_Accel >> 8;/ m2 q8 Q5 E- U' U5 e outAngleData[2] = AngleValue_Gyro & 0xFF;1 G9 t/ k' Z1 i! M outAngleData[3] = AngleValue_Gyro >> 8;' D; |" E* P6 L# Q E# r- _ outAngleData[4] = AngleValue_Comp & 0xFF;' g3 V; J5 |; N3 k8 h outAngleData[5] = AngleValue_Comp >> 8; //计算CRC: X, {) Q' N* P9 Q, ^ crcValue = CRC_CHECK(outAngleData,8); outAngleData[8] = crcValue & 0xFF;" x& r5 _7 t% B: t outAngleData[9] = crcValue >> 8;6 ]# v& \2 r, _& V: F4 a6 P1 C //发送至上位机( x! Y' }8 Z1 J1 E& i: {' ?3 V% z HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData)); }% x7 [6 I2 T( r5 M3 ]! y/ H# O0 ]2 ?( x+ Q /* USER CODE END 0 */ /* Private function prototypes -----------------------------------------------*// [7 \, ~, D, C# ~* S/ I: _0 S, r void SystemClock_Config(void); 4 L3 X- T) f- M$ G' ^ 硬件连接图: 波形图: 最后加一个视频: STM32L053 演示3 ]8 X* D( X. c- C/ x2 s) j |
意法半导体最具性价比、速度最快的单核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") e6 w. c; L& `) ]4 {7 [
#include "gpio.h") D9 Z# w; g1 B6 g, g
, Z( S3 w# U k
/* USER CODE BEGIN 0 */: {4 _. V5 m4 `! e4 R3 `& j i/ {
/ e8 b' {1 M# l) z8 ~1 [
/* USER CODE END 0 */" i* u1 s' B1 k7 F5 _& i& r
I2C_HandleTypeDef hi2cx; J8 g' A. s N M& i
2 `# `/ v+ s1 }* b/ n; u
/* I2C1 init function */8 N' B. A/ V* ]! C! y8 v
void MX_I2C1_Init(void)
{5 i8 i% V. F* p, C& L
hi2cx.Instance = I2C1;- ?% A0 v& }" w8 ]) W: f' K! r, N
hi2cx.Init.Timing = 0x20D22930;) `! i1 }5 q% @) C3 A
hi2cx.Init.OwnAddress1 = 0;1 s9 a# D) l5 d# j# c
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;" t& b2 `+ D) r$ J |7 d
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;& @6 ?& c3 X; l0 ?. R1 y
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;4 v1 u& W% ]. o$ h/ }1 L6 @" O8 \0 r
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;' C, P5 J; Z5 X' i0 L
HAL_I2C_Init(&hi2cx);
/**Configure Analogue filter6 k; \% q* |6 t! o- O( [
*/
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);, o7 H/ I# U, r5 U+ i
3 _$ b* `, D+ S; w) G
}
6 P1 E# N# k% y) q0 L
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)8 f9 r/ w/ o6 m% R+ Z$ m$ a5 T
{
/* Peripheral clock enable */, y# E" o. \* j1 z
__I2C1_CLK_ENABLE();
1 c) G5 z& z, n8 u+ v
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL) m7 a Z3 S* @9 D+ b0 M4 U2 M
PB7 ------> I2C1_SDA, b$ l |; C2 w9 I* B3 N
*/* h( V# W: G2 K1 a. A9 v
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;" _4 @' R j. [
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;7 w6 w8 P, o) e4 Q/ P4 F
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);; w' |. c! [4 ]- j1 ~( o% N
}
}
0 |+ n3 _$ c9 i5 J' d) H4 O7 e
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1), i4 D: n* `3 B3 N! J: |
{. A" x+ }8 c# l/ M( ^( C6 i2 X; M
/* Peripheral clock disable */
__I2C1_CLK_DISABLE();
+ L5 A# l& [" n; Y$ Q
/**I2C1 GPIO Configuration $ i6 e9 D+ G( i& S
PB6 ------> I2C1_SCL$ X) F% ?3 q+ l7 y5 V. Z
PB7 ------> I2C1_SDA
*/: \5 z- {) A$ Y9 } F5 O; [+ l# N
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
}- `; h" v( X! w9 b r
}& w) s2 @' e) q: q2 t' ^4 X
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------. |6 L0 t; L" y7 z* _# X$ ~
usart.c
#include "usart.h"
#include "gpio.h"
#include "dma.h"1 d$ J# C8 \( T1 I+ C4 z* h
4 y3 @ A+ @; `# D/ j7 i: D0 k' ]
/* USER CODE BEGIN 0 */
" h0 n3 n7 L1 Y7 E/ V' ~+ Y
/* USER CODE END 0 */
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;# r0 K. m/ O O- @
DMA_HandleTypeDef hdma_usart2_tx;
/* USART2 init function */! \0 D* z0 s" p' O5 K3 |4 D3 S
void MX_USART2_UART_Init(void)
{
# \9 {1 A0 z: |9 q( ], b
huart2.Instance = USART2;5 z4 e) t, `$ l# k' ]4 D
huart2.Init.BaudRate = 9600;" F# A/ j" W; m% }
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;. @5 [0 v B8 _0 e% c
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;; y$ p7 \, t1 V
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;; z) c& E" Q! x; `4 p6 I
HAL_UART_Init(&huart2);
} f. L3 i& [) Z- T+ B% v
void HAL_UART_MspInit(UART_HandleTypeDef* huart)4 w* g2 e9 @3 F# T
{
GPIO_InitTypeDef GPIO_InitStruct;* X4 f- \: M9 B
if(huart->Instance==USART2)
{5 F3 K2 ` P6 g: A7 A8 E# i
/* Peripheral clock enable */
__USART2_CLK_ENABLE();' i0 m( U4 m0 P
/**USART2 GPIO Configuration # _% B! q, q$ x, _5 K4 x$ t! y
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;' b# Q' s+ b& _& x* e* N/ ^$ `6 f
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;. G7 y9 W8 D4 J% F9 Q
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);& f/ X! p; q4 t) ~' ~9 w
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;5 m R8 y& R, ]( E
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;3 `4 p" _8 `7 N8 k8 }: M
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;! G, I. i6 W, i
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);6 \% s( v8 V) @) `& w) x
/* Peripheral DMA init*/3 I% Y6 r3 i) ]2 ]* n
hdma_usart2_rx.Instance = DMA1_Channel5;5 g- L! w. I3 M Y' k% O5 [$ {8 ~
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;5 _2 z& ^$ f7 D! o
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;% f* |0 r7 u# D
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;5 y, _. w3 a4 W+ d6 ?9 L# Z
hdma_usart2_rx.Init.Mode = DMA_NORMAL;' H. R. Q* j+ V$ l+ Z* E/ i7 A
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;- B J! W8 `, C$ u9 n/ ]
HAL_DMA_Init(&hdma_usart2_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);& X0 v& e8 m9 F. U4 l* `0 z& \9 {6 ~+ H
2 } Q0 r. V8 P3 d9 U' U* t
hdma_usart2_tx.Instance = DMA1_Channel4;/ b9 i: h6 u! K, @2 M
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;" _" ]& f7 G* S' m& y1 f$ _; F
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;( J4 t; J- E( @( Z+ G1 ~
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;& g" u! r& t8 K6 a2 @$ Y4 o
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);" _6 Z7 r6 { j8 ^5 D) j
! Q- n9 Z7 A$ n2 f) {6 Y+ ^! O
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
0 s: B& | z- D0 [$ K0 J( J
}" ^2 O$ f2 W1 k3 ^
}. z: t3 L: X S7 N- N; X! V
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{% z" |: M7 T! k& w+ b# u1 j+ f
if(huart->Instance==USART2)$ j5 v( ^& M7 d! L o0 n% K, \
{
/* Peripheral clock disable */) B* C; q6 u' Z
__USART2_CLK_DISABLE();( Q' c% ]' V+ R1 P8 M0 \( A# W# g+ Q% @ O
J0 @6 }2 w, b- C( Y7 z/ F
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);# b- k2 x: G" d% M
/* Peripheral DMA DeInit*// U! U0 n' s; P! R+ I9 ]
HAL_DMA_DeInit(huart->hdmarx);5 ~) G/ `( a- }4 _
HAL_DMA_DeInit(huart->hdmatx);3 M0 F" H) ?, Q4 l
}' p3 E0 `8 p0 L& D" q8 Q
}2 e/ n* h2 t, w) B" q3 M
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------0 h! V* ]1 m; W8 K1 T" E
mpu6050.c
#include "stm32l0xx_hal.h"/ U; Q z9 y9 c+ q S3 d
#include "MPU6050.h"
//各坐标轴上静止偏差(重力,角速度)3 [, p+ g2 N) s" _5 u
int16_t offsetAccelX = -195;
int16_t offsetAccelY = 560;
int16_t offsetAccelZ = -169;8 g; J1 v2 L7 w. C* x5 c$ r
int16_t offsetGyroX = 12;& t+ B) W3 V8 v0 | `
int16_t offsetGyroY = 33;% O5 [4 R, N# c. {2 o' _# j+ C
int16_t offsetGyroZ = 4;
0 ^' G2 r% A" i6 X' |
extern I2C_HandleTypeDef hi2cx;
4 D- |: V& v) t1 x. |
//**************************************5 L. [6 R) P8 c3 ~- u% K
//向I2C设备写入一个字节数据3 E* V( g- y! E, W" r2 l# p
//**************************************
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{
uint8_t rxData[2] = {REG_Address,REG_data};: K" y) f4 B1 t
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)2 t: ^2 H" u l' B
{5 C4 @% P7 [& {$ c: w/ }
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}! M# `: x1 G! v0 r) h& s
}
}- \. }7 p E _" @1 U5 u
//**************************************
//从I2C设备读取一个字节数据9 Z" R! k# L6 u" }
//**************************************
uint8_t Single_ReadI2C(uint8_t REG_Address)
{
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK): b9 b$ l, p( K& J- W# C9 i9 ~
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}, i; g* }* ?# M* Y9 l
}
" \8 f" j, e1 q. G
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
{+ L; U' s8 v5 T# n- }. K) D0 i
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}
return REG_data;
}% w; g/ T5 Z+ D
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{9 D. o( _" K" l
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态7 U$ l4 o/ \4 F1 P3 o
Single_WriteI2C(SMPLRT_DIV, 0x07);
+ Q. B7 b2 r( e4 x" x5 k
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);
( X5 _# M7 l& B3 I& w! V$ S& ?
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************- s8 Z1 r. j4 I* g. {7 ~
//合成数据
//**************************************$ K1 P7 d0 S* l+ Z
int16_t GetMPUOutValue(uint8_t REG_Address)
{* z( h, v3 W, k1 y5 P7 @
int16_t result;# w+ h% \. A* Y7 w+ ]7 h
uint8_t H,L;5 f5 r' |* @: X8 R. @/ D) P
H=Single_ReadI2C(REG_Address);+ j: Q0 M# @/ Y3 z6 y) R
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;
return result; //合成数据
}
//**************************************( }" _$ n1 Z( |. ^& M/ R
//取某一轴上的加速度数据
//**************************************0 z B5 Z! z4 V% e+ n
int16_t GetAccelValue(char axis)6 ?( f. U9 o2 `2 F# v
{% i& d# Y; B' X% p
int16_t result = 0;
switch(axis)
{; v, _& g3 L; |0 r/ w' C
case 'x':; q( }1 b& y4 h3 I1 Z
case 'X':
{
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
}* P9 o" I) O6 \5 i
break;; e# h W) O" U8 G- v3 u' {7 h
case 'y':
case 'Y':- x, @' V) V. I `$ Z3 K d
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
}- ~: r* ~( l: D4 q' s- R
break;3 E! D2 m( `9 S: E4 g4 C
case 'z': @. F( p z& E( p1 ]
case 'Z':
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}" \ K( r! @: u. d1 ~7 v
break;
}
return result;; _1 y/ f5 q$ c
}: `# m' n" m7 V5 l4 L$ |4 y8 A
& t# M( Y+ Q; P# w
//**************************************9 F8 I8 N' I, p, G
//取某一轴上的角速度数据8 F% S' Q) T/ L3 h
//**************************************" T9 O& B3 s0 F/ m3 G
int16_t GetGyroValue(char axis)
{
int16_t result = 0;
switch(axis)5 ~7 D# j# w+ b! A
{. O2 O8 _/ h5 h" w8 U$ {
case 'x':
case 'X':) Y9 X$ [% E }- |- H5 e" e
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;6 F7 L4 C) M6 Y9 s: X5 f2 z# \* w
}4 `3 \9 ]2 h# [& v" d' z/ b; e
break;
case 'y':+ k, `2 s/ w$ r/ x+ P( @
case 'Y': [# E. {7 C# O' b/ s! G1 ~
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
}
break;
case 'z':
case 'Z':
{3 \ S( _ k; J
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;0 @- W) h! A) k4 t
}: Q8 n4 ^7 T f c+ t
break;/ A b. P V1 Z* x5 u* _
}
return result;: b# r" z& q( J( v, _
}
评分
查看全部评分
{# K# T* t e7 C- ^, c+ L
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */$ B7 ~. }& C' w0 l* Z4 ^5 f5 O
& o; G6 h+ f6 `( `/ s" z+ t) M% \( T( C0 k1 ~
/* MCU Configuration----------------------------------------------------------*/5 q$ M, L G* \( o* I
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */7 i" X% d f) e
HAL_Init();$ j2 `+ W3 M8 g
; L N0 U4 `* g$ [, y4 u; u7 A
/* Configure the system clock */5 q( G3 ]4 w7 ?1 `
SystemClock_Config();6 t# W& z# t7 _1 e# w, h- K: q
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
^/ s- k1 x# |5 B7 C0 |/ h. R d% r
/* Initialize all configured peripherals */# J @$ D5 h9 F* M) ^1 k0 p3 R
MX_GPIO_Init();; D- w/ I' ]$ a2 N5 g% a
MX_DMA_Init();1 [0 y; a5 P8 k/ i, j' y9 S
MX_I2C1_Init();
MX_TIM2_Init();. f! \( [7 M; { z) d7 p2 `, N
MX_USART2_UART_Init();3 S- i# z2 C* R* I
InitMPU6050();, N& W. w* g2 W( }5 ?# @7 N
/* USER CODE BEGIN 2 */6 }+ U% A9 d" p* M8 v7 h5 J
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */
; `2 m p5 c9 z+ [2 B% a! i
/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)
{2 |( T9 R8 `( C4 g# @! d& G3 |' K
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);8 w3 S! x/ q/ X; ]# Z
VisualScopeAngleOutput();% o7 E( I9 }2 J; z H! Q
HAL_Delay(100);/ i7 z7 ?3 F' O3 D2 u7 c; z
}
/* USER CODE END 3 */9 t: r4 c1 w0 Z m. n0 f! w8 Z) |1 ?
}! v3 [+ e! m4 ^2 q5 n1 _% E% W2 A/ W' X& u
% d0 ~* R1 ]2 g6 Q& J% \
/** System Clock Configuration& z n$ U9 `+ J$ r$ y3 A! e
*/
void SystemClock_Config(void)
{8 _% J* U$ j* I/ w9 D
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitTypeDef RCC_OscInitStruct;
; v6 ~# v: l: ^7 {3 j2 \
__PWR_CLK_ENABLE();
* ~3 r& e) w8 s
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;9 U( N+ |6 H) ~6 b" S! f
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;" F; _3 H; [( p7 N, D8 t1 F
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;& _: O; i( u, D/ L! z1 E) r
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;9 l' k$ m9 k! H' G0 `
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
+ l2 N: ]% s( u# m q. _
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;. q9 m* @0 ^8 q- h3 Y6 @) ~
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;! {+ T5 I2 k$ T
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;1 N8 b3 s ], ]7 D# D1 k
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;5 [- [( p% H1 b
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;$ a0 [0 u. V6 i' r3 W
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);/ H/ a" d- G& Y" ?
4 B$ t2 t y9 A1 G2 F
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;+ ^5 D' k; R( h: g; W/ L/ r
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
/ h! s e D W
__SYSCFG_CLK_ENABLE();9 r; ]: S4 C* b) u5 R
: P8 O6 u2 D/ j( ?9 u* F
}
/ P) I5 w, P9 o/ q4 B* {5 }
/* USER CODE BEGIN 4 */* ~+ A$ S& g: v+ x( u+ N
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{, e# W% X9 q0 Z3 Z* I: N( }) {) }4 K
if(huart->Instance == USART2)
{
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);4 }5 ], Q4 }3 M2 p) p
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}
}- X* X a% V5 `. y' G
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)3 |0 ^( F- O& W6 F1 ]
{" B w6 d! m9 C6 v. y! u* ^5 `
}
" [- T% e) W* l) R6 W4 ~
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
int32_t GyroValue;# V8 T! u8 _: Q9 P
Calc_AngleAccel();
GyroValue = Calc_AngleGyro();
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。