拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:; q' x: E2 U; T. I5 Q4 [ -------------------------------------------------------------------------------传说中的分界线----------------------------------------------------------------------------& i$ B7 w$ b( Y main.c! Q [$ H( N/ z# i! T7 k" v2 u# } #include "stm32l0xx_hal.h"* N1 Y+ G9 z- ~+ [ #include "dma.h" #include "i2c.h" #include "tim.h" #include "usart.h"1 Y! f5 ~ S. R+ @0 \& a! u #include "gpio.h"+ W4 K# O i2 H! G% q/ @ #include "mpu6050.h" #include "visualscope.h" ( t C! X& R* a+ _3 K #include <string.h> #include <math.h>6 | _- t5 K6 L* _4 @ /* Private variables ---------------------------------------------------------*/6 {6 Y% T6 {0 K8 C8 \ #define RXSIZE 8 #define TXSIZE 8: V' o7 v. y" G; K uint8_t rxBuffer[RXSIZE]; uint8_t txBuffer[TXSIZE];$ c- X- w+ B8 I& r3 r % ~6 w$ F. w9 `, x7 T2 {9 r0 w' V8 z float Angle_accel = 0; float Angle_gyro = 0;) U: t8 U* t8 |5 A, E$ E# x$ d3 y float Angle_comp = 0; uint8_t outAngleData[10]; /* USER CODE BEGIN 0 */; G% y' M z2 F /*---------------------------------------------------------------------------------------------------------*/ /* 重力加速度算出的角度 */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel() {6 I" F& y( S1 ~$ M3 D3 g int32_t value = 0; value = GetAccelValue('x'); if(value > 16384) Angle_accel = -(asin(1) * 180 / 3.1415296); else8 Z: s. Q4 {7 y6 u; t# s Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); return value; } % v) U7 d2 E, r' u0 p* C5 V, K /*---------------------------------------------------------------------------------------------------------*/ /* 角速度算出来的角度(积分) */) G/ W) ^& I7 U /*---------------------------------------------------------------------------------------------------------*/+ H1 U% x. Z6 A/ T6 t int32_t Calc_AngleGyro() {3 F; T0 k' V, x' g9 s/ {' n int32_t value = 0;# U- S- `7 s+ I0 V' L value = GetGyroValue('y');# E$ P. q0 K& L$ [; _6 a Angle_gyro += (value / 16.384 * 0.01);4 B: Z$ I I% z% _+ L return value; }1 K9 K/ O9 F# u6 J * V( Y( x7 S* F9 w /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */0 h% J7 ~5 P- b5 K* U; x4 Y /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro) {1 e: R7 b& y0 n Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;" ~" `' i* q4 R8 [! C$ F) \( U x 0 T# V2 S: I/ Q: `6 n, | return Angle_comp;) e' X2 k* C1 [5 M; { }/ ^) A5 T7 _& V$ e9 S+ B /*---------------------------------------------------------------------------------------------------------*/) u6 ?5 }! v, W9 b7 ~# g, p5 _ /* 输出角度至上位机 */( o+ ?4 W5 p4 M' j7 Y /*---------------------------------------------------------------------------------------------------------*/1 \$ _- m( z0 W/ i p void VisualScopeAngleOutput() {! ]! W8 o: _. X" j1 C) j5 N int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp; uint16_t crcValue; . C* V! c3 l: b t( A6 H; I AngleValue_Accel = ceil(Angle_accel * 10 -0.5);1 j& y/ ] n; `. l7 c4 v) w8 j AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5); AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); ) X' F: M! R/ c outAngleData[0] = AngleValue_Accel & 0xFF;7 h: h5 W3 Z: D outAngleData[1] = AngleValue_Accel >> 8; outAngleData[2] = AngleValue_Gyro & 0xFF;6 e. {0 U/ Y0 I: r1 A; g) B outAngleData[3] = AngleValue_Gyro >> 8; outAngleData[4] = AngleValue_Comp & 0xFF;: l7 |! d' z; J! k- Y/ [ outAngleData[5] = AngleValue_Comp >> 8; //计算CRC2 `& {" y; J1 Z crcValue = CRC_CHECK(outAngleData,8);' b/ G! }+ D1 C; C outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8; //发送至上位机4 [: w# D* V5 X3 v; T! Y/ G- R HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData)); }- G; o7 Q6 I. J+ b; x /* USER CODE END 0 */" X: f5 r8 B/ l" ]; c& ~ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void);' b( j" @' j7 ]5 O8 z 2 l9 O. D8 Z* p5 a+ t ' ]5 G; j1 x2 ^1 B+ X3 ` 硬件连接图: 波形图: 最后加一个视频:/ T8 N3 d% n0 I7 `0 r STM32L053 演示/ m: \. D- z" n) m' N y# X |
意法半导体最具性价比、速度最快的单核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"
#include "gpio.h"
4 f* T% O0 m8 _/ P* N! l$ c+ }. }4 j
/* USER CODE BEGIN 0 */
/ c* _" w* |' G2 `
/* USER CODE END 0 */
8 V( ~1 n9 o. a4 L& Z# u9 [
I2C_HandleTypeDef hi2cx;
/* I2C1 init function */0 @7 q- h8 _& f
void MX_I2C1_Init(void)
{
hi2cx.Instance = I2C1;
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0;( Q: }* t# F+ y8 ^7 ~9 Q1 K
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;. m5 a% p% ^* @! q7 ]1 Y+ t2 g
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;# Y6 T' |. a% m
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;: n3 q5 {, `' P5 b. i
HAL_I2C_Init(&hi2cx);
/**Configure Analogue filter* d4 `2 z: i4 C& P) @) R" I
*// P: b9 b4 C) F: p2 X+ g. A0 T i
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
}+ |# J0 s: h u
0 W. s6 ~0 m8 ?# {0 T3 `
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{4 Z4 B- m7 R6 Z/ t' r5 \
! t) T& J$ T+ K7 p/ _/ `7 t
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)) @; t- L% }3 s1 c# V- t
{: C& l: t: K5 L4 q: V- p$ R
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();
/**I2C1 GPIO Configuration 8 k2 [0 U1 n9 }( q5 z
PB6 ------> I2C1_SCL- n4 Y+ {. _" ~0 z/ S- P
PB7 ------> I2C1_SDA: [7 @" A' \& Z& [* _
*/+ e% k4 K4 d( ?: d
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;* c6 C3 W; {4 R0 b! j
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;- E! Y7 R U2 E( L, E, j
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}/ k1 f- U$ m/ M4 G) o" E8 d- O( a
}& V; Z* J4 o' c8 w" A8 }
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)0 W* A( j _, q$ L% O! ?
{
/* Peripheral clock disable */
__I2C1_CLK_DISABLE();+ T' |' G0 [ D4 |
, S/ `, \. @2 K9 n0 Y7 p
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);& v3 |. B E) q* ~% y J
; ]$ i3 y2 C3 o0 W" a
}
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
usart.c! I R0 b4 p; z, E- \
#include "usart.h"
* s, J9 u$ c9 L* e; ^( w
#include "gpio.h"
#include "dma.h"2 I- F. O' X! m
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart2;6 d, Q. i, q1 X* S: t
DMA_HandleTypeDef hdma_usart2_rx;+ n! L: P: s& c( q4 x+ C/ I
DMA_HandleTypeDef hdma_usart2_tx;9 f* k9 S/ O. g8 `
- u- c2 K( v$ ~, m
/* USART2 init function */( i3 k* C; h& D% Y) B
void MX_USART2_UART_Init(void)
{6 t8 p r' J. D7 H4 c8 `
huart2.Instance = USART2;7 ?' }% m8 ^, w I
huart2.Init.BaudRate = 9600;4 C7 x. q W% \& b+ ~1 S7 n% j; C7 ~
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;: B' G2 j# y) x$ m
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;4 `1 J- X( l/ `/ n5 f
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;! U$ G0 F+ R) ~$ y
HAL_UART_Init(&huart2);" K( u) f: R+ A! B$ M- S
; E* V5 a" g a- l1 D2 N
}
6 i7 ^ T, d3 M: b
void HAL_UART_MspInit(UART_HandleTypeDef* huart) [' k- p, H3 O8 h% k0 B
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{
/* Peripheral clock enable */
__USART2_CLK_ENABLE();9 {, M7 Q% j+ \' x
- C& ]. X- G3 _; e
/**USART2 GPIO Configuration 6 z# ]6 B# q5 {& _2 {
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;$ F k% c6 S+ t7 I* T
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;/ }& J+ z' I" l _
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
! y n/ m; _# n! D: h0 q
GPIO_InitStruct.Pin = GPIO_PIN_3;% S7 g2 C4 u, W: O" g
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;- E/ W: t$ T2 m; l9 o# Q
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/ M0 K7 M0 k2 Z! M Q2 H o
/* Peripheral DMA init*/
0 c% S3 t& p& |6 [* L6 l0 `( m! C
hdma_usart2_rx.Instance = DMA1_Channel5;- O8 y$ Y+ E( h1 d# j
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;. D; X. `6 w+ S6 [9 c# C* w) b+ n% D
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;4 N( n% ^$ W' D0 H' o' p* B
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;& s% g2 Z* a3 F9 Y+ |
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;, |. T! {' `5 i# L \
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;( |5 R4 h& @( \ w
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);9 s( \! q+ F% _* q
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
hdma_usart2_tx.Instance = DMA1_Channel4;5 X2 H. M2 v" m) c+ w
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;( \* [4 O4 J- k. C* H) p
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; ^! L$ B8 @7 x# i* e" s6 L( n- F
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
6 q( \ [+ j: N I1 N6 _( e
}5 o" Y) T2 A- N9 n+ \" `3 }6 R
}# N' g+ [* _ g) @$ N' `4 E: V# k
8 G) E' I. C7 ^% ^8 q
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{3 a) ]' D3 }/ d3 L! ?# X+ y
if(huart->Instance==USART2)
{ m6 o+ j, \- Z5 g8 S' C4 b
/* Peripheral clock disable */
__USART2_CLK_DISABLE();4 n4 R& \" h) M Y6 }8 D
9 Y; x, A; f4 c5 I
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX# B; l) O2 a8 N; g3 W. D
*/! I$ k5 i {! b, }
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);: Q( a7 \, I @0 o
/* Peripheral DMA DeInit*/+ t6 p) C1 ^; T) H
HAL_DMA_DeInit(huart->hdmarx);
HAL_DMA_DeInit(huart->hdmatx);
}7 k' c9 w6 ]% X+ C' M: V, j$ n
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ R& |- s7 h) A* d' Z$ G, E
mpu6050.c% X5 N& w5 r$ g2 n5 `
#include "stm32l0xx_hal.h"7 E5 n: A, F# m1 ?+ e* O
#include "MPU6050.h"+ |/ Q0 v* q2 T5 S) T& w8 M2 a3 O
" W9 S! W& A- U4 X3 t/ y0 p& {" r
//各坐标轴上静止偏差(重力,角速度)
int16_t offsetAccelX = -195;
int16_t offsetAccelY = 560;7 y% V0 ~# I# z- d
int16_t offsetAccelZ = -169;
int16_t offsetGyroX = 12;) a8 u2 A6 t* |7 B) J9 ]/ e
int16_t offsetGyroY = 33;7 W1 `, i1 F$ ~
int16_t offsetGyroZ = 4;2 }+ n* y, ~, @7 [
' _% L6 h6 m" j
extern I2C_HandleTypeDef hi2cx;
- b# X, u2 Y X/ z
//**************************************/ y. X4 o6 U Q0 J
//向I2C设备写入一个字节数据 a1 K+ `, u( b% C" }6 u
//**************************************8 `6 j4 T8 |8 u3 a( @: c! a* o& s
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data) B8 U. X( [: T1 m5 n& l
{6 v2 ~ m6 U7 d. H. Y6 o" r; l, v
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)
{, N' R& u+ S6 I/ |, O' V; }
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)9 e5 V! \6 E4 g) [; V! X
{}
}% P+ L5 ^$ D; q0 r
}" N" p% m8 a3 L8 e
//**************************************& x, K! G4 y. e* r4 w, H
//从I2C设备读取一个字节数据
//**************************************- C8 l8 B3 L Q3 I5 L
uint8_t Single_ReadI2C(uint8_t REG_Address)
{1 o2 w9 C, W) m& R: N
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)8 o4 a2 X/ C+ i2 b! ^/ J2 }7 \
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 n2 z% B2 s! \9 |
{}# C" }- Q! d8 H) t9 A* b2 i, p4 z
}
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)+ M' g& h9 T# @- P
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}+ ]# [( r. l6 ^7 H
}
return REG_data;# X. U7 H; i2 r2 F9 p* U8 c7 I
}( x! p7 X$ D9 h$ f0 C
//**************************************+ h; d# m/ }! f7 O: Z D
//初始化MPU6050% B- j! Y8 T) d6 P
//**************************************+ ]% ?9 c; C6 @1 u. l
void InitMPU6050()# W( _1 G, z w* `$ G5 s3 ?
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态# y. L! K% f& `% d, O) q
Single_WriteI2C(SMPLRT_DIV, 0x07);
8 |( D6 w, N1 w6 `5 Z F
Single_WriteI2C(CONFIG, 0x06);! N; U7 I4 l. l2 u+ O* L$ |1 i" a% _
Single_WriteI2C(GYRO_CONFIG, 0x18);
9 x% }" q. w- v
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************; Z2 L8 Y2 Q; M7 }
//合成数据. S: X& E1 S9 D( _4 k
//*************************************** q. } ]. R$ f" J' D6 g3 s3 y
int16_t GetMPUOutValue(uint8_t REG_Address): s [2 J! ?6 P* r. J
{/ n- u8 H: z1 s' ^! [* Y4 q
int16_t result;. H) d1 r5 E/ I( U
uint8_t H,L;0 E+ x( \3 `( |1 x
H=Single_ReadI2C(REG_Address);# d# n# y, E# M8 P
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;5 ?/ d I% s6 Z0 [% B
return result; //合成数据9 ?* T5 Z, s0 k: K$ G
}
) R: {3 g( ]' Q( H* k) w
//**************************************7 ~& N7 q0 ~8 r; d
//取某一轴上的加速度数据
//**************************************4 X5 k$ L0 N7 F7 @9 n
int16_t GetAccelValue(char axis)+ [+ ^9 z j/ j) F! I, C3 j* b
{3 v$ \: Y: {7 w1 O7 H
int16_t result = 0;
switch(axis)+ B/ X6 g! M. g' s; K* k/ `. G
{
case 'x':
case 'X':
{
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;
}
break;
case 'y':# K/ f2 y F- ]! _' G+ m: s Q
case 'Y':4 _; f+ f+ @2 p2 w' p$ r, w
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
}" h3 K5 Y/ L0 h; A
break;* u8 m8 w' _9 `1 r) M, w
case 'z':
case 'Z':
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}& r [; v2 Q6 t& C* h4 [
break;( h# n7 M! w7 j% M0 o( w5 ] e
}$ T$ [, W, B$ C7 a
return result;
}! C( y: \ e# [, F* Q+ L
//**************************************9 G# N8 {) A/ P2 H. c
//取某一轴上的角速度数据. h: t/ V/ R6 i* \& \7 Z
//**************************************
int16_t GetGyroValue(char axis)8 h0 q% N3 ]7 R& s d m
{; [& Z) R7 b' E8 m# u% Y N
int16_t result = 0;
switch(axis)+ b! @& c0 _/ J
{
case 'x':1 N" E8 q1 g4 S0 D0 U
case 'X':
{0 q* s8 ^# f+ Y; I& `& R0 i
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;* O. C9 T z( p7 {1 B. `. I
}
break;* C' O2 W7 A5 e( v! u; N& Q
case 'y':; b: ~, p' f' h; q
case 'Y':8 j& N# I5 b- n- F3 W
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
}- x+ P1 V7 f O8 `
break;8 j8 e& l, }9 n; z( k+ M- Q: s1 \" L
case 'z':
case 'Z':& `$ ^4 }0 t; v3 U) `
{
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
}
break;5 G, d g3 K8 _3 g7 [
}- {) P! q2 k0 |
return result;
}
评分
查看全部评分
{
/* USER CODE BEGIN 1 */9 k6 c$ p7 u6 m# H% w+ S
/* USER CODE END 1 */1 H$ _+ ~8 [, K7 x( j
/* MCU Configuration----------------------------------------------------------*/
" L* y" i2 L' z- q( c# L
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/ P) Y! i2 z# I* G; V# j
/* Configure the system clock */3 K7 a. K9 a0 F
SystemClock_Config();; A, Y5 _ C+ D% q, V8 [/ \
6 S W* T8 | B( Q2 q' f! o* S
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */7 n, g0 s8 S" @4 u
MX_GPIO_Init();) N5 C6 P- h# s& y/ R; _6 f8 Q B" A, f
MX_DMA_Init();
MX_I2C1_Init();; w( g4 l* q0 q
MX_TIM2_Init();
MX_USART2_UART_Init();7 k7 j9 h; @' x: W' \0 d
InitMPU6050();* b0 M0 Z0 \3 ~+ J0 y2 d
5 p" @# d+ E/ x- m3 `8 v( V
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);( Y% x+ q" P4 h2 Y' n% Q
HAL_TIM_Base_Start_IT(&htim2);1 @! s% f9 m+ G3 G2 E) l0 E% n
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */" R$ @, e) _ z H& {
/* Infinite loop */
while (1)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);2 B" B# W4 h+ h* z% I
VisualScopeAngleOutput();
HAL_Delay(100);
}$ B7 Q: }5 d7 b }- Q
/* USER CODE END 3 */
6 W+ u& q$ J0 @& O* C* p' ^
}
/** System Clock Configuration; I1 b+ X: K7 p
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitTypeDef RCC_OscInitStruct;( e" [6 M3 G+ G) k
' ^1 a& e* A. a
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;6 E R2 Y5 X; _" N; ~
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;% `; [4 B: [# e3 B$ Y
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;9 z0 |4 G8 o4 L, k7 k
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;1 q' g# V. u. Z, e8 a& T
HAL_RCC_OscConfig(&RCC_OscInitStruct);
8 X! ^' Q( ~( V& H& ~& w. O
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;2 r; O2 [( a- e9 }& c7 G
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;( W: j3 E/ I8 ~3 W# R" P
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;7 ~9 U3 k& c. n0 I# G$ l
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;6 M# W7 a+ f% k) x5 T- q# z
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);1 {. k# C t, p x7 h
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;0 {0 k& M! z# s' I1 O5 b+ R$ Y
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
. j6 R2 i1 i; y- G- W8 s' ~
__SYSCFG_CLK_ENABLE();8 t; |" f+ C9 F' ~
: a7 K/ @5 j J) s4 ~% S" |
}# @- Z5 I$ D7 @# r
( }/ Q% Y1 |# O* v% I
/* USER CODE BEGIN 4 */* w* B/ E2 z' m0 a: c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
{
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);$ f3 e4 M3 a7 v3 |% i& J
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}/ f: ?* O5 h) c0 w3 Z# @1 M
}; o1 [- G& t: S' a( s0 D- b+ `9 g. M0 I
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
& H6 a7 A8 S# o- l; Q. s0 F4 F
}
! I( S0 f- a6 Z% H# G* m3 u
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
int32_t GyroValue;
Calc_AngleAccel();
GyroValue = Calc_AngleGyro();$ L( [9 v, g+ A j3 T3 E
ComplementFilter(GyroValue);1 l, d/ h* p: Y/ {& ^) K( |7 m& R
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。