电机的速度pid闭环控制代码及注释
我写文章的内容,大部分围绕一个技术人员的技术路线、财务规划等,可能会稍微有点杂。但我感觉这是一些技术人员的普遍现象,都需要技术积累,都需要生存,都想做好的产品。在这里都可以看到相关的文章,我会陆续的整理思路和内容,发出来。
上一篇文章讲了基于stm32单片机的pwm输出,实现的代码。下面用一个例子来说明运动控制中,一个旋转速度闭环是如何通过代码实现,后面都加了注释。大家一起学习交流。
这个在机器人的运动控制中很常用,具体代码及注释如下:
#include "sys.h"
u8 Flag_Stop=1; //停止标志位
int Encoder; //编码器的脉冲计数
int Motor_1; //电机PWM变量
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
LED_Init(); //初始化与 LED 连接的硬件接口
uart_init(72,115200); //初始化串口1
MiniBalance_PWM_Init(7199,0); //=====初始化PWM 10KHZ 高频可以防止电机低频时的尖叫声
Encoder_Init_TIM2(); //初始化编码器
Timer3_Init(99,7199); //=====10MS进一次中断服务函数,中断服务函数在control.c
while(1)
{
printf("%d\r\n",Encoder);
}
}
#include "motor.h"
void MiniBalance_Motor_Init(void)
{
RCC->APB2ENR|=1<<3; //PORTB时钟使能
GPIOB->CRH&=0X0000FFFF; //PORTB12 13 14 15推挽输出
GPIOB->CRH|=0X22220000; //PORTB12 13 14 15推挽输出
}
void MiniBalance_PWM_Init(u16 arr,u16 psc)
{
MiniBalance_Motor_Init(); //初始化电机控制所需IO
RCC->APB2ENR|=1<<11; //使能TIM1时钟
RCC->APB2ENR|=1<<2; //PORTA时钟使能
GPIOA->CRH&=0XFFFF0FF0; //PORTA8 11复用输出
GPIOA->CRH|=0X0000B00B; //PORTA8 11复用输出
TIM1->ARR=arr; //设定计数器自动重装值
TIM1->PSC=psc; //预分频器不分频
TIM1->CCMR2|=6<<12; //CH4 PWM1模式
TIM1->CCMR1|=6<<4; //CH1 PWM1模式
TIM1->CCMR2|=1<<11; //CH4预装载使能
TIM1->CCMR1|=1<<3; //CH1预装载使能
TIM1->CCER|=1<<12; //CH4输出使能
TIM1->CCER|=1<<0; //CH1输出使能
TIM1->BDTR |= 1<<15; //TIM1必须要这句话才能输出PWM
TIM1->CR1=0x8000; //ARPE使能
TIM1->CR1|=0x01; //使能定时器1
}
#include "encoder.h"
/**************************************************************************
函数功能:把TIM2初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM2(void)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0XFFFFFF00;//PA0 PA1
GPIOA->CRL|=0X00000044;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM2->PSC = 0x0;//预分频器
TIM2->ARR = ENCODER_TIM_PERIOD-1;//设定计数器自动重装值
TIM2->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM2->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM2->CCER |= 0<<1; //IC1不反向
TIM2->CCER |= 0<<5; //IC2不反向
TIM2->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM2->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:把TIM4初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM4(void)
{
RCC->APB1ENR|=1<<2; //TIM4时钟使能
RCC->APB2ENR|=1<<3; //使能PORTb时钟
GPIOB->CRL&=0X00FFFFFF;//PB6 PB7
GPIOB->CRL|=0X44000000;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM4->PSC = 0x0;//预分频器
TIM4->ARR = ENCODER_TIM_PERIOD-1;//设定计数器自动重装值
TIM4->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM4->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM4->CCER |= 0<<1; //IC1不反向
TIM4->CCER |= 0<<5; //IC2不反向
TIM4->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM4->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:单位时间读取编码器计数
入口参数:定时器
返回 值:速度值
**************************************************************************/
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;
}
感谢阅读:)
对我文章感兴趣的网友,可以关注我。
一文搞懂PID算法如何实战-直流电机控制从原理、C代码到参数整定
今天我们来聊一聊直流电机速度控制,不过别担心,我们会用最通俗易懂的语言来讲解这个在工程和机器人领域中非常重要的应用案例,以此为例让你一文搞懂PID算法是如何实战的。
1. 理论分析
在速度闭环控制中,我们使用PID(比例-积分-微分)控制算法来调整电机的转速,使得实际转速逐渐趋近于期望值。PID算法的离散形式可以表示为:
离散PID
这个公式描述了如何通过比例项、积分项和微分项来计算控制输出,进而调整电机的运行状态。PID代表“比例-积分-微分”,是一种超级智能的调节系统。这玩意的目标是让电机跑到我们期望的速度。
比例项(P): 就是看实际速度跟我们想要的速度差多远,然后按比例调整输出。比如,差距大,输出就大,差距小,输出就小。积分项(I): 累积一下误差,让电机更快地达到目标速度。就好比你一直按着油门,车就能更快。微分项(D): 预测一下速度变化的趋势,防止电机响应过度。有点像提前感知前方路况,避免突然变化。这三个项通过一些调节参数,比如Kp、Ki、Kd,就组成了PID算法。
2. 控制原理图
下图为电机速度控制原理图,清晰展示了闭环控制系统中各个组成部分之间的关系,搞懂它就明白了整个系统的大的原理。
控制原理图
1.带编码器直流电机就是整个系统的被控制对象,我们要控制的就是它的转速。
2.直流电机是带编码器的,编码器通过测量单位时间内的脉冲数就能算出电机实际的转动速度。我们要将编码器传感器测量的电机实际转速值反馈给速度控制器使用。
3.直流电机驱动器就是驱动电机动起来的硬件部分,有了它电机就可以让电机有足够能量转起来,控制器只需要给直流电机驱动器提供一个电压信号,驱动器就根据这个信号大小来控制电机转速,可以理解成油门信号。所以控制器就是控制输入到驱动器的这个电压信号来达到控制电机的目的,一般是使用微控制器的PWM脉宽调制来实现信号电压大小调节。
4.速度PID控制器部分就是PID算法部分,我们一般通过微控制器来跑固件代码的形式来实现PID算法控制,所以是一个软件实现过程。
总体来讲就是,速度闭环控制就是根据编码器测量的电机实际速度,并与目标速度值进行比较,得到控制偏差,然后通过PID对偏差的比例、积分、微分进行控制,使偏差趋于零的过程。
3. C语言代码实现
现在,让我们看一下如何用C语言来结合上面的理论来实现这个速度闭环控制器,这是一个非常有意思的过程。PID算法函数代码如下:
C代码
函数入口参数为编码器的电机速度的实际测量值,第二个参数为我们期望的速度目标值,函数返回值是pwm值,也就是输入到电机驱动器的电压信号大小。
第二行是计算速度偏差,测量值减去目标值。
第三行通过累加实现 速度偏差积分。
第四行使用位置式PID算出电机控制值,按照上面PID离散公式计算。
第五行事保存上一次速度偏差,方便下次计算。
接着,如下,在单片机的周期执行函数里面调用该函数来实现。
代码
1.这个调用PID函数的周期即是我们离散系统的控制周期,比如10ms,这个一般根据实际控制需求来定,理论上越小越好,因为控制周期越小信号更连续,但是也不能也必须在电机和驱动器的可接受信号范围内。
2.Set_Pwm(Moto)就是将PID算法算出的控制值通过单片机的PWM技术调制出实际电压信号输入到电机驱动器来控制电机。注意,这个函数具体实现根据单片机硬件不同具体代码实现有所差异,但是通用思路基本上也是将PID算出的值设置到PWM相关寄存器上,从而让单片机IO输出对应电压。
通过周期性执行PID函数,周期性单片机输出变化电压信号,输入到电机驱动器就可以周期性的调整电机转速,通过不断调整电机输出,使得电机的当前转速逐渐接近目标转速。
4. 参数整定
在实际应用中,PID算法的参数(Kp、Ki、Kd)的选择对系统性能影响很大。通常采用经验法或者一些专业工具进行参数整定。这包括:
比例项参数 Kp: 控制系统的灵敏度,如果设置太高,系统可能会过于敏感,引起振荡。如果设置太低,系统响应可能较慢。积分项参数 Ki: 控制系统的稳定性,用于消除系统静差。过高的积分项可能导致系统过度调整,产生超调。微分项参数 Kd: 控制系统的过冲和振荡,可以减缓系统的响应。然而,过高的微分项可能引入噪声。参数的选择需要在实际系统中进行调试和优化,通常是一个迭代的过程。如下图就是一个比较理想的效果。
理想效果图
白线是目标值,红线是实际电机响应曲线。可以看到系统很快速,也就是很短时间内就达到目标值,这叫快速性。可以看到系统达到目标值之后震荡非常小,波动幅度很小,这叫稳定性。系统最后停留的速度基本上和目标线重叠,基本无偏差,这叫准确性。关于PID的参数整定,通俗讲法叫做调参,到底如何整定,由于文章篇幅问题,后续文章我将详细讲解,欢迎大家持续关注。
后续持续更新系列高质量文章,码字不易,觉得写的不错欢迎关注、点赞、收藏以及提问。
相关问答
8位 单片机PID控制 PWM的算法如何实现,C语言计算? - 沈默U 的...能帮我设计一个用单片机控制PWM占空比再控制可控硅的开端的硬件及程序。如果有发至liu983580@163.com直接配置单片机PWM输出的占空比就行了啊
单片机 中的 PID 算法是什么意思啊,有什么用途呢?谢谢! - ?水...就是一算法用于控制PID算法是一种经典的控制算法.由比例/积分/微分组成.建议看看控制理论.PID就是比例积分微分控制,在工业里面应用非常广泛,据统...
单片机 怎么用 pid控制 1220v的加热灯-ZOL问答对于PID控制,首先要明确几点:1.确定所需控制的物理过程是否可微分,可微分性是PID控制的基础条件之一;2.确定所要控制的参数是否可测量和可观察;3.确定所需...
如何用温度 控制电机 运行?PID控制即可,别人已经说过了如果是工厂里用买个带PID功能的温控表,能输出4~20mA信号,测温用热电阻就行(根据温控表支持的类型、测温范围选择),如果布线较...
IGBT如何驱动直流电动机? 单片机控制 ?1,简单的开关控制,用单片机引脚输出高低电平,控制MOS管驱动电路。2,正反转控制,需要两个单片机引脚,一个控制正反转,一个控制启动与否。3,需要控制速度...1...
如何用51 单片机控制电机 和水泵?谢谢邀请,作为一名单片机开发工程师,和大家讲一讲电机控制的几个技术要点。电机是自动化等领域必须要用到的电子器件,而电机控制也就应用很广泛,专业技术要求...
有谁知道么,重庆老牌的晶闸管直流调速设备,晶闸管直流调速...基于单片机控制的PWM直流调速系统贾玉瑛;王臣介绍了一种基于单片机控制的PWM直流电机调速系统,系统以8032单片机为核心,以小直流电机为控制对象,实...
51 单片机 采用的什么算法?51单片机PID的算法实现程序,用整型变量来实现PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了,关于系数和采样电压全...
步进 电机 驱动器和步进 电机 怎么接线?[回答]TS5740A42A步进电机一般有两相,三相,五相步进电机。接TD4845驱动器一般有说明书。不能随便接。因为步进电机和普通电机不同,里面至少两个绕组。接错...
两个电磁阀怎么 控制 一开一关?首先一般的电磁阀你是无法控制开口大小的,比例阀才行,一般的电磁阀只能控制通断。以我在学校时的经验,单片机的输出不能直接控制电磁阀,驱动能力不够,可以...