stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号

(3) 2024-09-21 15:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号,希望能够帮助你!!!。

从零开始STM32平衡小车代码01

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第1张

教你从零开始STM32平衡小车代码

前言:

本人也是学生,只是分享一下自己的设计思路与代码教学。

STM32平衡小车是基STM32CubeMX软件生HAL库代码编写。

第一部分:前期准备

这部分主要是关于组装基本平衡小车需要的零件

1.小车车架以及电机固定轮子和联轴(我是通过淘宝上购买的)

2.带有编码器的直流电机

3.直流电机驱动电(也可以通过网上购买推荐大鱼电子的电机驱价格30+

4.STM32最小系统(本人芯片型号STM32F103ZET6

5.一个陀螺随意型可以买贵一点的这样数据不会很多毛刺,如果要节约成本就需要自己进行滤波优化了。(本人使用的是维特智jy61p

6.3S航模电池,想要小车跑起来电池是必不可少的

第二部分:新STM32CubeMX工程

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第2张主页面

进入页面后先选择一MUC:点 ACCESS TO MCU

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第3张

在此搜索你们使用的芯片型号即可

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第4张

进去后先点SYSDebug模式,我这里选SWD

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第5张

RCC下选择外部晶振如图

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第6张

点击上方的时钟树,正确配置后只要在最后

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第7张

这个位置,输入最大的速率,软件就会自动配置好时钟树

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第8张

最后在上方的项目管理界面选择你要IDE

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第9张

勾选需要的配置,这样工程就基本建立完成。

第三部分:配置需要的外设

在第二部分的基础上配置

1.定时器

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第10张

首先是定时器,想要驱动电机,我们需要配置定时器生PWM

这里使TIM1CH1CH2PWM控制两路电机

自动重装载值设置7200-1

这样生成的10khz的方波足够我们使用了

这里顺便说一下电机的驱动原理:电机的转速是PWM的占空比成正比的。

2.编码器

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第11张

编码器是读取电机真实速度,作为后PID控制的反馈值。

TIM2TIM3都如图配置编码器模式

3.主要控制定时器

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第12张

配置一10ms的定时器,作为我们的控制周期

网上很多平衡小车都是通过陀螺仪的引脚外部中进行控制周期

其实不是很需要这样,这样写代码也不好理解

只需要确保陀螺仪的回传速率能够大于等于控制周期即可

4.串口

作为陀螺仪数据的接收和处理

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第13张

波特率

如果和我是同款陀螺仪的话初始波特率9600回传速率10hz需要使用官方的上位机进行设置。

其实也可以使用指令进行配置,但是我一直没有成功,最后还是使TTL连接上位机配置。

这样所有需要的配置都配置完啦,接下来只要点击右上角的生成代码就可以啦。

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第14张

会生成这样一个文件夹

打开里面MDK-ARM就是熟悉Keil因为我选择的MDK IDE

第四部分:代码编写

1.HAL库运行编写

因为上面的步骤软件已经帮我们把基础的外设驱动代码编写完了

接下来我们要做一些必要的代码

HAL库中定时器中断需要我们手动开启

main.c

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第15张stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第16张开启定时器中断stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第17张开启编码器PWM以及串口接收中断

以及编码器启动,PWM生成都需要手动先开启

2.编码器代码

因为编码器是基于定时器的,所以我们找tim.c底下进行代码编写

stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第18张stm32平衡小车课程设计报告_用车辆识别代码怎么查车型号_https://bianchenghao6.com/blog__第19张

user code begin1

HAL库代码是软件生成的我们需要按照提示进行编写代码,否则下次生成代码,会消失

intRead_Encoder(uint8_tTIMX){

intEncoder_TIM;

switch(TIMX)

{

case2:Encoder_TIM=(short)TIM2->CNT;TIM2->CNT=0;break;

case3:Encoder_TIM=(short)TIM3->CNT;TIM3->CNT=0;break;

case4:Encoder_TIM=(short)TIM4->CNT;TIM4->CNT=0;break;

default:Encoder_TIM=0;

}

returnEncoder_TIM;}

编码器代码如上,控制周期10ms

3.电机控制代码

先前讲过电机主要是通PWM的占空比进行速度控制

所以我们需要编写一个控制占空比的函数

voidsetspeed(intleft_1,intright_1){

if(right_1>0)

{

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);//电机方向控制HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);

}

else

{

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);//电机方向控制HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);

}

if(left_1>0)

{

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_SET);

}

else

{

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_RESET);

}

if(left_16900)//满速7200限制速度避免坏电机left_1=-6900;

if(left_1>6900)

left_1=6900;

if(right_16900)

right_1=-6900;

if(right_1>6900)

right_1=6900;

left_1=abs(left_1);//输出占空比一定不能是负值right_1=abs(right_1);

__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,left_1);

__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,right_1);}

稍微讲解一下代码,首先需要对输入的占空比进行判断,是负的还是正的

对电机进行方向控制

后序进行一个限制速率的操作,避免电机太快损坏

