STM32cubeMX--增量式PID调节电机速度(霍尔编码器)

前言

趁你们不注意,我突然更!!
在这里插入图片描述


一、直流减速电机与霍尔编码器

1.1、编码器介绍与选择

是一种可以测量目标机械运动或者目标位置的传感器或装备,分为线性编码器和旋转编码器,我们这里测的是电机速度,很明显,电机是旋转的,所以是旋转编码器

一般旋转编码器又有两种类型

  • 增量编码器:增量式旋转编码器在电机旋转时输出脉冲。 要使用增量编码器确定轴
    位置, 您必须知道起始位置并使用外部电路来计算输出脉冲数。
  • 绝对编码器:绝对旋转编码器输出对应于旋转角度的数字代码。 无需计算脉冲了解电
    机轴的位置。 您只需要读取编码器的数字输出。

我来翻译一下,增量编码器就是通过是输出脉冲让后让单片机计数脉冲数来算速度,绝对编码器就是直接输出角度变化的数字量。

打开淘宝搜,很明显,增量编码器占一大半儿,所以我们用增量编码器

增量编码器还可以分:

  • 光电:我来翻译一下这张图的意思,LED灯光穿过这个码盘的孔后就会输出一个脉冲,让后单片机计数脉冲就行了,不同的码盘通常转一圈发送的脉冲数也不一样,一般是300-500个脉冲。在这里插入图片描述

  • 霍尔:由霍尔开关集成传感器和磁性转盘组成, 霍尔式转速传感器结构如下图所示。 将磁性转盘的输入轴与被测转轴相连, 当被测转轴转动时, 磁性转盘便随之转动, 固定在磁性转盘附近的霍尔开关集成传感器便可在每一个小磁铁通过时产生一个相应的脉冲, 检测出单位时间的脉冲数,便可知道被测对象的转速。一般霍尔编码器的精度比较低。 在这里插入图片描述

1.2、编码器参数

根据题目可知,我买的是直流减速电机和霍尔编码器。
如图在这里插入图片描述

参数表:在这里插入图片描述
红色是我买的型号,蓝色是很重要的参数。

翻译:

  • 电压控制好,这玩意儿挺贵的,别给烧了昂。
  • 磁环式就是霍尔磁环式。
  • 精度就是每圈可以发送的脉冲数。
  • 霍尔

1.3、编码器测速原理

编码器使用的是“正交”这一原理将信号(光束)分为两个平行的,称为A和B。且他们通过编码器盘时相差90°。
偏移后会出现这种情况
在这里插入图片描述

1.3.1、方向判断

鲁迅说过:运动是相对的。
我们知道了A和B的输出相差90°,所以我们只要检测两个脉冲信号的相对位置就能检测出其方向

1.3.2、速度获取

首先知道精度CPR
在一个规定时间 t 内单片机获取脉冲总数 Num 。
F是一个周期测量的脉冲数,由图一个周期四个脉冲,对于32来讲,F一般是4或者2。
在这里插入图片描述

速度v 就相当于

v = (Num/(CPR*F))/t

因为时直流减速电机,所以还得除以减速比,但是这里就先不除了。我的电机减速比为1:10。
所以算出的v再除以10。

二、STM32cubeMX库配置编码器模式

2.1、连线分析

我所购买的编码电机的连线
在这里插入图片描述
我这里用的时野火的 指南者STM32F103VET6开发板。
STM32F103的高级定时器拥有编码器功能,所以我们直接匹配高级定时器的编码器功能的引脚!
电机驱动我们使用TB6612模块,不知道TB6612怎么用?请看这里

所以单片机上需要设置的引脚有:
1、高级定时器编码器模式(CH1,CH2通道)
2、串口(调PID不要串口真的大丈夫?)
3、通用或高级定时器的PWM输出模式
4、两个GPIO控制电机转方向
5、板载用来LED测试BUG
6、基本定时器计算时间
六色战队(不是)

在这里插入图片描述

2.2、cubeMX设置

2.2.1、cubeMX初始化

配置RCC外部晶振
在这里插入图片描述
改为72Mhz
在这里插入图片描述
仿真更改
在这里插入图片描述

2.2.2、高级定时器编码器模式(CH1,CH2通道)

