stm32c8t6上采集到Pitch, Roll, Yaw,esp8266通过串口1发送,不用HAL
时间: 2025-06-27 12:12:07 浏览: 13
### 实现思路
为了在 STM32F103C8T6 上实现不使用 HAL 库的情况下,通过 ESP8266 经由串口 1 发送 Pitch、Roll 和 Yaw 数据,需要完成以下几个核心功能:
1. **初始化 IIC 接口**:用于与 MPU6050 进行通信并读取其内部寄存器中的数据。
2. **配置 MPU6050 的 DMP 功能**:利用 DMP 提供的姿态解算能力,直接获取经过融合算法处理后的 Pitch、Roll 和 Yaw 值[^4]。
3. **初始化 UART 接口**:设置串口 1 来与 ESP8266 通信,并将姿态数据发送给它。
4. **编写主循环逻辑**:定期从 MPU6050 获取姿态数据并通过串口发送。
以下是具体的代码示例以及说明。
---
### 示例代码
#### 初始化 IIC 接口
```c
#include "stm32f1xx.h"
void I2C_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// 配置 SCL (PB6) 和 SDA (PB7) 为复用推挽模式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PB6(SCL), PB7(SDA)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; // 复用开漏模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置 I2C 参数
I2C_InitStruct.I2C_ClockSpeed = 100000; // 设置时钟频率为 100KHz
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // 标准模式
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 快速模式下的占空比
I2C_InitStruct.I2C_OwnAddress1 = 0x00; // 不使用自己的地址
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // 启用应答
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE); // 开启 I2C1
}
```
#### 初始化 UART 接口
```c
void USART1_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置 TX (PA9) 和 RX (PA10) 引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9(TX), PA10(RX)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 USART1 参数
USART_InitStruct.USART_BaudRate = 115200; // 波特率设为 115200
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE); // 开启 USART1
}
// 发送字符串函数
void USART_SendString(char *str) {
while (*str != '\0') {
USART_SendData(USART1, *(str++));
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
```
#### 配置 MPU6050 并启用 DMP
```c
#define MPU6050_ADDR 0xD0 // 默认设备地址
#define PWR_MGMT_1 0x6B // 寄存器地址
#define SMPLRT_DIV 0x19 // 采样速率分频寄存器
#define CONFIG 0x1A // 配置寄存器
#define GYRO_CONFIG 0x1B // 陀螺仪量程寄存器
#define ACCEL_CONFIG 0x1C // 加速度计量程寄存器
#define INT_ENABLE 0x38 // 中断使能寄存器
#define USER_CTRL 0x6A // 用户控制寄存器
#define FIFO_EN 0x23 // FIFO 能力寄存器
#define SIGNAL_PATH_RESET 0x68 // 信号路径重置寄存器
void MPU6050_Init(void) {
uint8_t data;
// 写入寄存器以唤醒 MPU6050
data = 0x00;
I2C_WriteReg(MPU6050_ADDR, PWR_MGMT_1, &data, 1);
// 设置采样率为 1kHz / (1 + SMPLRT_DIV)
data = 0x07;
I2C_WriteReg(MPU6050_ADDR, SMPLRT_DIV, &data, 1);
// 关闭低通滤波器
data = 0x00;
I2C_WriteReg(MPU6050_ADDR, CONFIG, &data, 1);
// 设置陀螺仪满量程范围 ±2000°/s
data = 0x18;
I2C_WriteReg(MPU6050_ADDR, GYRO_CONFIG, &data, 1);
// 设置加速度计满量程范围 ±16g
data = 0x18;
I2C_WriteReg(MPU6050_ADDR, ACCEL_CONFIG, &data, 1);
// 清除 FIFO 缓冲区
data = 0x00;
I2C_WriteReg(MPU6050_ADDR, USER_CTRL, &data, 1);
// 启用 DMP
data = 0x01;
I2C_WriteReg(MPU6050_ADDR, FIFO_EN, &data, 1);
}
```
#### 主程序逻辑
```c
int main(void) {
char buffer[100];
SystemInit(); // 初始化系统时钟
I2C_Init(); // 初始化 I2C
USART1_Init(); // 初始化 USART1
MPU6050_Init(); // 初始化 MPU6050
while (1) {
int16_t pitch, roll, yaw;
// 从 MPU6050 获取姿态数据(假设已封装好)
GetOrientation(&pitch, &roll, &yaw);
// 将数据转换为字符串格式
sprintf(buffer, "Pitch:%d Roll:%d Yaw:%d\r\n", pitch, roll, yaw);
// 通过串口发送数据
USART_SendString(buffer);
// 延迟一段时间再重复操作
Delay_ms(100);
}
}
```
---
###
阅读全文
相关推荐

















