拿到开发板有一段时间,看了下资料,使用mbed平台那简直是太简单了,但mbed封装的太严实,实在是不利于我们了解MCU内部运作机理,所以还是要使用ST的库(直接寄存器操作就免了,我不想回到石器时代),现在ST库除了F1系列已经改变,采用新的HAL Drivers的方式,这种方式更友好,更符合软件工程。使用STM32CubeMX把和MCU相关的代码已经生成的90%了,剩下和10%需要自己来完成,所有的中断基本上采用“伪回调”的方式,使用用户更专注于业务算法本身。废话不多说了,直接上代码: -------------------------------------------------------------------------------传说中的分界线---------------------------------------------------------------------------- main.c+ v P/ y# j9 d) D #include "stm32l0xx_hal.h" #include "dma.h" #include "i2c.h" #include "tim.h" #include "usart.h"4 \8 D2 U3 g3 f9 u0 J #include "gpio.h": a: Q9 Q# l/ C. o/ S( s1 z8 { #include "mpu6050.h" #include "visualscope.h"# h* x6 L3 w/ L, D3 ]8 } #include <string.h> #include <math.h> /* Private variables ---------------------------------------------------------*/ #define RXSIZE 8 #define TXSIZE 8: _! Z, ?6 o( s7 Q) e uint8_t rxBuffer[RXSIZE];$ b2 v: e# w) B# z uint8_t txBuffer[TXSIZE]; 9 O' g' `. h2 ~) I7 p float Angle_accel = 0; float Angle_gyro = 0; float Angle_comp = 0; uint8_t outAngleData[10];$ B+ r; {( x- G% f5 E3 m/ B/ w$ ~ /* USER CODE BEGIN 0 */ ! m/ u" i3 n e' c' S /*---------------------------------------------------------------------------------------------------------*/9 B3 E9 n: K' w; X /* 重力加速度算出的角度 */0 V+ i" S% n0 p$ d) b. q /*---------------------------------------------------------------------------------------------------------*/' y9 t2 P+ T" g& O4 G" M/ g int32_t Calc_AngleAccel() {1 Y8 I- K+ e9 a; h int32_t value = 0;8 y/ a* L5 {+ t! G' b$ J" d" o# w value = GetAccelValue('x');1 m. A: P" }/ r4 d# \+ C7 ^# m* O if(value > 16384)6 N% X5 i4 m% s/ W9 j* E# H Angle_accel = -(asin(1) * 180 / 3.1415296); else& G6 k A4 ]' |2 N Angle_accel = -(asin(value * 1.0 / 16384) * 180 / 3.1415296); return value; }" l# r% F) O4 Q /*---------------------------------------------------------------------------------------------------------*/ /* 角速度算出来的角度(积分) */" `' Q# ]+ H3 E9 S /*---------------------------------------------------------------------------------------------------------*/ int32_t Calc_AngleGyro()4 Y8 [, w" ?6 @* {0 Z. A% R { int32_t value = 0;/ D) G ]) r7 C: ^9 x- K2 Y , S% _; ?+ h4 G; {0 r' f# m value = GetGyroValue('y');: T# c2 Z1 n2 ~7 _3 u$ |* i Angle_gyro += (value / 16.384 * 0.01); return value;, K3 g; o+ _( V/ P( c- a }( s" W" `; U4 Y' }" G& y0 Z2 x /*---------------------------------------------------------------------------------------------------------*/ s9 a& q1 s8 V /* 互补滤波求角度 */8 M' j) ^2 [3 T% A3 w /*---------------------------------------------------------------------------------------------------------*/2 T6 z- @) G0 {$ l/ ? Y5 w float ComplementFilter(int32_t simpleGyro) {% @' U, `* s; g9 L# h2 V' K Angle_comp = 0.98 * (Angle_comp + -simpleGyro / 16.384 * 0.01) + 0.02 * Angle_accel;+ ?. {4 ]5 t& |7 j 3 V. h: [7 m9 v+ b return Angle_comp;9 A4 f% J3 k% {, j0 Y0 D }- z( A: ^' U! j% m m( M' ^ /*---------------------------------------------------------------------------------------------------------*/ /* 输出角度至上位机 */; N0 z3 u8 v: t1 K /*---------------------------------------------------------------------------------------------------------*/& Z+ e7 T% W( R, g- O void VisualScopeAngleOutput() {$ R2 v( S9 ~# H" u# ~ int AngleValue_Accel,AngleValue_Gyro,AngleValue_Comp;: S$ j$ S! C E! y' R% B- S uint16_t crcValue;; `8 @8 B$ u' n , d& X( n7 o6 d, D: ] AngleValue_Accel = ceil(Angle_accel * 10 -0.5); AngleValue_Gyro = ceil(Angle_gyro * 10 - 0.5);1 U. u! ]" |6 Y1 g* G AngleValue_Comp = ceil(Angle_comp * 10 - 0.5); outAngleData[0] = AngleValue_Accel & 0xFF;$ v( R' ^2 n' Q, }6 l outAngleData[1] = AngleValue_Accel >> 8;: }: X6 B; N6 J D2 b4 ^ outAngleData[2] = AngleValue_Gyro & 0xFF; outAngleData[3] = AngleValue_Gyro >> 8;0 F9 _; Q, t5 N* m7 T outAngleData[4] = AngleValue_Comp & 0xFF; outAngleData[5] = AngleValue_Comp >> 8; //计算CRC$ u/ W* l, W- O, \" Q crcValue = CRC_CHECK(outAngleData,8);+ i' q/ ]+ n' f( S8 e: h outAngleData[8] = crcValue & 0xFF; outAngleData[9] = crcValue >> 8;- V0 V W3 t7 J( M: g //发送至上位机# O* W& s+ L) b: N HAL_UART_Transmit_DMA(&huart2,outAngleData,sizeof(outAngleData));5 e8 e1 v! e3 d: P4 D }( U! t6 f8 e- a- j; L /* USER CODE END 0 */ /* Private function prototypes -----------------------------------------------*/9 e$ o+ f/ g2 n/ R7 G9 f' A7 \ void SystemClock_Config(void);' U a7 F/ E) C+ k ( v0 @6 U* g4 J& ^. Y5 [ * d" Y' @' [6 G% F" k 硬件连接图: 波形图:: O8 i7 X) ? h9 u+ a! g 最后加一个视频: STM32L053 演示 |
聊聊 STM32 MPU OpenSTLinux 实时扩展包 X-LINUX-RT
意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS
【STM32MP135-DK】裸机移植shell
【STM32MP13DK】 在Linux主机上交叉编译一个Hello Word应用
STM32MP135F-DK 开箱&开发环境搭建&硬件设计分析
意法半导体在意大利建SiC整合制造厂
轻松地实现ClassB在STM32CubeIDE上的移植
ST历史小知识(6)- 与世界共同塑造美好明天
ST历史小知识(5)- SiC衬底进一步发展
ST历史小知识(4)- 投资未来
#include "i2c.h"2 z9 E& R8 e& u' `, h
. r p \( B+ f- E
#include "gpio.h"
/* USER CODE BEGIN 0 */! \- {3 F, D9 G8 i
/* USER CODE END 0 */
1 ?# h4 V3 L! M$ A5 C+ `
I2C_HandleTypeDef hi2cx;
# y" M! C0 o# Q/ L* ~
/* I2C1 init function *// j2 z( |" X3 A; O+ ~% {
void MX_I2C1_Init(void)
{
8 l( S! @) {2 M6 `
hi2cx.Instance = I2C1;' d) R( _. X6 v
hi2cx.Init.Timing = 0x20D22930;
hi2cx.Init.OwnAddress1 = 0;
hi2cx.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2cx.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
hi2cx.Init.OwnAddress2 = 0;; v6 C! M4 t- V' _ _! c
hi2cx.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2cx.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;. L% o [; L, f/ f3 d1 \
hi2cx.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&hi2cx);
0 {9 R# C7 a; v) G1 y- G2 F
/**Configure Analogue filter
*/
HAL_I2CEx_AnalogFilter_Config(&hi2cx, I2C_ANALOGFILTER_ENABLED);
" [& [' U9 |; m2 R; I( K+ X4 u
}
3 V; Y+ i) ?" s$ P
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)- |2 X! G7 L5 ^# `
{8 p2 u* b0 M; H% k( P8 z* l
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{ e5 |( A0 @' ^: B9 e8 Y
/* Peripheral clock enable */1 ~! E+ ~! J6 P& n
__I2C1_CLK_ENABLE();$ B+ S" t0 @/ c# X
/**I2C1 GPIO Configuration / U2 I- T8 v$ K: g9 u; W5 y
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;3 f: s$ {, x5 w# Z* \0 |
GPIO_InitStruct.Pull = GPIO_NOPULL;( Y1 h; x# m; n; _* m
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;8 d( y' O/ x8 [& w
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);) |8 X( x5 [6 b6 a
}
}( d* N% V* I$ I; ^( M6 }7 b* M+ ^
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)8 H) D. _8 d6 a4 [
{
if(hi2c->Instance==I2C1)2 `, m2 c4 ?* ?) r% G) l
{) }- u9 J2 z0 S) y; Q) Q' \7 s
/* Peripheral clock disable */. G# T, @: y/ c6 N1 M* d% Z$ I; S
__I2C1_CLK_DISABLE();
) j/ Z+ a6 G8 Z, E
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL( E! C, w2 P m3 ^
PB7 ------> I2C1_SDA/ {8 b% k" F3 G$ P
*/: Z0 K' W. k# H0 F" [, P! y
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
* D/ b- `* @) o) ?
}3 O; V& E3 E! R: j, I5 o
}& o* Y3 k8 F* k, A
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------/ w3 B, Q4 Z( P" B
usart.c9 g* `5 d6 _+ k) Y9 Z- p
#include "usart.h"8 i# w3 v4 X* f5 b M0 v
+ M) v o+ q2 s/ V4 }% _, r4 X
#include "gpio.h"
#include "dma.h"
/* USER CODE BEGIN 0 */4 u; X' r0 `1 m5 ~
; z- j6 I2 u" W! }
/* USER CODE END 0 */( |+ L) z6 u% v
6 T( z. Y: h& k
UART_HandleTypeDef huart2;) e' l. T1 F- z
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
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;- ^. \0 t% V7 ~' N
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart2);# c( c- m7 Z' Y
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)5 y$ v9 n: C& K; P. Q% p: Q
{7 v, E0 ^1 T! q" W8 C
8 C" t4 Z; z& O
GPIO_InitTypeDef GPIO_InitStruct;/ H4 A5 R6 {8 e- G# |
if(huart->Instance==USART2)
{
/* Peripheral clock enable */8 }+ x) B M' u
__USART2_CLK_ENABLE();
/**USART2 GPIO Configuration * Z# I5 S4 D2 t1 J$ W
PA2 ------> USART2_TX- g4 f" I" K/ r
PA3 ------> USART2_RX# W; d. d9 x5 \- {+ w
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;% R0 N* w- ~# v& d
GPIO_InitStruct.Pull = GPIO_NOPULL;- ~# g2 O3 ?+ r$ o7 ^- v. ?4 n
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;# t. Q8 T' P3 W. A
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;1 f7 N d( e( H5 n
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);% o, a; [+ c& Q$ S( z2 k( G
: S! {, d4 } W3 f) k7 N/ o
GPIO_InitStruct.Pin = GPIO_PIN_3;' P0 q! U8 G8 I- B/ e' a3 C
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; H. [' j$ N# P( f8 C
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;/ _4 P, U8 M* q3 d7 K) c7 N& {1 i
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;% I( l6 M7 Q8 J* a7 P
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
" Q5 z% t B% C; X. U" |
hdma_usart2_rx.Instance = DMA1_Channel5;+ i. |: G+ `. d
hdma_usart2_rx.Init.Request = DMA_REQUEST_4;" u5 Q7 p+ ]- ]( d! I7 k6 v# K
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;* U$ z2 }- D5 ?& ]$ c
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;3 z& d. U4 U/ @# x7 C: |$ A2 d
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;- F$ x1 b* O* q0 O
hdma_usart2_rx.Init.Mode = DMA_NORMAL;: o8 \0 Z% B4 m$ }. k
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;# h- t3 n5 X* ~ Y
HAL_DMA_Init(&hdma_usart2_rx);$ R8 t; W$ P: W
: v$ b& @& s6 O3 ?$ n$ X) e3 Z
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);7 T9 M5 H, P" b1 q4 t- C4 X
hdma_usart2_tx.Instance = DMA1_Channel4;- Y) w6 I* p3 i8 Y8 A2 z* h/ c5 p
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;9 X3 |3 g' r1 m5 p, y: N
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;9 V: k7 H) D" ?' Y
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;0 Y4 C- i* r+ q1 u* X! p( s/ y9 B
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;1 O4 u% L9 m( F& p0 b0 L9 H
hdma_usart2_tx.Init.Mode = DMA_NORMAL;3 i$ T# W$ B5 i1 N" I
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;+ D, _7 x1 _- z; O. F% d6 e, e$ V
HAL_DMA_Init(&hdma_usart2_tx);2 ^ |: q) g3 ^! |6 R
4 D, D# {. |. S7 i" l0 v
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx); ^' X% m8 K: d2 k6 Q- t7 h
}. \) T8 X0 V2 ^
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart): I* ~; q- _( G- s
{5 \) W( O. n5 t# L
" k3 \$ i1 v. q. v4 |
if(huart->Instance==USART2)! s- Y0 F W) f* @
{/ C' v* B3 X7 n+ T8 Y
/* Peripheral clock disable */9 d* K9 E/ T* Y5 B6 W
__USART2_CLK_DISABLE();7 R' Z8 n: m3 x) D9 b% U t7 \
5 B( @) z" B1 }3 t& E9 t
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX( [7 d$ p5 H1 Y3 \8 I# ?
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);5 w3 ]4 h2 k9 u6 b7 i% t5 ^
. h- V* U" b/ l4 \
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(huart->hdmarx);
HAL_DMA_DeInit(huart->hdmatx);
}! Y: p; G' K6 F! z/ G0 t
}
------------------------------------------------------------------------------- 传说中的分界线 ----------------------------------------------------------------------------
mpu6050.c: h+ b$ T0 A. t
#include "stm32l0xx_hal.h": A7 B4 Q0 Y! C2 v; {2 W. V8 Y) X
#include "MPU6050.h"- \8 ~5 N; ~" d) T$ F
//各坐标轴上静止偏差(重力,角速度). ?' z/ ]' q; `+ G. [
int16_t offsetAccelX = -195;/ a# U5 C- L5 \2 V4 q
int16_t offsetAccelY = 560;
int16_t offsetAccelZ = -169;
int16_t offsetGyroX = 12;
int16_t offsetGyroY = 33;
int16_t offsetGyroZ = 4;
/ f: D5 L1 N# Q! ~0 n
extern I2C_HandleTypeDef hi2cx;' n; |/ F6 l4 R9 U
//**************************************/ f9 O0 n9 W0 i6 Z+ N
//向I2C设备写入一个字节数据* ~$ t. H4 U8 R& r8 O
//**************************************: L7 k0 |' P9 O4 N: s" h
void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)6 \, f% c) {5 l6 l9 f! C
{7 s- I( _$ S) }& _- T4 D
uint8_t rxData[2] = {REG_Address,REG_data};
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,rxData,2,5000) != HAL_OK)" q8 |: I1 T7 [3 y! }( P4 r
{
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}
}9 R9 v/ F! q" r9 v* @
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uint8_t Single_ReadI2C(uint8_t REG_Address)5 i+ S+ v" q* U& m9 i
{, w# x& ^/ x t8 S$ s
uint8_t REG_data;
while(HAL_I2C_Master_Transmit(&hi2cx,SlaveAddress,®_Address,1,5000) != HAL_OK)
{% H, J+ p8 B. M: l# ^$ {0 }
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF). M* X6 V* S3 H0 E; Y
{}9 |! r& G% j: W
}
if(HAL_I2C_Master_Receive(&hi2cx,SlaveAddress+1,®_data,1,5000) != HAL_OK)
{% ?0 A: l% M; F9 H. G
if(HAL_I2C_GetError(&hi2cx) != HAL_I2C_ERROR_AF)
{}
}
return REG_data;
}6 p" I9 ~" r9 A! m
//**************************************
//初始化MPU60504 b: F0 C2 J6 [1 k
//**************************************
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
7 p4 q7 E) j% x3 H: v4 W
Single_WriteI2C(SMPLRT_DIV, 0x07);* f9 _' R$ Z+ V+ @: F) q
Single_WriteI2C(CONFIG, 0x06);
6 J l' | {: m; d9 t, T5 }4 M+ ^
Single_WriteI2C(GYRO_CONFIG, 0x18);
) `3 g% t7 { R( q: y4 l
Single_WriteI2C(ACCEL_CONFIG, 0x01);: p4 F' `' F* g) R8 f
}6 k$ J: L6 I D
//**************************************
//合成数据
//**************************************
int16_t GetMPUOutValue(uint8_t REG_Address)
{) y. w* w1 P* Y j# C+ f
int16_t result;
uint8_t H,L;, c& R6 d0 N: }) ]& g2 l* E3 r
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
result = (H<<8)+L;: j4 [* Z* h) M* m4 T. d, d
return result; //合成数据
}
% C- a7 c# m4 J7 p$ ~9 o
//**************************************8 `' T. B* \6 u
//取某一轴上的加速度数据; t; {/ H3 ~0 i& v* c
//**************************************
int16_t GetAccelValue(char axis)
{
int16_t result = 0;
switch(axis) q) Z! b% k; [2 V+ s0 O0 j
{# Y0 B2 ]: }' y# X4 K' G& p& K
case 'x':, T, m. a5 @% c' R4 P
case 'X':
{# w4 t6 Q: m9 k3 Z. e8 \
result = GetMPUOutValue(ACCEL_XOUT_H) - offsetAccelX;2 Z2 E+ @% Q' c- n+ c6 v" y3 [
}+ ?/ M' A6 _4 b9 }
break;
case 'y':7 j4 n7 w7 \' u, `
case 'Y':( o5 h1 Y' n" E ^6 B
{( Y! ?# i# R. n; i0 W3 B3 u
result = GetMPUOutValue(ACCEL_YOUT_H) - offsetAccelY;
} R- J8 Y! T/ Y7 |1 t
break;
case 'z':
case 'Z':
{% o; {1 B7 W2 S' \7 }& ?
result = GetMPUOutValue(ACCEL_ZOUT_H) - offsetAccelZ;$ P% d1 U2 {' b9 {+ i9 P
}- V$ R8 x. h6 j* t( M
break;
}
return result;. v7 g* P+ r5 m
}
3 i/ c% t0 l6 H' h6 L; x; g- x( L
//**************************************7 z. B; ~1 @* I. ], Q* W; h9 x5 |* o8 Q
//取某一轴上的角速度数据
//**************************************% w! r) u6 l* l9 A4 y
int16_t GetGyroValue(char axis)
{
int16_t result = 0;. K0 s& _0 {+ A
switch(axis)
{1 a! X- L/ b* e# ^- ]) C
case 'x':1 Y& g# r. E5 O( B7 {3 H2 R
case 'X':
{
result = GetMPUOutValue(GYRO_XOUT_H) - offsetGyroX;
}
break;/ @! ^/ m7 i9 b, M/ J
case 'y':
case 'Y':
{
result = GetMPUOutValue(GYRO_YOUT_H) - offsetGyroY;9 ~+ i% k4 ?/ o1 L6 b
}6 M" y( X$ I! A, F" r4 O
break;, O5 |) Q+ l% d
case 'z':' _$ E U. j; y
case 'Z':
{* |5 w, B8 W6 p8 t9 c2 _+ X/ y
result = GetMPUOutValue(GYRO_ZOUT_H) - offsetGyroZ;
}! @# F D: f @; ?" B
break;
}7 W$ d1 G/ X/ H( u
return result;, c2 v2 s& R: V- S4 g
}
评分
查看全部评分
{% E9 S0 e0 b1 U( E- f
/* USER CODE BEGIN 1 *// k% q5 Y: D `9 o7 |
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
+ V1 c* {" ~. T# i D- \
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */8 u( b0 M0 B) G) \1 s2 K
SystemClock_Config();3 G, F) t+ d8 [4 o7 m
! H# Q' v8 i) t4 c" a
/* System interrupt init*/3 D f6 Y8 j, f$ I9 K4 {( o$ H
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);. y* ?, D- L3 I$ p
" n8 g9 t- d( D# u1 E# F
/* Initialize all configured peripherals */
MX_GPIO_Init();! H+ N* e/ K2 @: N; J- }* ?6 Q
MX_DMA_Init();
MX_I2C1_Init();% ^" ~, d( g# c: U; M. H8 T
MX_TIM2_Init(); K# T+ c! v- P5 d# h8 \6 l; V# }2 }
MX_USART2_UART_Init();1 j1 a# q, q7 f3 N8 W
InitMPU6050();. b, S0 b- e- i( o0 H" F2 ^1 {
/ W, Q, I$ i! ^' @ ^
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2,rxBuffer,RXSIZE);
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */; [4 z$ a7 K* D: n" S4 \
& I& G$ ~4 ]& ^
/* USER CODE BEGIN 3 */
/* Infinite loop */! y' ?- L3 U) n. H: d# t
while (1)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
VisualScopeAngleOutput();
HAL_Delay(100);1 Y$ @! |7 m) v6 o5 _: d
}6 H2 L8 o/ r0 ]' @5 f" J/ P
/* USER CODE END 3 */5 B: X/ F: O# S/ ]+ G! C% s
8 t2 A' V! O* i$ s$ L4 w. O
}: f% ~( c$ z C) H
/** System Clock Configuration4 E" S; Y1 _% g d$ k0 |
*/1 _ G) f: x! e; D2 O0 k
void SystemClock_Config(void)9 C0 B" @. ?6 j1 e
{0 H p, x9 `( [. G7 J
RCC_ClkInitTypeDef RCC_ClkInitStruct;0 g: K( m0 i% h/ a% z9 T
RCC_PeriphCLKInitTypeDef PeriphClkInit;( P! k0 h3 |- ?
RCC_OscInitTypeDef RCC_OscInitStruct;$ g; P8 \! t) ~ \; B2 G
Y2 [) t) `7 W. U6 ~
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);% @# }" ]9 G% m4 c4 |: {: m
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;0 Q7 l5 ]* ?/ X5 @8 j' e f% K
RCC_OscInitStruct.HSIState = RCC_HSI_ON;; c. ~! z3 o& b0 P: Q# F
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);) L7 B' ?3 O8 ?8 h! A
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;8 q3 Y4 `) U, o: k
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;4 H5 z5 B' C, r' t% H6 Y2 E; C% s# l
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;0 @* C/ Q9 N* C+ f( d
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;( \6 c7 Z, O! e; n7 p! V2 M
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);( ]+ N+ w2 W7 u) g9 e
8 G; z9 ]5 e; [0 S% M
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);" v: O3 Q* e' H+ i- A) m
$ d4 V- q. I9 X* G. M. {
__SYSCFG_CLK_ENABLE();; w+ v5 P% t2 g: }/ i+ `
}
/* USER CODE BEGIN 4 */) \: K2 A5 C3 L h' s8 J; S; l
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)& q+ z. _% U- x& ^) u
{# S% F$ F3 F% a- K) a5 g5 m& K
memcpy(txBuffer,rxBuffer,RXSIZE);
HAL_UART_Receive_DMA(huart,rxBuffer,RXSIZE);/ r& c2 q- P% j& M; a5 H2 ~+ A6 L$ q
HAL_UART_Transmit_DMA(huart,txBuffer,TXSIZE);0 U t7 z, q* l) k
}0 N6 ?" k( F# ^7 X6 ?
}1 L: T" p# _9 \1 f
7 ^3 I; T- q! B" U1 |+ H
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)( V0 r7 i( _6 x o$ }
{+ | r6 o7 i: S; H
' x; Q/ @. x" @/ D( a$ D. p+ ?$ H* E
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
int32_t GyroValue;
8 V: o0 y# r2 b
Calc_AngleAccel(); Z8 n: K* v( C3 K, E8 `3 H
GyroValue = Calc_AngleGyro();
ComplementFilter(GyroValue);) K$ }: l& S, T8 Z' F* i2 D# c/ i- Q
}
使用DMA方式,接收发送数据必须是个固定长度。
如果是长度不固定,你使用中断方式,然后加起止,停止标志位来判断。
好的,多谢指点!
请问应该注意什么地方
我使用是没有问题的呀。