在这里插入图片描述
编码器计数有三种模式
通道CH1计数
通道CH2计数
通道CH1、CH2双通道计数

编码器A相—CH1 简称CHA
编码器B相—CH2 简称CHB

此处需要说一点,上图种绿框部分通道x计数模式并不是如它英文Rising Edge一样的上升沿计数的意思,而是计数模式的意思,这里算是cubeMX的小问题。

他的真实含义是相对信号的电平计数模式。
什么是相对信号?其实就是CHA相对CHB的的电平或者CHB相对CHA的电平。
在这里插入图片描述
Rising Edge模式下CH1通道是遇到虚线出数值发生一次变化,左边为每次遇到虚线加一,右边为每次遇到虚线减一。即一个周期编码器计数两次。(Falling Edge模式加减相反)

知道Rising Edge什么意思了,CHB的就略过了,可以直接看下图理解。

TI1是CHA,TI2是CHB
计数规则如下图:
在这里插入图片描述
由图,TI1是一个周期CH1通道捕获两次脉冲,TI2是一个周期CH2通道捕获两次脉冲。
TI1和TI2就是两个同时捕获,一个周期可以捕获4次脉冲
精度更大更爽!!!
所以我们用TI1和TI2有效边缘检测!!!

CH1和CH2双通道捕获计数:在这里插入图片描述
由图一个周期捕获四次脉冲,所以我们得除4,也就是上面的公式中 F = 4

2.2.3、串口DMA

配置串口DMA的目的1是为接收速度数据调整速度,2是为了方便调BUG和参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.4、PWM输出

在这里插入图片描述

频率f = TimCLK/((PSC+1)x(ARR+1))

占空比 = (Pulse+1)/(ARR+1)

Pulse的值可以在代码中调
TIMx->CCRx = N;

2.2.5、GPIO控制电机方向

GPIO不多说,不知道的建议先学一下32。

2.2.5、LED

在这里插入图片描述
配置LED

2.2.6、基本定时器

在这里插入图片描述
是能基本定时器,频率为200HZ,每隔5ms进入一次中断

在这里插入图片描述
使能中断

2.2.6、配置中断优先级

在这里插入图片描述
配置中断优先级
TIM3为编码器捕获
TIM7为定时器中断

三、离散PID简介

PID分为位置式和增量式,位置式是普通的PID,增量式可以理解为式位置式的微分形式
由于编程系统时离散的,所以我们用离散的PID。
也就是说
累加代替积分
前后相减代表微分

3.1、位置式

通过直接改变输出来保证被控制量(一般为控制位置)的稳定。
大概意思就是:
就拿无人机来说明,当无人机距离所设定高度比较远时,电机转速变大,当无人机接近所设定位置时电机速度逐渐减小。
公式为:
在这里插入图片描述

3.2、增量式

通过改变输出的增减来保证被控制量(一般为控制速度)的稳定
其实就是:
我们要控制电机的速度,不是通过直接改变PWM的值,而是改变每次PWM的增减来控制速度的稳定。
公式为:
在这里插入图片描述

这里只对PID做简要概述,具体可以看
PID教学

四、代码及其讲解

生成代码后
我们设置三个全局变量

int Timer = 0;			//时间
uint8_t speed = 0;		//当前PWM
short TargetSpeed = 10; //目标速度

在主函数前初始化我们的设置

	TIM1->CCR1 = speed;           //写入PWM
	Motor_1(GPIO_PIN_SET);		  
	Motor_2(GPIO_PIN_RESET);	  //给电机一个电压,让他转起来!!

	/*打开PWM输出*/
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	/*打开定时器中断*/
	HAL_TIM_Base_Start_IT((TIM_HandleTypeDef *)&htim7);
	/*开启串口DMA接收,默认DMA为循环模式,千万不要放在循环里!!*/
	HAL_UART_Receive_DMA(&huart1,(uint8_t*)&TargetSpeed,sizeof(TargetSpeed));
	/*打开编码器捕获*/
	HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);

我们之前设置每5ms进入一次中断
并在中断中进行PWM输出的的计算

