平衡小车之家--风力摆开箱实录(附资料)

平衡小车之家--风力摆开箱实录[附资料]

前言

你好学弟!这里是学长向你展现他们在2019年夏天花了大价钱购入一台平衡小车之家的风力摆,一直想照着搭一个,结果刚研究完就比赛了。
老师让咱们把这堆破烂留给大家(有些零件缺了大家要本身买 -_-),这边怕大家不懂,彻底自愿的给大家写了一篇教程,规避一些咱们走过的弯路,也但愿大家能把这份精神传承下去,替下下届的接班人们开山铺路。话很少说,先上个实物图。
在这里插入图片描述
还有一个电源:
在这里插入图片描述web

硬件部分

在这里插入图片描述
这根杆是很是软质的那种,颇有弹性,咱们以前买过一根碳纤维杆彻底不适合。
其次它全部重量全都集中在底部,惯性至关好。总共分三层,下面一一拆解开来看一下:app

  • 主控层:
    主控为一块F103,左边5个排母是OLED接口,若是插上的话能够看到输出的调试信息。右边有四根排针为SWD调试接口,能够用J-link调试器进行调试。下面是一个串口IO,能够经过串口查看信息。

在这里插入图片描述

  • 硬件层:
    这一层有一块MPU6050用于姿态测量,一块蓝牙模块用于使用配套的APP,还有从顶部接入的主电源。输出方面有四路电机插槽,不知道是怎么驱动空心杯电机的,由于并无看到任何驱动器件,还有一个激光头输出。
    在这里插入图片描述svg

  • 机械层:
    最底层是四路空心杯电机和一个激光头用于指示路径。
    在这里插入图片描述函数

代码部分

用Keil v5建的工程,用Keil v4要装一个Keil v5,并且Keil v4要卸载掉,否则会起冲突。
先看主函数部分:spa

int main(void)
  { 
	  MY_NVIC_PriorityGroupConfig(2); //=====设置中断分组
	  uart1_init(128000);             //=====串口1初始化
	  uart2_init(9600);               //=====串口2初始化 
	  delay_init();	    	          //=====延时函数初始化
// JTAG_Set(JTAG_SWD_DISABLE); //=====关闭JTAG接口
// JTAG_Set(SWD_ENABLE); //=====打开SWD接口
	  LED_Init();                     //=====初始化LED
	  KEY_Init();                     //=====按键初始化
      MiniBalance_PWM_Init(7199,0);   //=====初始化PWM10KHZ,用于驱动电机
	  OLED_Init();                    //=====OLED初始化 
	  delay_ms(1000);                 //=====延时
      
      IIC_Init();                     //=====IIC初始化
      MPU6050_initialize();           //=====MPU6050初始化 
  	  DMP_Init();                     //=====初始化DMP 
      Adc_Init();                     //=====adc初始化 
      MiniBalance_EXTI_Init();        //=====MPU6050 5ms定时中断初始化 200Hz定时
	  Laser=1;                        //=====开启激光灯 PA12
	  if(KEY==0)Flash_Read();         //=====开机长按用户按键读取flash参数运行
    while(1)
	   {
		   if(Debug_key==7&&Flag_Zero)  {Read_AngleZero(Flag_Zero,10);}//调试界面按键7(第三排第一个)零点读取
		   if(Debug_key==4&&Flag_Zero==0) {Flag_Zero=1,count_Zero=0,LED=0;}//调试界面按键4(第二排第一个)零点读取标志位,建议4,7重复两次
		   if(Flag_Show==0)           //默认开启APP和OLED显示屏,长安按键3S切换上位机
		   {
			   APP_Show();	          // APP显示数据
			   oled_show();           //===显示屏打开
		   }
		   else DataScope();          //开启上位机
           
		   if(Flash_Send==1)          //写入PID参数到Flash,由app控制该指令
		   {
			   Flash_WritePID();      //将PID参数写入Flash保存
			   Flash_Send=0; 
		   }
           delay_flag=1;	      
           delay_50=0;
           while(delay_flag);  //经过MPU6050的INT中断实现精准的50ms延时
	  } 
}

其余的就大体讲解一下各个文件的内容:
在这里插入图片描述.net

main.c:
包含所有变量的定义,初始化与主循环函数,全部文件经过调用sys.h来使用变量

sys.c:
包含全部系统相关初始化函数的定义,如时钟初始化,配置JTAG模式,配置外部中断等

usart.c:
包含uart1与uart2的初始化。uart2的中断处理函数,用于处理蓝牙传过来的数据。fputc函数的重定义,这里同时使用了串口12。

LED.c:
LED的初始化与闪烁函数

key.c:
按键的初始化与双击,单击,长按函数

oled.c:
oled的初始化与各类使用函数

adc.c:
ADC1的初始化与使用,用于获取电池电压

motor.c:
定义用于驱动四个电机的PWM,初始化TIM3的四个PWM输出脚

IOI2C.c:
用于定义一个模拟IIC协议,是给MPU6050使用的

exti.c:
将PB6定义为一个外部触发的中断,由MPU6050给出中断信号,获得一个精确的5ms时钟

stmflash.c:
对stm32的内部flash进行初始化与读写操做函数,主要用于存取预设的PID参数

control.c:
是整个工程的主要控制逻辑部分,包含
------------------------------------------------------------------------------------
int EXTI9_5_IRQHandler(void) //由MPU6050触发的5ms定时中断处理函数
//包括姿态更新Read_DMP(),控制模式更新Get_RC(),PID计算,按键扫描,电机的PWM赋值

int Position_PID_X (float value,float Target)	//PID的的计算,这里采用的就是传统的PID,
int Position_PID_Y (float value,float Target)
//关于PID的相关说明与各类PID,见https://blog.csdn.net/foxclever/article/category/9281151,这是一个系列,建议从第一篇到结尾都看一遍

void Get_RC(void)	//处理APP传入的控制模式信息
//根据uart2中断里置位的各类标志位进行一系列的switch-case操做
------------------------------------------------------------------------------------

inv_mpu.c:
inv_mpu_dmp_motion_driver.c:
MPU6050的dmp单元相关库,若是要使用MPU内置的dmp单元则须要包含

MPU6050.c
包含MPU6050的初始化与内部信息的读取函数

filter.c	(未使用)
定义了卡尔曼滤波与一阶滤波的相关函数

show.c
包含
void oled_show(void)用于在oled显示屏上显示数据。
void APP_Show(void)用于向串口2 APP发送数据。
void DataScope(void)用于向串口1 上位机发送数据

相关资料

店家给的资料其实还挺多的,然而你不买根本不会给你。
腾讯微云:https://share.weiyun.com/5kC2VAe 密码:bt5u5c
源码连接:https://download.csdn.net/download/qq_43243338/11939899调试