基于STM32的智能车/平衡小车/蓝牙小车
硬件支持
- MPU6050
- OLED
- 蓝牙模块
- 直流电机
MPU6050程序
//******************************************************//
承接stm32单片机、STC系列单片机设计、嵌入式问题咨询
联系扣扣:
2424 6446 92
//******************************************************//
#include "MPU6050.h"
#include "USART.h"
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include "OLED.h"
void I2C_delay(void)
{u8 i=6; //?aà??éò?ó??ˉ?ù?è £??-2aê?×?μíμ?5?1?üD′è?while(i) { i--; }
}
void delay5ms(void)
{int i=5000; while(i) { i--; }
}
/*******************************************************************************
* Function Name : I2C_Start
* Description : Master Start Simulation IIC Communication
* Input : None
* Output : None
* Return : Wheather Start
****************************************************************************** */
Myflag I2C_Start(void)
{SDA_H;SCL_H;I2C_delay();if(!SDA_read)return FALSE; //SDA???aμíμ????ò×ü???|,í?3?SDA_L;I2C_delay();if(SDA_read) return FALSE; //SDA???a??μ????ò×ü??3?′í,í?3?SDA_L;I2C_delay();return TRUE;
}
/*******************************************************************************
* Function Name : I2C_Stop
* Description : Master Stop Simulation IIC Communication
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Stop(void)
{SCL_L;I2C_delay();SDA_L;I2C_delay();SCL_H;I2C_delay();SDA_H;I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_Ack
* Description : Master Send Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Ack(void)
{ SCL_L;I2C_delay();SDA_L;I2C_delay();SCL_H;I2C_delay();SCL_L;I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_NoAck
* Description : Master Send No Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_NoAck(void)
{ SCL_L;I2C_delay();SDA_H;I2C_delay();SCL_H;I2C_delay();SCL_L;I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_WaitAck
* Description : Master Reserive Slave Acknowledge Single
* Input : None
* Output : None
* Return : Wheather Reserive Slave Acknowledge Single
****************************************************************************** */
Myflag I2C_WaitAck(void) //·μ???a:=1óDACK,=0?TACK
{SCL_L;I2C_delay();SDA_H; I2C_delay();SCL_H;I2C_delay();if(SDA_read){SCL_L;I2C_delay();return FALSE;}SCL_L;I2C_delay();return TRUE;
}
/*******************************************************************************
* Function Name : I2C_SendByte
* Description : Master Send a Byte to Slave
* Input : Will Send Date
* Output : None
* Return : None
****************************************************************************** */
void I2C_SendByte(u8 SendByte) //êy?Y′ó????μ?μí??//
{u8 i=8;while(i--){SCL_L;I2C_delay();if(SendByte&0x80)SDA_H; else SDA_L; SendByte<<=1;I2C_delay();SCL_H;I2C_delay();}SCL_L;
}
/*******************************************************************************
* Function Name : I2C_RadeByte
* Description : Master Reserive a Byte From Slave
* Input : None
* Output : None
* Return : Date From Slave
****************************************************************************** */
unsigned char I2C_RadeByte(void) //êy?Y′ó????μ?μí??//
{ u8 i=8;u8 ReceiveByte=0;SDA_H; while(i--){ReceiveByte<<=1; SCL_L;I2C_delay();SCL_H;I2C_delay(); if(SDA_read){ReceiveByte|=0x01;}}SCL_L;return ReceiveByte;
} //μ¥×??úD′è?*******************************************
Myflag Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void
{if(!I2C_Start())return FALSE;I2C_SendByte(SlaveAddress); //·¢?íéè±?μ??·+D′D?o?//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//éè?????eê?μ??·+?÷?tμ??· if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}I2C_SendByte(REG_Address ); //éè??μí?eê?μ??· I2C_WaitAck(); I2C_SendByte(REG_data);I2C_WaitAck(); I2C_Stop(); delay5ms();return TRUE;
}//μ¥×??ú?áè?*****************************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ unsigned char REG_data; if(!I2C_Start())return FALSE;I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//éè?????eê?μ??·+?÷?tμ??· if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}I2C_SendByte((u8) REG_Address); //éè??μí?eê?μ??· I2C_WaitAck();I2C_Start();I2C_SendByte(SlaveAddress+1);I2C_WaitAck();REG_data= I2C_RadeByte();I2C_NoAck();I2C_Stop();//return TRUE;return REG_data;}void GPIO_6050_I2C_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
// GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOC, &GPIO_InitStructure);
}void MPU6050_Init(void)
{GPIO_6050_I2C_Config(); //3?ê??ˉ6050μ?I2C?úSingle_Write(MPU6050_Addr,PWR_MGMT_1, 0x00); //?a3yDY??×′ì?,1?±????è′??D?÷Single_Write(MPU6050_Addr,SMPLRT_DIV, 0x07); //1KHz/(6+1)7ms×a??ò?′?Single_Write(MPU6050_Addr,CONFIG, 0x06); //μíí¨??2¨?÷μ??μ£o0x01=188Hz 0x02=98Hz 0x03=42Hz 0x04=20Hz 0x05=10Hz 0x06=5HzSingle_Write(MPU6050_Addr,GYRO_CONFIG, 0x18); //íó?Yò?×??ì?°2aá?·??§£?μ?Dí?μ£o0x18(2?×??ì£?2000deg/s)Single_Write(MPU6050_Addr,ACCEL_CONFIG, 0x01); //?ó?ù??×??ì?¢2aá?·??§?°??í¨??2¨?μ?ê£?μ?Dí?μ£o0x01(2?×??ì£?2G£?5Hz)
}Data_6050_str Data_6050; //6050êy?Y?á11
float AccX,AccY,AccZ,GyroX,GyroY,GyroZ;;
uint8_t Temp1[20];
void READ_MPU6050(void)
{ unsigned char BUF[12]; //?óê?êy?Y?o′??? ///10/*???ù?è′??D?÷2aá?*/
// BUF[0]=Single_Read(MPU6050_Addr,GYRO_XOUT_L);
// BUF[1]=Single_Read(MPU6050_Addr,GYRO_XOUT_H);
// Data_6050.GX= (BUF[1]<<8)|BUF[0];
// Data_6050.Gryo_X = (float)Data_6050.GX /16.4; /*-----------------------------------------------------------*/BUF[2]=Single_Read(MPU6050_Addr,GYRO_YOUT_L);BUF[3]=Single_Read(MPU6050_Addr,GYRO_YOUT_H);Data_6050.GY= (BUF[3]<<8)|BUF[2];Data_6050.Gryo_Y = (float)Data_6050.GY /16.4;//?úá?3ì2000?è/S/*-----------------------------------------------------------*/
// BUF[4]=Single_Read(MPU6050_Addr,GYRO_ZOUT_L);
// BUF[5]=Single_Read(MPU6050_Addr,GYRO_ZOUT_H);
// Data_6050.GZ= (BUF[5]<<8)|BUF[4];
// Data_6050.Gryo_Z = (float)Data_6050.GZ /16.4;/*?ó?ù?è′??D?÷2aá?*/BUF[6]=Single_Read(MPU6050_Addr,ACCEL_XOUT_L); BUF[7]=Single_Read(MPU6050_Addr,ACCEL_XOUT_H);Data_6050.AX= (BUF[7]<<8)|BUF[6];Data_6050.Acc_X = (float)Data_6050.AX/16384; //Acc = AX * 9.8/0x4000;//Angle = asin(Acc/9.8)*57.32 ; ???è??×a??57.32 = 180/3.14/*-----------------------------------------------------------*/
// BUF[8]=Single_Read(MPU6050_Addr,ACCEL_YOUT_L);
// BUF[9]=Single_Read(MPU6050_Addr,ACCEL_YOUT_H);
// Data_6050.AY= (BUF[9]<<8)|BUF[8];
// Data_6050.Acc_Y = (float)Data_6050.AY/16384; //Acc = AY * 9.8/0x4000;//Angle = asin(Acc/9.8)*57.32 ; ???è??×a??57.32 = 180/3.14/*-----------------------------------------------------------*/BUF[10]=Single_Read(MPU6050_Addr,ACCEL_ZOUT_L); BUF[11]=Single_Read(MPU6050_Addr,ACCEL_ZOUT_H);Data_6050.AZ= (BUF[11]<<8)|BUF[10];Data_6050.Acc_Z = (float)Data_6050.AZ/16384; //Acc = AZ * 9.8/0x4000;// GyroX = Data_6050.Gryo_X;
// sprintf(Temp1,"GyroX: %4.2f \r\n", GyroX);
// USART_printf(USART1,Temp1);GyroY = Data_6050.Gryo_Y;if(GyroY>32768) GyroY-=65536; sprintf(Temp1,"GyroY: %4.2f \r\n", GyroY);USART_printf(USART1,Temp1);// GyroZ = Data_6050.Gryo_Z;
// sprintf(Temp1,"GyroZ: %4.2f \r\n", GyroZ);
// USART_printf(USART1,Temp1);AccX = Data_6050.Acc_X;if(AccX>32768) AccX-=65536; sprintf(Temp1,"AccX: %4.2f \r\n", AccX);USART_printf(USART1,Temp1);
//
// AccY = Data_6050.Acc_Y;
// sprintf(Temp1,"AccY: %4.2f \r\n", AccY);
// USART_printf(USART1,Temp1);AccZ = Data_6050.Acc_Z;if(AccZ>32768) AccZ-=65536; sprintf(Temp1,"AccZ: %4.2f \r\n", AccZ);USART_printf(USART1,Temp1);
// USART_printf(USART1,Temp); //Angle = asin(Acc/9.8)*57.32 ; ???è??×a??57.32 = 180/3.14
}
//
//float Pitch;
float pitch_temp1;float K1 =0.15;
float angle, angle_dot;
float Q_angle=0.003;// 过程噪声的协方差
float Q_gyro=0.0003;//0.003 过程噪声的协方差 过程噪声的协方差为一个一行两列矩阵
float R_angle=0.5;// 测量噪声的协方差 既测量偏差
float dt=0.005;//
char C_0 = 1;
float Q_bias, Angle_err;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] ={0,0,0,0};
float PP[2][2] = { { 1, 0 },{ 0, 1 } };/**************************************************************************
函数功能:一阶互补滤波
入口参数:加速度、角速度
返回 值:无
**************************************************************************/
void Yijielvbo(float angle_m, float gyro_m)
{angle = K1 * angle_m+ (1-K1) * (angle + gyro_m * 0.005);
}
void Angle_Calcu()
{int i = 0;static float pitch_sum = 0.0;for(i=0;i<3;i++){READ_MPU6050(); pitch_temp1 = (atan((float)AccX/AccZ)*57.2958); //??Pitch?? 0.4??????pitch_sum += pitch_temp1;}pitch_temp1 = pitch_sum / 3.0; //?????pitch_sum = 0.0;Yijielvbo(pitch_temp1,-GyroY);sprintf(Temp1,"%4.2f",angle);OLED_ShowString(5,2,Temp1,16);sprintf(Temp1,"%4.2f",Midle);OLED_ShowString(70,2,Temp1,16);
}
float kp=525,kd=32,Midle=4.55;
/**************************************************************************
函数功能:直立PD控制
入口参数:角度、角速度
返回 值:直立控制PWM
**************************************************************************/
int balance(float Angle,float Gyro)
{ float Bias; //525 32 535 38int balance;Bias=Angle-Midle; //===求出平衡的角度中值 和机械相关balance=kp*Bias+Gyro*kd; //===计算平衡控制的电机PWM PD控制 kp是P系数 kd是D系数 return balance;
}
基于STM32的智能车/平衡小车/蓝牙小车相关推荐
- 基于STM32的智能循迹避障小车实验(小车运动部分)
写在前面 这个实验是关于智能小车的实验,现在的想法就是先做出一个循迹和避障功能,后续可能会再添加一些其他的模块. 我在做这个实验之前基本了解了F1系列开发板的大部分模块,如果没有学习之前的模块,建议先 ...
- 基于STM32的智能循迹避障小车
[1]研究背景 随着计算机,微电子技术的快速发展,智能化技术的开发越来越快,智能程度也越来越高,应用的范围也得到了极大的扩展.因此,基于嵌入式技术的智能小车应运而生. 近来两年,智能小车在生活中有着广 ...
- 基于STM32的智能小车方案设计
基于STM32的智能小车设计 前言 一.什么是STM32智能小车? 二.模块汇总 1.主控板(STM32F103ZE) 2.底板 3.电机 4.避障模块(超声波传感器,红外传感器) 5.寻迹模块(3路 ...
- 基于STM32的智能小车(一)
## 基于STM32的智能小车 在假期自学了STM32,一直想做一个智能小车,刚好这次有时间就在家自己制作了这个基于STM32的智能小车,小车基本功能包括循迹.壁障及手机蓝牙控制,本人是第一次制作小车 ...
- 基于STM32的智能巡检小车系统设计--选材篇
基于STM32的智能巡检小车系统设计--选材篇 作者:车 邮箱:692604135@qq.com 学校:西安工程大学硕士研究生 方向:机器视觉.图像分割.深度学习 本人毕业设计题目是基于STM32的智 ...
- 基于数字电路交通灯信号灯控制系统设计-基于单片机病房温度监测与呼叫系统设计-基于STM32的无线蓝牙心电监护仪系统设计-基于STM32的智能蓝牙温控风扇控制设计-基于STM32的智能温室控制系统设计
1617基于数字电路交通灯信号灯控制系统设计(仿真电路,论文报告) 摘 要:交通灯控制系统在城市交通控制中发挥着重要的作用,本次课程设计就是以城市交通灯控制系统为背景的,主要通过运用学过的数字电路 ...
- 基于STM32的智能温室控制系统仿真电路设计(温控补光)-基于STM32的智能蓝牙温控风扇控制系统设计-基于STM32的无线蓝牙心电监护仪系统设计【毕设课设分享】
1609 基于STM32的智能蓝牙温控风扇控制系统设计-毕设课设 1.LCD1602液晶显示当前温度,温度上下限值,风扇等级,自动手动模式: 2.设置有4个按键,按键1可以设置自动和手动2种模式切换: ...
- 基于STM32的智能小车--舵机云台设计
基于STM32的智能小车 第一章 基于STM32的智能小车方案设计 第二章 基于STM32的智能小车–电机驱动设计 第三章 基于STM32的智能小车–循迹设计 第四章 基于STM32的智能小车–避障设 ...
- 基于STM32的智能小车--电机驱动设计
基于STM32的智能小车 第一章 基于STM32的智能小车方案设计 基于STM32的智能小车--电机驱动设计 基于STM32的智能小车 前言 一.电机是什么? 二.常见电机分类 1.有刷电机 2.无刷 ...
最新文章
- Android Studio 受不了了
- Gym 101741 K(AC自动机)
- ITK:运算后的当前图像
- ediplus 复制编辑一列_vi编辑器的使用详解
- c语言float判断相等,c/c++ 比较两个浮点数相等
- iText中输出 中文
- 初见mybatis-plus(快速创建入门案例)
- 全国多地元旦迎雾霾天气 京津冀霾明天短暂减弱
- 你知道硬齿面减速机价格为什么比齿轮减速机,蜗轮蜗杆减速机高?
- 威富通 php,关于威富通的微信扫码支付处理思路和流程
- java外链_如何做外链
- python中的pika模块
- Openstack Periodic Task
- 3 RRC 系统消息 SI
- xsim安装手记(转)
- quartz原理 java_Quartz原理解密
- Activiti6:模拟钉钉上面的请假流程(使用web画图并导出xml然后使用java执行流程)
- web缓存—Squid代理服务
- Lambda使用指北(上)
- mysql优化数据库对象