加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

第17章-用6050走直线和转90度功能 平衡车入门-超详细陀螺仪MPU6050模块输出姿态角

06/24 09:53
3613
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
相关方案
  • 方案介绍
    • 第17章-用6050走直线和转90度功能
  • 相关文件
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱
第17章-用6050走直线和转90度功能 平衡车入门-MPU6050陀螺仪的使用 超详细陀螺仪MPU6050模块输出姿态角(有完整版源码)
这个是全网最详细的STM32项目教学视频。
第一篇在这里:
视频在这里:

STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随

第17章-用6050走直线和转90度功能

17.1-6050姿态数据读取

STM32读取6050数据

先把我们的参考历程里面的6050文件复制过去
在这里插入图片描述
添加文件
在这里插入图片描述
在这里插入图片描述
然后在魔术棒添加上面两个的路径,不再截图了。
简单阅读代码,知道 我们需要设置两个引脚,这两个引脚使用模拟IIC读取6050数据
1.在mpuiic.c延时使用自己写的、引脚需要使用两个先设置推挽输出、高电平
在这里插入图片描述

void mpuiic_Delayus(uint32_t usdelay)
{
  __IO uint32_t Delay = usdelay * (SystemCoreClock /8U/1000U/1000);//SystemCoreClock:系统频率
  do
  {
    __NOP();//使用空指令延时、移植不同单片机注意__NOP(); 执行时间
  }
  while (Delay --);
}
  //MPU IIC 延时函数
void MPU_IIC_Delay(void)
{
	mpuiic_Delayus(2);
}

//初始化IIC
void MPU_IIC_Init(void)
{					     
//  GPIO_InitTypeDef  GPIO_InitStructure;
//	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//先使能外设IO PORTB时钟 
//		
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;	 // 端口配置
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
//  GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIO 
//	
//  GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);						 //PB10,PB11 输出高	
 
}

使用软件初始化两个引脚

6050_SDA–PB9

6050_SCL–PB8
在这里插入图片描述
PB8-输出模式-起始输出高电平
在这里插入图片描述
PB9 输出模式 起始状态高电平
在这里插入图片描述
生成代码

打开我们的代码,是通过模拟IIC 读取6050数据的,我们知道SDA是模拟IIC的数据线 所以通信过程中是再输入和输出模式中切换的,但是我们的STM32CubeMX是设置的输出,是在哪里更改的模式那?

是通过寄存器设置的,在mpuiic.h可以看到

删除掉#include “sys.h”

把这个修改了
在这里插入图片描述
2.在mpuiic.h更改相内容

改成下面这样的
在这里插入图片描述

//IO方向设置 设置SDA-PB9为输入或者输出
#define MPU_SDA_IN()  {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=8<<4;}
#define MPU_SDA_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=3<<4;}
  1. 这是通过按位与后赋值 &=按位或后赋值 |=
  2. 设置端口配置高寄存器指定位。

先看一个例子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更改设置SDA与SCL电平的宏
在这里插入图片描述

//IO操作函数	 
#define MPU_IIC_SCL_Hige    	HAL_GPIO_WritePin(SCL_6050_GPIO_Port,SCL_6050_Pin,GPIO_PIN_SET)//设置SCL高电平
#define MPU_IIC_SCL_Low      	HAL_GPIO_WritePin(SCL_6050_GPIO_Port,SCL_6050_Pin,GPIO_PIN_RESET)//设置SCL低电平
#define MPU_IIC_SDA_Hige        HAL_GPIO_WritePin(SDA_6050_GPIO_Port,SDA_6050_Pin,GPIO_PIN_SET)   //设置SDA高电平
#define MPU_IIC_SDA_Low         HAL_GPIO_WritePin(SDA_6050_GPIO_Port,SDA_6050_Pin,GPIO_PIN_RESET) //设置SDA低电平
  	 
#define MPU_READ_SDA            HAL_GPIO_ReadPin(SDA_6050_GPIO_Port,SDA_6050_Pin)    //读SDA电平