/*中断回调函数*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	short fSpeed;
	short ERROR;
	static uint8_t i = 0;
 	
 	/*判断当进入定时器7中断时*/
	if(htim->Instance == TIM7)
	{
		fSpeed = GetSpeed();			//获取当前速度	
		speed += PID_Cal(fSpeed,&ERROR);//当前PWM数值加上增量式PID计算所得
		
		//限制PWM最大范围
		if(speed>100)speed = 100;
		else if(speed<1)speed = 1;
		
		//将PID计算后的PWM写入系统
		SetMotorVoltageAndDirection(speed);

		/* 每隔(5*100)ms打印一次速度数据 */
		i++;
		if(i >= 100)
		{
			i = 0;
			Led_Toggle();
			printf("速度数据为%d\n",fSpeed);
			printf("目标速度为%d\n",TargetSpeed);
			printf("误差为%d\n",ERROR);
		}
	}
	
	if(htim->Instance == TIM3)
	{
		
	}
}

离散PID计算与速度获取控制函数

Contral.c

#include "main.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

#include "Contral.h"
#include <stdio.h>
#include <math.h>

/*PID参数*/
#define kp 0.86
#define ki 0.012
#define kd 0.005


/******************************
	功能:每5ms在定时器中执行一次,
				获取电机速度SPEED
	返回值:电机速度SPEED
	形参:无
*******************************/
short GetSpeed()
{
	short SPEED = 0;
//	static short last = 0;
	SPEED = (short)(__HAL_TIM_GET_COUNTER(&htim3)*100)/(4*16*10);
	__HAL_TIM_SET_COUNTER(&htim3,0);
	return SPEED;
}


/******************************
	功能:每5ms在定时器中执行一次,
				计算pwm返回值
	返回值:电机速度SPEED
	形参:无
*******************************/
short PID_Cal(short Speed,short *error)
{
	short Error = TargetSpeed - Speed;
	short Error_last = 0,Error_prev = 0;
	short pwm_add=0;
	*error = Error;
	pwm_add = kp*(Error - Error_last) + ki*Error + kd*(Error-2.0f*Error_last+Error_prev);
	
	Error_prev = Error_last;	  	    // 保存上上次误差
  Error_last = Error;	              // 保存上次偏差
	
	
	return pwm_add;
}
/******************************
	功能:判断电机正反转,
			并将计算所得的PWM数值
			写入单片机中
	返回值:无
	形参:无
*******************************/
void SetMotorVoltageAndDirection(int Pwm)
{
	if(Pwm<0)
	{
		Motor_1(GPIO_PIN_RESET);
		Motor_2(GPIO_PIN_SET);
	}
	else if(Pwm>0)
	{
		Motor_1(GPIO_PIN_SET);
		Motor_2(GPIO_PIN_RESET);
	}
	Pwm = fabs(Pwm);
  TIM1->CCR1 = Pwm;
}

让后你就可以开心的调参了~~~~
调参口诀:
在这里插入图片描述


后记

陈你们不注意,突然更新!!!!
这不给一键三连????

老样子:
度娘网盘:https://pan.baidu.com/s/1f7Jwmn6I8JZgZ3HuCw4MLQ
提取码:z5a4

版权声明:本文为CSDN博主「QWQ_DIODA」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/QWQ_DIODA/article/details/116519580

生成海报
点赞 0

QWQ_DIODA

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于STM32的指纹密码锁

设计简介: 本设计是基于单片机的指纹密码锁,主要实现以下功能: 矩阵按键输入密码,并通过按键显示*号可通过按键或手机开门密码可通过按键进行开门可通过蓝牙模块连接手机进行开门可通过指纹进

定时器触发STM32 ADC的采样转换示例

开发板:STM32F446 Nucleo开发板IDE:  keil MDK初始化配置工具:stm32cubeMx例程内容:通过定时器触发ADC规则通道及注入通道的模数转换工作。下面基于STM32CubeMx进行些必要

STM32串口发送接收数据

1.串口通信 我用的32是stm32f10x最小系统没有UART4和UART5 USART : 通用同步异步收发器 UART : 通用异步收发器 nRTS : 请求发送 nCTS : 请求接收 区别:USART指单片机的一个IO端

TCRT5000循迹模块原理及应用

前言 本文将讲述TCRT5000循迹模块的原理及应用。本文应用于STM32,对于使用循迹模块的你有一定的帮助。 以下是本篇文章的正文内容 一、TCRT5000循迹模块介绍 TCRT5000就是一个红外发射和接收器&#xff0