首页 > 编程知识 正文

pid开环到闭环如何实验,pid双闭环控制系统

时间:2023-05-03 14:45:40 阅读:133795 作者:4280

PS :更新2022 PID的详细说明

一般不怎么使用增量式,而是使用位置式。 以下也可以不看增量式

正文分为几个部分:

1 .编码器

2 .计时器输入捕获(计时器初始化为编码器模式) ) ) ) ) ) ) ) )。

3.pid闭环控制速度

编码器配置

编码器1.概述

传感器-角速度或角位移-------------电数字脉冲3358 www.Sina.com/http://www.Sina.com /

注意:

我从一开始就一直怀疑的一个点是这里的4倍频率。 这样操作时,一个nxdsg计数器计数两次。 然后,ab2相计数4次。 但是,我们明明只出了一个nxdsg却记得四个,所以这边有问题。

2.原理

计时器各参数的含义四倍频技术

case 2: encoder _ xsd zxc=(短) xsdzxc2 - CNT; xsdzxc2 - CNT=0; 布雷克; 更改为

case 2: encoder _ xsd zxc=(短) xsdzxc2 - CNT )/4; xsdzxc2 - CNT=0; 布雷克; 转速计算方法:用捕捉值(1秒输出的脉冲数) /编码器线数(转速1转输出脉冲数) /电机减数比)内部电机转速相对于电机输出轴转速之比,即减速齿轮比() ) ) ) )

2 .计时器输入捕获(将计时器初始化为编码器模式)//解决方案1:经过学长讲解,下文中xsdzxc2配置编码器时候,psc=0x0需要改为0x03,这样能达到4分频,也只有在这种情况下才能准确计算出单位时间内的nxdsg数量//(边沿触发cnt计数,分频没用)

void编码程序_ init _ xsd zxc2(void ) {RCC-APB1ENR|=10; //xsdzxc2时钟使能RCC-APB2ENR|=12; 启用端口时钟GPIOA-CRL=0XFFFFFF00; //PA0 PA1将编码器的ab相GPIOA-CRL|=0X00000044 //浮动输入//*计时器初始化为编码器模式*/xsdzxc2-PSC=0x0预分频器xsd zxc 2 //设置计数器自动重载值65535 xsdzxc2-CCMR1 |=10; //输入模式,将IC1FP1映射到TI1的xsdzxc2-CCMR1 |=18; //输入模式,将IC2FP2映射到TI2的xsdzxc2-CCER |=01; //IC1不反转xsdzxc2-CCER |=05; //IC2不反转xsdzxc2-SMCR |=30; //SMS='011 '所有输入在上升沿和下降沿有效的xsdzxc2-CR1 |=0x01; //CEN=1,启用定时器(voidencoder_init_xsdzxc4) void ) {RCC-APB1ENR|=12; //xsdzxc4时钟使能RCC-APB2ENR|=13; 启用PORTb时钟GPIOB-CRL=0X00FFFFFF; //PB6 PB7GPIOB-CRL|=0X44000000; //将浮动输入//*计时器初始化为编码器模式*/xsdzxc4-PSC=0x0预分频器xsd zxc4- arr=encoder _ xsd zxc _ period-1; //设置计数器自动重载值xsdzxc4-CCMR1 |=10; //输入模式,将IC1FP1映射到ti1 xsd zxc4- CCM R1|=18; //输入模式,将IC2FP2映射到TI2的xsdzxc4-CCER |=01; //IC1不反转xsdzxc4-CCER |=05; //IC2不反转xsdzxc4-SMCR |=30; //SMS='011 '所有输入在上升沿和下降沿有效的xsdzxc4-CR1 |=0x01; //CEN=1、使能计时器}3.通过PID闭环控制速度main函数调用

timer3_ init (99,7199; //=====10MS进入一次中断服务函数,中断服务函数位于控制. c计时器3

配置函数

void Timer3_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<1; //时钟使能 xsdzxc3->ARR=arr; //设定计数器自动重装值 xsdzxc3->PSC=psc; //预分频器7200,得到10Khz的计数时钟xsdzxc3->DIER|=1<<0; //允许更新中断xsdzxc3->DIER|=1<<6; //允许触发中断 xsdzxc3->CR1|=0x01; //使能定时器MY_NVIC_Init(1,3,xsdzxc3_IRQn,2);}

定时器3中断服务函数,其中用到的函数在下文实现

int Target_velocity=50; //设定速度控制的目标速度为50个脉冲每10msint xsdzxc3_IRQHandler(void) { if(xsdzxc3->SR&0X0001)//10ms定时中断{ xsdzxc3->SR&=~(1<<0); //===清除定时器1中断标志位 Encoder=Read_Encoder(2);//===读取编码器的值,M法测速,输出为每10ms的脉冲数 Led_Flash(100); //===LED闪烁;指示单片机正常运行 Moto1=Incremental_PI(Encoder,Target_velocity); //===速度PI控制器 Xianfu_Pwm(); //===PWM限幅 Set_Pwm(Moto1); //===赋值给PWM寄存器 } return 0; }

读定时器cnt计数函数

int Read_Encoder(u8 xsdzxcX){ int Encoder_xsdzxc; switch(xsdzxcX) { case 2: Encoder_xsdzxc= (short)xsdzxc2 -> CNT; xsdzxc2 -> CNT=0;break; case 3: Encoder_xsdzxc= (short)xsdzxc3 -> CNT; xsdzxc3 -> CNT=0;break; case 4: Encoder_xsdzxc= (short)xsdzxc4 -> CNT; xsdzxc4 -> CNT=0;break; default: Encoder_xsdzxc=0; }return Encoder_xsdzxc;} 增量式PID控制函数 /**************************************************************************函数功能:增量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; static int Bias,Pwm,Last_bias; Bias=Encoder-Target; //计算偏差 Pwm+=Kp*(Bias-Last_bias)+Ki*Bias; //增量式PI控制器 Last_bias=Bias; //保存上一次偏差 return Pwm; //增量输出} 位置式PID控制 /**************************************************************************函数功能:位置式PID控制器入口参数:编码器测量位置信息,目标位置返回 值:电机PWM根据位置式离散PID公式 pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]e(k)代表本次偏差 e(k-1)代表上一次的偏差 ∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;pwm代表输出**************************************************************************/int Position_PID (int Encoder,int Target){ float Position_KP=80,Position_KI=0.1,Position_KD=500; static float Bias,Pwm,Integral_bias,Last_Bias; Bias=Encoder-Target; //计算偏差 Integral_bias+=Bias; //求出偏差的积分 Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias); //位置式PID控制器 Last_Bias=Bias; //保存上一次偏差 return Pwm; //增量输出} /**************************************************************************函数功能:赋值给PWM寄存器入口参数:PWM返回 值:无**************************************************************************/void Set_Pwm(int moto1){if(moto1>0)AIN2=1,AIN1=0;else AIN2=0,AIN1=1;PWMA=myabs(moto1);}/**************************************************************************函数功能:限制PWM赋值 入口参数:无返回 值:无**************************************************************************/void Xianfu_Pwm(void){ int Amplitude=7100; //===PWM满幅是7200 限制在7100 if(Moto1<-Amplitude) Moto1=-Amplitude;if(Moto1>Amplitude) Moto1=Amplitude;}

源码:

电机速度闭环控制
电机位置闭环控制

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。