更改一下 mupiic.c文件

//把之前的MPU_IIC_SDA=1;	 换成 MPU_IIC_SDA_Hige;
//MPU_IIC_SDA=0;	 换成 MPU_IIC_SDA_Low;
//MPU_IIC_SCL=1;  换成 MPU_IIC_SCL_Hige;
//MPU_IIC_SCL=0;  换成 MPU_IIC_SCL_Low;
//

编译一下、删掉没有用的文件

把u8 替换为uint8_t
在这里插入图片描述
t替换一下,u8 替换为uint8_t u32替换为uint32_t

可以一个文件一个文件的替换掉,如果整个工程替换其他HAL库文件内容也可能改变了
在这里插入图片描述
删除多余的库文件

注释掉
在这里插入图片描述
如果有其他的delay_ms 都替换为HAL_Delay

还有一个错误

		if((txd&0x80)>>7) MPU_IIC_SDA_Hige;
		else MPU_IIC_SDA_Low;

在这里插入图片描述
编译一下 、没有错误和警告

然后在main.c中定义变量和添加同文件

float pitch,roll,yaw; // 俯仰角 横滚角 航向角

#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h" 

在这里插入图片描述
替换inv_mpu.h的

#include "stm32f1xx_it.h"

在这里插入图片描述
初始化6050

  HAL_Delay(500);//延时0.5秒 6050上电稳定后初始化
  MPU_Init(); //初始化MPU6050
  while(MPU_Init()!=0);
  while(mpu_dmp_init()!=0);

在这里插入图片描述
我们通过下面的代码获得数据

   	sprintf((char *)Usart3String,"pitch:%.2f roll:%.2f yaw:%.2frn",pitch,roll,yaw);//显示6050数据
	HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),0xFFFF);//通过串口三输出字符 strlen:计算字符串大小	
   
   //mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出欧拉角
    while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //这个可以解决经常读不出数据的问题

在这里插入图片描述
然后我看一下 这个Usart3String 现在发送的大概多大的?
在这里插入图片描述

uint8_t OledString[50];
uint8_t Usart3String[50];

编译、烧录、然后就可以连接手机蓝牙,在蓝牙软件查看数据了
在这里插入图片描述

17.2-利用6050直线和90度(有代码)

为什么小车还是不能走直线

为什么两个电机转速一样不能走非常正直线,如何控制小车转弯90度。

当然,我们可以开环控制,但是控制效果可能不好,受外界影响比较大。

如果我们使用闭环控制,就要使用一个传感器来获得现在小车角度。
在这里插入图片描述
https://www.bilibili.com/video/BV1UV4y1p7Hd/?spm_id_from=333.337.search-card.all.click

走直线(控制朝一个方向运动)

在pid.c中定义一个姿态控制使用的PID
在这里插入图片描述

tPid pidMPU6050YawMovement;  //利用6050偏航角 进行姿态控制的PID

在这里插入图片描述

	pidMPU6050YawMovement.actual_val=0.0;
	pidMPU6050YawMovement.target_val=0.00;//设定姿态目标值
	pidMPU6050YawMovement.err=0.0;
	pidMPU6050YawMovement.err_last=0.0;
	pidMPU6050YawMovement.err_sum=0.0;
	pidMPU6050YawMovement.Kp=2;//定距离跟随的Kp大小通过估算PID输入输出数据,确定大概大小,然后在调试
	pidMPU6050YawMovement.Ki=0;
	pidMPU6050YawMovement.Kd=0;

仿照之前红外循迹代码编写姿态控制函数
在这里插入图片描述

float  g_fMPU6050YawMovePidOut = 0.00f; //姿态PID运算输出
float  g_fMPU6050YawMovePidOut1 = 0.00f; //第一个电机控制输出
float  g_fMPU6050YawMovePidOut2 = 0.00f; //第一个电机控制输出

