拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码:* h2 i7 v+ s! H* y3 H! b( \ -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c9 x* ~2 ]! Y8 R; U4 t #include "stm32l0xx_hal.h"" n. S I4 _1 u- F1 u0 { #include "dma.h") | C' N7 q$ s z- [ #include "i2c.h"! T V; x5 R% g4 n0 _4 V% V #include "tim.h" #include "usart.h"9 \1 O/ u' ~& f) f9 T #include "gpio.h"1 J2 B4 o3 }/ \ #include "mpu6050.h" #include "visualscope.h" " z' x3 I" S0 m" U9 T4 o+ D+ M #include <string.h> #include <math.h>: T- y5 }( u( f; D t) C 0 }, ?) A5 C; a /* Private variables ---------------------------------------------------------*/. d" q: d8 }2 F. h0 N6 }7 C7 Y #define RXSIZE 8 #define TXSIZE 85 x6 r+ ]6 E! C; P6 U. z t uint8_t rxBuffer[RXSIZE];* ?7 I( ^+ A) H5 A- o+ ~0 g uint8_t txBuffer[TXSIZE];( }" h- e# D5 A$ [$ ~# t 3 c: Q4 V/ ?, F- i float Angle_accel = 0;, m/ y( ^- {$ T+ f float Angle_gyro = 0; float Angle_comp = 0;/ @/ h2 y" E2 L' G" ? uint8_t outAngleData[10]; /* USER CODE BEGIN 0 */ " c) F4 s8 E+ t1 J9 p& R /*---------------------------------------------------------------------------------------------------------*/ /* 重力加速度算出的角度 */' K. e- R5 f' f3 R3 n( i& K- ` /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleAccel() {7 y. H2 S+ O$ u+ A6 ^4 v" d int32_t value = 0; - w4 r! O& T3 X9 I6 v9 K value = GetAccelValue('x');- N) I) Z+ w8 n, N$ q' L if(value > 16384)6 Y% E6 u5 q5 N$ s7 A* ?5 [ Angle_accel = -(asin(1) * 180 / 3.1415296); else/ h9 X/ C3 O5 H7 x. T Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); return value; }) `% M* t9 ~2 p4 R1 q& G3 u L /*---------------------------------------------------------------------------------------------------------*/' Z7 _/ X& F+ X; K+ M# I* v /* 角速度算出来的角度(积分) */ /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleGyro() { int32_t value = 0;: n9 \1 N ]" {, j5 y" z value = GetGyroValue('y'); Angle_gyro += (value / 16.384 * 0.01); : h) z5 D, G4 j. |: m return value;% B2 b2 z7 b5 ^# \* O9 x& B }, K. t! Q4 S+ P5 { /*---------------------------------------------------------------------------------------------------------*/ /* 互补滤波求角度 */( n2 e( J* u. i$ i- I/ Q/ o /*---------------------------------------------------------------------------------------------------------*/ float ComplementFilter(int32_t simpleGyro)" V7 E0 H) z! U/ E/ V {: |4 c+ }) r2 Y& B& S Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;) E# C9 e2 S+ m+ o% _2 j return Angle_comp;* f+ e# N/ {$ _ } /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */) V$ c! v8 }3 @+ s2 K, d, } /*---------------------------------------------------------------------------------------------------------*/ void VisualScopeAngleOutput() {) S5 l9 C9 I, `' a$ ]7 L9 v int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;3 t: @ N: R! D8 N9 o/ @ uint16_t crcValue;# x/ ~1 `1 Y; F5 P2 n/ } , J* s' v @ Y9 y AngleValue_Accel = ceil(Angle_accel * 10 -0.5);4 |- ?7 U4 S; E1 V. A AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5); AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); % {' k. {9 o, s! C2 {0 R outAngleData[0] = AngleValue_Accel & 0xFF;# X/ J; Z9 r: T! {, b/ B3 { outAngleData[1] = AngleValue_Accel >> 8;; i: ]( A" \' p2 g9 {4 |, E# e outAngleData[2] = AngleValue_Gyro & 0xFF;" C2 A% Y3 ?; h- I outAngleData[3] = AngleValue_Gyro >> 8; outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8;% d: B+ w: Q, Y //计算CRC3 ~* }" E9 {) U9 z0 _ crcValue = CRC_CHECK(outAngleData,8); outAngleData[8] = crcValue & 0xFF;, s4 I- F S7 w. W outAngleData[9] = crcValue >> 8;, ]/ o ^" _3 Z8 [" ~( V; J% I //发送至上位机+ \- v, y" e: a- o; l! |+ |$ m HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));1 t; }( U+ M E+ S( T" D- W( c P, h } /* USER CODE END 0 */; W. ?8 e* }! d4 P. |% R$ v5 Q3 _4 i w0 k: _# U+ A4 r2 e: J' l2 ^+ I /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); 0 X3 ~" n/ x5 ]( z 硬件连接图: 波形图:1 J# R* w$ a) Q/ S 最后加一个视频: STM32L053 演示" t8 }/ r2 W6 P8 N7 o5 S |
意法半导体最具性价比、速度最快的单核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"
$ A8 T5 ~3 k2 ^1 S v
#include "gpio.h"
2 f% U* C. v+ F* n! ]- _/ ]- ?
/* USER CODE BEGIN 0 */
- H" T$ t8 h% S! D5 L! u2 ]
/* USER CODE END 0 */+ z/ T# z1 x+ R7 {, M% J
/ V2 n4 h1 f3 ^) n$ h; a
I2C_HandleTypeDef hi2cx;( L( a b9 w( X$ t7 N* ]
/* I2C1 init function */1 p2 M1 g. w: \) G- N
void MX_I2C1_Init(void)
{ l( Z Q; t# }6 L( G) t! ?, z, P
hi2cx.Instance = I2C1;4 S+ @! W" u: } \, ]7 w `+ B
hi2cx.Init.Timing = 0x20D22930;1 {$ e- k' r$ k$ R" h6 X
hi2cx.Init.OwnAddress1 = 0;! G, C8 i2 j* w' K
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;3 S% t7 Q# }0 y6 l. E
hi2cx.Init.OwnAddress2 = 0;
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;& j4 A d# k3 ` ~4 G
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;' ^+ l" \/ H! x
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);
/**Configure Analogue filter D/ b& G6 B* |9 r: `7 }4 S' S, q4 v
*/# k: x" ~2 l1 W; p, l( f" U
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);: E9 w' `6 ~& {& u4 J
}7 ^4 k. p; L6 X
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)0 O1 Q& {4 k! l* d$ @) T$ \
{
GPIO_InitTypeDef GPIO_InitStruct;! N* c: y1 H; J7 {% ~6 E7 {
if(hi2c->Instance==I2C1)3 E* o! |8 f& u$ b1 `6 c
{
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();
/**I2C1 GPIO Configuration ; v5 ]3 v. ]8 ?4 R6 W# |0 L
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/" _+ C& P. z4 z* x0 M
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;* z0 b8 Y3 e: _* b7 n3 E# l( j
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;# U5 _! X. h) x/ e
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}
]& v% q* i' {+ _0 p. y
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
/ ]9 u% Z2 u$ E% |) t
if(hi2c->Instance==I2C1)1 b6 `2 l* D, x9 @
{
/* Peripheral clock disable */
__I2C1_CLK_DISABLE();- q4 U# D5 p! |9 ]# o$ ?
" C H; i( K" e9 S- p9 R
/**I2C1 GPIO Configuration . }' U8 W5 e5 `" A) t" k
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);/ l3 q3 F7 Y. i( {% D
8 f/ W2 |; o4 C# A
}
}3 q: T$ b, K" \% f# I8 X
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
usart.c8 V; M5 v5 Q1 e! T9 L x# x' |
#include "usart.h"
#include "gpio.h"
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */- Y' r) y- a( A9 I/ T* }
3 ]3 j3 Y# Y/ O
UART_HandleTypeDef huart2;* r) ~* i! o7 E3 ?, T" G
DMA_HandleTypeDef hdma_usart2_rx;8 _( _* I, M1 ?# R
DMA_HandleTypeDef hdma_usart2_tx;5 P- m. B. d* K4 s
6 a3 N: f. o3 P& T( {
/* USART2 init function */
. H/ k% p" D( B" B. D% r1 n- |! c
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;) ~" p) u8 P0 ?, ^, g: p
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;5 z6 m0 `% I1 W2 x. l4 }
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;% ~& O$ h9 P B3 {3 f' z
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;/ a! L& @$ G; x3 Y) B
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart2);
" {: ~* a+ v) H$ \. F
}7 y; v# s0 e4 A! h$ W; p
, F8 A: z. A# N: T/ O4 c
void HAL_UART_MspInit(UART_HandleTypeDef* huart)( g% Z m- _* J8 Y+ q
{! T" p! @' x- X( R" ?
6 F: P' F- J- n6 }
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{. J) d2 U5 _* X. _1 X. D
/* Peripheral clock enable */* L; O0 n" F! h4 S. @$ Q
__USART2_CLK_ENABLE();+ L0 L3 N# { c( ]* ~) `4 t
3 R) A, Q% `' O: M4 M
/**USART2 GPIO Configuration " A' @; P" N# ]9 G0 P
PA2 ------> USART2_TX% }( Y1 `$ X% {7 H) p4 r4 k
PA3 ------> USART2_RX8 {# X# ~8 ?5 z+ N0 m* D) q
*/3 x9 d& ?+ _7 v4 b, N
GPIO_InitStruct.Pin = GPIO_PIN_2;( z" }1 h* ~; M4 c6 n
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;+ Z- y2 {5 Z0 U( D% t
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;( V. U: _! _) t5 M& u
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);) n) e# q5 D# V7 X
/* Peripheral DMA init*/
hdma_usart2_rx.Instance = DMA1_Channel5;
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;4 Y4 ~# G; |1 h0 q U, q
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;8 ^- c0 {6 N% ^% P# U: D7 v0 ^. n; X
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;+ _9 @7 }1 n) v h# B- ]' b
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;$ F: N, e" S! r& V" ]( k5 t
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
2 Y) i1 f& \/ y. C
hdma_usart2_tx.Instance = DMA1_Channel4;
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;1 n3 T F* U# S2 E+ A
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;6 s- w- m1 L. Z2 o; y2 X, R- k9 J
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;: o: u3 U1 p! ~6 d( W/ v
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);
; x6 o6 l9 t! q* B6 ^' u% a
}) h0 Z4 A& w9 V; i& D9 j
} H9 H. }/ Z9 m* @/ F
% e; s0 A( [% [7 i! k" L% a
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{- e/ T( L, N+ o: q
" @3 F+ A# r& n2 t
if(huart->Instance==USART2)
{
/* Peripheral clock disable */8 D0 h% N& F, M! Q
__USART2_CLK_DISABLE();1 w0 u9 [& k" S8 W
7 T8 W! ?& b1 y; o& Z, o4 x) k1 s. @
/**USART2 GPIO Configuration , g% J* q0 C! l/ D4 J' V
PA2 ------> USART2_TX1 X. X4 a/ i! g% ]1 P: v
PA3 ------> USART2_RX
*/; [) Z+ i- w" ^; j
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
) f( o/ w5 |+ k0 a/ `( Y0 L3 m3 p
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(huart->hdmarx);9 a% t9 Q: E- }/ P$ T$ Z' X
HAL_DMA_DeInit(huart->hdmatx);
}
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------* x: d* u! H x2 o* R/ D0 N
mpu6050.c7 _- w4 I8 a6 ~" T v( G
#include "stm32l0xx_hal.h". k) Q# p7 p& ]% G1 l
#include "MPU6050.h"
//各坐标轴上静止偏差(重力,角速度)6 ^: ]- o" u0 l3 Q
int16_t offsetAccelX = -195;$ k' T, |$ G- l7 i
int16_t offsetAccelY = 560;
int16_t offsetAccelZ = -169;
1 S; S; l% ]( b3 g- m7 p
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33; s& f" D4 l5 O# s: i
int16_t offsetGyroZ = 4;$ D* W; g3 |% w, V
extern I2C_HandleTypeDef hi2cx;
//**************************************5 E, Q2 h# e4 \- }
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{, F' I* x7 ~6 E6 D4 L7 C3 \! v
uint8_t rxData[2] = {REG_Address,REG_data};& I: c( E, W( a& `8 Q$ \$ X
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)' d# k0 G) h1 W
{- B7 N; a4 ]8 [1 c5 l1 l
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)2 N+ _) g+ l; t( u8 ~8 H
{}
}9 \& j+ e3 Z7 f1 V) j( M7 i- ^) e8 J
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************; I/ l# ^# X! N7 m
uint8_t Single_ReadI2C(uint8_t REG_Address)6 h0 Q: s& r3 E( f3 I
{# e+ x( D. A, `7 f% Q
uint8_t REG_data;+ E+ B+ Q* N7 h+ C
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
{% k6 n5 k, `* x' o! p3 i( N
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}+ f' w4 K' k* Z) E0 j
}
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)/ S: N) V+ ^6 Z0 Y# c* G! p
{}
}6 K: V: B: g% X0 t, x4 J ?) s6 A
return REG_data;9 _' D" V0 x p# c0 `/ N
}) J# c+ x+ L7 x0 X
//**************************************& @% u* ^1 b' K
//初始化MPU6050
//**************************************
void InitMPU6050()3 h- S9 b% m# f v! v
{" @; u/ u l7 Q" v5 r
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
6 U; g4 T; b: X* {6 U& s7 R) @
Single_WriteI2C(SMPLRT_DIV, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);0 B' h2 v' G8 J4 Q4 j, t. _
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}' A5 |/ m$ D8 B4 S4 j3 s
//**************************************$ z C C8 k) ?
//合成数据+ `3 ` D$ q0 K. a/ j* c. [; W
//**************************************# T @6 \+ U" W% A' U5 T# ?. J
int16_t GetMPUOutValue(uint8_t REG_Address)
{2 g) i2 m: y% |
int16_t result;6 W: O& V- E3 ?: D4 E
uint8_t H,L;2 c" i. M' \6 A" R7 Y
H=Single_ReadI2C(REG_Address);1 v# [ _2 m/ F A5 M9 @( W
L=Single_ReadI2C(REG_Address+1);) Z5 H2 V( v2 y" D
result = (H<<8)+L;
return result; //合成数据7 n& j1 i4 V3 u- q2 g" R& E
}
//************************************** e0 H, A% i- W2 w6 m
//取某一轴上的加速度数据2 S8 ~+ I- C y5 B
//**************************************
int16_t GetAccelValue(char axis)& T3 \$ o: C* A, G; i" T
{
int16_t result = 0;
switch(axis)
{& d$ ^6 E F9 @
case 'x':
case 'X':; I; w) O1 V" T3 J2 A9 {+ Q# c- d
{9 T" P j0 h& [% u0 B# F6 X
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;% z& u5 i3 {. J: H
}
break;3 T, t! ~# S7 f/ h, T& d" v6 w* L
case 'y':$ X' a5 V% H# P5 Z; G
case 'Y':# o5 _3 A8 W: e. u
{
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;. G, M0 X; }3 M+ o
}4 j8 k9 s% X! Z7 E
break;
case 'z':
case 'Z':
{
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;
}
break;
}
return result;/ Q! c; [( o" _( r! M. q0 a
}0 F9 O1 d i \
//**************************************3 h$ Q9 O7 \ I& P! w
//取某一轴上的角速度数据. H3 f; S! W1 H% ]# u$ ]
//**************************************
int16_t GetGyroValue(char axis)8 [6 |: I# c' G! \
{
int16_t result = 0;+ h5 s% e% R; X6 Y* g5 Z
switch(axis)
{
case 'x':& P6 i6 Y# z* R- P) p
case 'X':
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;" Z6 }5 u4 M! Y7 f
}
break; n* {, J1 c0 q q
case 'y':& ?, ^( c [, f _) M
case 'Y':
{; n& f5 [. K0 ]( J( d& W
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;
}
break;" g+ j6 p# e" D1 Z; ]9 ]
case 'z':
case 'Z':
{
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;+ x* x+ A2 F* W0 @& B9 R( R2 A: z
}/ g$ C" a- e$ e/ G
break;# \7 F" q7 m. |" W& H% z; _
}
return result;
}
评分
查看全部评分
{; l9 U5 A, B' R" x: w3 Y+ T h
% z) g& \* }" R, M* _; q
/* USER CODE BEGIN 1 */8 i+ \9 R! V4 p5 y/ ^: T
/* USER CODE END 1 */
, L: H5 W3 `# G. K0 P8 j- h! h
/* MCU Configuration----------------------------------------------------------*/" i1 ^+ E6 M1 F8 k, j1 L; f
4 m. S& p$ i* C( B
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */( c% R3 \1 S% ]1 G$ _
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
) |6 O/ F( K; o& i4 i6 ^
/* System interrupt init*/0 L8 C" E$ n- G4 P2 G4 v% N
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */$ k5 U% s3 B/ S9 J
MX_GPIO_Init();
MX_DMA_Init();# \8 I' w, \$ j* r
MX_I2C1_Init();
MX_TIM2_Init();
MX_USART2_UART_Init();1 A$ D2 U9 ?8 A6 x
InitMPU6050();% r: B( e4 B- L: y5 F# h
: y) p; C+ A0 s9 J
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);! N. w. y& L Z& h1 k& j- M
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */9 t6 U* F/ G1 @! g" o2 ^6 ~
/* USER CODE BEGIN 3 */
/* Infinite loop *// ]) m% g5 d0 a9 P0 P1 G
while (1) _0 ^- e9 G, f$ w
{ R, @. ?8 e: o' Y7 _0 u
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);' W1 _! R8 |2 b# N" `: _
VisualScopeAngleOutput();# |1 `7 d2 U0 c% ]7 ^1 ^) T. r
HAL_Delay(100);
}
/* USER CODE END 3 */
; X- {% o! a* S0 y. `6 }
}" S' o* m8 f$ c9 E* l
/** System Clock Configuration1 x" o; A/ i7 {9 n9 `
*// Z, N( x/ C6 Q% D, k, z& Q$ _4 S
void SystemClock_Config(void)
{
" @ K. C: x$ I9 x; t2 J
RCC_ClkInitTypeDef RCC_ClkInitStruct;! T: i* a( c9 y: V
RCC_PeriphCLKInitTypeDef PeriphClkInit;2 j5 R Z* e# B: t" H/ M V
RCC_OscInitTypeDef RCC_OscInitStruct;$ f" G; W! X1 M" R7 l
__PWR_CLK_ENABLE();, @ w* C. {0 }2 E: n& G" N5 i% c
4 J9 Q5 k5 A0 b# k, p; x$ W0 `
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;! B- [/ j4 X0 z: g ^& t; Y$ |
RCC_OscInitStruct.HSICalibrationValue = 16;5 Z( Y& v9 J9 T9 h9 T
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;' Q* X+ X5 g3 R0 I* Y: H
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;. t, \6 J0 h0 t1 I9 r6 U! Y
HAL_RCC_OscConfig(&RCC_OscInitStruct);& n% t6 M+ U2 u' h3 t" ?
; w! u$ t5 }& G
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;+ b. @# S% v( {% R( R2 }8 @- K
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;: X8 L" v9 G! v: b7 ?
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;: c' \7 \ C; X) t1 ?6 S
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);" F( E6 S6 V) D K0 ]
5 r* p- ?1 J* ]4 A+ t4 k7 V
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);- @& x9 @* `9 [- R- V7 e- ?" |
__SYSCFG_CLK_ENABLE();
1 ^' w5 G! ~: ~$ a
}
/* USER CODE BEGIN 4 */$ b" p4 r. o5 B, A! I; `' U
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)& A2 ?8 B9 M( [ C. u i
{
if(huart->Instance == USART2)
{9 O0 C! v/ Y) k, A
memcpy(txBuffer,rxBuffer,RXSIZE);- B0 s9 y! v# q8 X0 v
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
8 M: t5 c; ?0 ]! _( x$ m
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{4 ? \4 n. i# U; Z" v
int32_t GyroValue;
% g! G3 K4 t# u; f
Calc_AngleAccel();
GyroValue = Calc_AngleGyro();( H& U5 d5 S2 F
ComplementFilter(GyroValue);
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。