天天看点

STM32笔记之直流电机控制直流电机控制

直流电机控制

1. 编码器

1.1 简介

  1. 用来测量机械旋转或位移的传感器,能够测量机械部位在旋转或直线运动时的位移位置或速度等信息,并将其转换成一系列电信号
  2. 根据检测原理分为光电编码器(最广泛)、磁编码器(霍尔元件,精度较低)和感应式编码器(可靠性高,高端领域)
  3. 根据运动方式分为线性编码器和旋转编码器
  4. 根据编码类型分为增量式、绝对式、混合式

1.2 原理

  1. 分辨率:编码器能够分辨的最小单位
  2. 精度:编码器每个读数与转轴实际位置间的最大误差,通常用角度、角分或角秒来表示
  3. 最大响应频率:编码器每秒输出的脉冲数,单位是Hz
  4. 信号输出形式:直接输出/输入协议

1.3 定时器的编码器模式

STM32笔记之直流电机控制直流电机控制
STM32笔记之直流电机控制直流电机控制

1.3.1 程序逻辑

  1. 初始化定时器为编码器模式
/**************************************************************************
函数功能:把TIM3初始化为编码器接口模式
入口参数:无
返回  值:无
**************************************************************************/
void Encoder_Init_TIM3(void)
{
	__HAL_RCC_TIM3_CLK_ENABLE();			//使能定时器3
	GPIOA_TIM3_Init();						//使能IO口
	/* 把定时器初始化为编码器模式 */ 
	TIM3->PSC = 0x0;		//预分频器
	TIM3->ARR = ENCODER_TIM_PERIOD-1;	//设定计数器自动重装值 
	TIM3->CCMR1 |= 1<<0;          		//输入模式,IC1FP1映射到TI1上
	TIM3->CCMR1 |= 1<<8;          		//输入模式,IC2FP2映射到TI2上
	TIM3->CCER |= 0<<1;           		//IC1不反向
	TIM3->CCER |= 0<<5;           		//IC2不反向
	TIM3->SMCR |= 3<<0;	          		//SMS='011' 所有的输入均在上升沿和下降沿有效
	TIM3->CR1 |= 0x01;    				//CEN=1,使能定时器
}

//编码器TIM2 IO初始化
void GPIOA_TIM2_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOA_CLK_ENABLE();           	//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; 	//PA0、PA1
    GPIO_Initure.Mode=GPIO_MODE_INPUT;  		//浮空输入
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
           
  1. 读取定时器中的脉冲数,通过读取CNT的值
/**************************************************************************
函数功能:单位时间读取编码器计数
入口参数:定时器
返回  值:速度值
**************************************************************************/
int Read_Encoder(u8 TIMX)
{
	int Encoder_TIM;    
	switch(TIMX)
	{
		case 2:  Encoder_TIM= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;
		case 3:  Encoder_TIM= (short)TIM3 -> CNT;  TIM3 -> CNT=0;break;	
		case 4:  Encoder_TIM= (short)TIM4 -> CNT;  TIM4 -> CNT=0;break;	
		default: Encoder_TIM=0;
	}
	return Encoder_TIM;
}
           

2. PID

2.1 简介

P(比例)I(积分)D(微分)

通过编码器的速度反馈,可以实时知道小车的速度是否慢了,然后利用目标速度与实际速度的误差代入算法,既可获得当前占空比,达到控制速度的效果

PID控制其实对偏差的控制过程

  1. PID算法连续公式
  2. 离散的PID公式
  3. 位置式PID:每次输出均与过去的状态有关,直接控制执行机构
  4. 增量式PID:实时性,无扰动切换,有稳态误差,溢出的影响大

2.2 原理

  • 参数
  1. 比例项:增大比例系数可以加快系统的响应、增大比例系数有助于减小静差
  2. 积分项:增大积分时间有利于减小超调,使系统稳定性增加,但是会增长消除静差的时间
  3. 微分项:具有超前调节的作用,抑制振荡
  • 整定方法
  1. 试凑法:先比例,再积分,最后微分
  2. 临界比例法:从大到小逐渐改变调节器的比例度,并且得到等幅度的震荡过程就叫做临界比例度
  3. 一般调节法:
    1. 输出不振荡 - 增大比例增益P
    2. 输出不振荡 - 减小积分时间常数Ti
    3. 输出不振荡 - 增大微分时间常数Td
    (这三个任何一个过大都会造成系统振荡)
  • 采样周期
  1. 采样周期越短控制的效果越接近于连续,对于大多数算法缩短采样周期可使控制回路性能改善
  2. 但采样周期缩短时,频繁的采样必然会占用较多的计算工作时间,同时也会增加计算的负担
  3. 而对有些变化缓慢的受控对象无需很高的采样频率既可满意地进行跟踪,过多的采样反而没有多少实际意义

2.3 程序逻辑

一般把PID放在一个周期执行,比如定时器或定时的中断中,这里以定时器为例

  1. 在定时器中断中:读取编码器的值-PID计算-赋值PWM输出
//回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim==(&TIM3_Handler))
    {
		Encoder=Read_Encoder(2);                                 //===读取编码器的值,M法测速,输出为每10ms的脉冲数
		Moto1=Incremental_PI(Encoder,Target_velocity);           //===速度PI控制器
		Xianfu_Pwm(&Moto1);                                       //===PWM限幅
		Set_Pwm(Moto1);                                          //===赋值给PWM寄存器
		printf("AIN1=%d\tAIN2=%d\tMoto1=%d\tEncoder=%d\r\n",AIN1,AIN2,Moto1,Encoder);
    }
}
           
  1. 增量式PI控制器
/**************************************************************************
函数功能:增量PI控制器
入口参数:编码器测量值,目标速度
返回  值:电机PWM
根据增量式离散PID公式 
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k)代表本次偏差 
e(k-1)代表上一次的偏差  以此类推 
pwm代表增量输出
在我们的速度控制闭环系统里面,只使用PI控制
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)
**************************************************************************/
int Incremental_PI(int Encoder,int Target)
{ 	
	float Kp=20,Ki=30;			//原例程中Kp=20,Ki=30	
	static int Bias,Pwm,Last_bias;
	
	//Bias=Encoder-Target;               //计算偏差
	Bias=Target-Encoder;               //计算偏差
	Pwm+=Kp*(Bias-Last_bias)+Ki*Bias;  //增量式PI控制器
	Last_bias=Bias;	                   //保存上一次偏差 
	
	return Pwm;                        //增量输出
}
           

2.4 剖析PI控制器

  1. 中断函数中
    1. 读取编码器的值:Encoder(由于定时器每10ms中断一次,所以得到的值为每10ms的脉冲数)
    2. 调用速度PI控制器获得电机PWM变量:Motol
    3. 进行PWM限幅
    4. 赋值给PWM寄存器
  2. 读取编码器的值
    1. 初始化TIM为编码器模式(需要两个IO口)
    2. 读取TIM->CNT的值
  3. 增量PI控制器
    1. 该函数中的Kp和Ki需要直接在函数中修改
    2. 该函数的形参为编码器测量值:Encoder和目标速度:Target_velocity(目标速度的表示为每10msX个脉冲)
    3. 该函数的返回值是一个int的数据
    4. 补充知识点:static(静态局部变量的效果类似于局部变量)
  4. PWM限幅
    1. 由于PWM的满幅是7200,不可以超过这个值
    2. 若Motol的绝对值超过7100,则将其修改为设定的最大值:7100

继续阅读