走直线程序如下(因为上电初始化时候航向角是0、而且pidMPU6050YawMovementPID结构体的目标值target_val 也是0)
在这里插入图片描述


//*************MPU6050航向角 PID转向控制*****************//

   	sprintf((char *)Usart3String,"pitch:%.2f roll:%.2f yaw:%.2frn",pitch,roll,yaw);//显示6050数据 俯仰角 横滚角 航向角
	HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),0xFFFF);//通过串口三输出字符 strlen:计算字符串大小	
   
   //mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出欧拉角
    while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //这个可以解决经常读不出数据的问题
	
	
	g_fMPU6050YawMovePidOut = PID_realize(&pidMPU6050YawMovement,yaw);//PID计算输出目标速度 这个速度,会和基础速度加减

	g_fMPU6050YawMovePidOut1 = 1.5 + g_fMPU6050YawMovePidOut;//基础速度加减PID输出速度
	g_fMPU6050YawMovePidOut2 = 1.5 - g_fMPU6050YawMovePidOut;
	if(g_fMPU6050YawMovePidOut1 >3.5) g_fMPU6050YawMovePidOut1 =3.5;//进行限幅
	if(g_fMPU6050YawMovePidOut1 <0) g_fMPU6050YawMovePidOut1 =0;
	if(g_fMPU6050YawMovePidOut2 >3.5) g_fMPU6050YawMovePidOut2 =3.5;
	if(g_fMPU6050YawMovePidOut2 <0) g_fMPU6050YawMovePidOut2 =0;
	motorPidSetSpeed(g_fMPU6050YawMovePidOut1,g_fMPU6050YawMovePidOut2);

然后调节PID参数

顺序 先确定P 正负 然后P大小

然后D正负 然后D大小

最后调节的参数如下
在这里插入图片描述

	pidMPU6050YawMovement.Kp=0.02;//6050航向角PID运动控制 
	pidMPU6050YawMovement.Ki=0;
	pidMPU6050YawMovement.Kd=0.1;

然后我们把小车放在地上就可以完成一直朝着初始方向前进,如果往侧面推也会马上矫正。

转弯90度功能(控制转弯角度)

然后我们增加一下,如何旋转90度程序

在串口接收回调函数表姿态PID的目标值
在这里插入图片描述

extern tPid pidMPU6050YawMovement;  //利用6050偏航角 进行姿态控制的PID

在这里插入图片描述

		if(g_ucUsart3ReceiveData == 'H')//转向90度
		{				
			if(pidMPU6050YawMovement.target_val <= 180)pidMPU6050YawMovement.target_val += 90;//目标值
		}
		if(g_ucUsart3ReceiveData == 'I')//转回90度
		{				
			if(pidMPU6050YawMovement.target_val >= -180)pidMPU6050YawMovement.target_val -= 90;//目标值
        }	

然后我们的蓝牙APP增加两个发送按钮的设置
在这里插入图片描述
现象 是上电小车向初始方向直行,如果推小车车头方向,小车能够立马矫正。

然后连接蓝牙发送转90度 小车会转90度,按下 转回90度小车回转回。

这样我们就把6050转向程序写完了,下面开始 把上面代码如何结合一下,然后讲解如何增加视觉功能。

联系:Q,1930299709

  • 联系方式.txt

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
DS24B33S+ 1 Maxim Integrated Products EEPROM, 4KX1, Serial, CMOS, PDSO8, 0.208 INCH, ROHS COMPLIANT, SOP-8
$2.89 查看
PVG612SPBF 1 Infineon Technologies AG Transistor Output SSR, 1-Channel, 4000V Isolation, LEAD FREE, SURFACE MOUNT, DIP-6

ECAD模型

下载ECAD模型
$9 查看
SME2470-021 1 Honeywell Microelectronics & Precision Sensors Photo Transistor Detector, Surface Mount, 3.81 X 2.54 X 2.10 MM, CERAMIC PACKAGE-SME2470
$7.64 查看

相关推荐

电子产业图谱