由于输出给驱动的占空比一定不是能负数,所以我们还需要一abs函数取绝对值

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,left_1);

HAL库设TIM12的占空比函数

4.陀螺仪

陀螺仪是整个小车的灵魂,但是代码太长不好展示,大家可以去卖家找对应的例程

这里说一下思路就是通过串口不断读取数据

/***************串口中断回调函数数据处***************/voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){

if(huart->Instance==USART2)

{

USART2_IT_OK=USART2_IT_OK+1;

CopeSerial2Data(jydata);

//陀螺仪数据处理

//加速度a[0]=(float)stcAcc.a[0]/32768*16;

a[1]=(float)stcAcc.a[1]/32768*16;

a[2]=(float)stcAcc.a[2]/32768*16;

//角速度w[0]=(float)stcGyro.w[0]/32768*2000;

w[1]=(float)stcGyro.w[1]/32768*2000;

w[2]=(float)stcGyro.w[2]/32768*2000;

//角度Angle[0]=(float)stcAngle.Angle[0]/32768*180;

Angle[1]=(float)stcAngle.Angle[1]/32768*180;

Angle[2]=(float)stcAngle.Angle[2]/32768*180;

//四元素q[0]=(float)stcQ.q[0]/32768;

q[1]=(float)stcQ.q[1]/32768;

q[2]=(float)stcQ.q[2]/32768;

q[3]=(float)stcQ.q[3]/32768;

HAL_UART_Receive_IT(&huart2,&jydata,1);

}}

5.PID算法代码

PID算法在小车中有很多种

这里使用的是经过推导后直立环和速度环

要让小车直立这两个环是必不可少的

转向环可以暂时不需要

直立环是让小车具有一个直立的趋势

速度环是让小车在直立的情况下还能在原地不动

转向环是让小车具有走直线的能力

这里的代码借鉴了平衡小车之家的代码

直立环代码

floatBias,kp=100,kd=12;intbalance(floatAngle,floatGyro){

intbalance;

Bias=Angle-3;//===求出平衡的角度中和机械相关balance=kp*Bias+Gyro*kd;//===计算平衡控制的电PWM PD kpP kdDreturnbalance;}

单单有直立环是很难直立起来的还需要加入速度环

速度环代码

floatVelocity_Kp=60,Velocity_Ki=0.3;//PID参数intvelocity(intencoder_left,intencoder_right){

staticfloatVelocity,Encoder_Least,Encoder,Movement;

staticfloatEncoder_Integral;

//=============PI控制=======================//Encoder_Least=(encoder_left+encoder_right)-0;//===获取最新速度偏==测量速度(左右编码器之和-目标速度(此处为零Encoder*=0.8;//===一阶低通滤波Encoder+=Encoder_Least*0.2;//===一阶低通滤波Encoder_Integral+=Encoder;//===积分出位积分时间10msEncoder_Integral=Encoder_Integral-Movement;//===接收遥控器数据,控制前进后退if(Encoder_Integral>10000)Encoder_Integral=10000;//===积分限幅if(Encoder_Integral10000)Encoder_Integral=-10000;//===积分限幅Velocity=Encoder*Velocity_Kp+Encoder_Integral*Velocity_Ki;//===速度控制returnVelocity;}

PID的调参,那就是另一门学问了,这里就先不讲解

PID代码里面的一些低通滤波也不做讲解,想要做出来只要会用就行了

至此基本的代码都已经写完,是不是感觉其实平衡小车并不难造

接下来就是控制部分的代码了,要将上面的代码有序的组合起来

合成小车的灵魂

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

/* USER CODE BEGIN Callback 0 */

/* USER CODE END Callback 0 */

if (htim->Instance == TIM8) {

HAL_IncTick();

}

/* USER CODE BEGIN Callback 1 */

if (htim->Instance == TIM1) //10khz

{

TIM1_IT_OK = 1;

}

if (htim->Instance == TIM2) //encoder

{

TIM2_IT_OK = 1;

}

if (htim->Instance == TIM3) //encoder

{

TIM3_IT_OK = 1;

}

if (htim->Instance == TIM4) //5ms

{

TIM4_IT_OK = 1;

}

if (htim->Instance == TIM6) //10ms

{

TIM6_IT_OK = 1;

Left_Speed = -Read_Encoder(3);

Right_Speed = -Read_Encoder(2);

Balance_Pwm = balance(-Angle[0],-w[0]);

Velocity_Pwm = velocity(Left_Speed,Right_Speed);

setspeed(Balance_Pwm+Velocity_Pwm,Balance_Pwm+Velocity_Pwm);

}

/* USER CODE END Callback 1 */

}

这里HAL库的定时器中断回调函数

因为我设置的TIM6TIM6的中断回调函数中进行编写

注意控制周期10ms对应陀螺仪的速率一定不能低100hz不然小车就会一直摇摆。

先读取编码器的数据,自己在操作的时候要调好正负,因为每个人安装都不太一样

平衡小pid调参后

ok教程到此结

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复