当前位置:网站首页>【无标题】PID控制TT编码器电机
【无标题】PID控制TT编码器电机
2022-04-23 06:13:00 【ZLP啊~】
记录本人学习的笔记
开始学习PID感觉他很难,其实并不是的。首先我们需要取了解PID控制电机的基本流程,然后再搭配你学的理论知识。
下面来讲讲具体的实现,首先设置单片机的定时器用来读取到AB相中的脉冲数目(首先注意的是获取脉冲的通道只能是定时器的前两个通道),然后在PID中将你设置的脉冲数目与测得的脉冲数目进行对比。通常来说我们设定的是转速,所以我们需要将转速转换成脉冲数目。举个例子:TT电机13线的使四倍频,一圈有2496个脉冲,我们设定50转每分钟(这里只轮子转速,如果是电机内部转速需要除以你的减速比),然后我们设置定时器10ms读取一次值。那么10ms脉冲数应该为50*2496/6000(一分钟有6000个10ms),因此将设定脉冲与目前测得得脉冲带入PID计算公式算出值,抽象地来说它就是个依据偏差,产生的控制作用。通过计算值产生一个PWM信号。
下面是部分代码,可以看一看,基本上就这些东西。
1.对定时器进行设置
#include "encoder.h"
#include "delay.h"
#include "usart.h"
//PA0
//PA1
void TIM5_Encoder_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x00; // No prescaling
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM5, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 10;
TIM_ICInit(TIM5, &TIM_ICInitStructure);
TIM_SetCounter(TIM5,0);
TIM_Cmd(TIM5, ENABLE);
}
2.PID计算部分
这里有两种计算公式就是写法不同,用哪个都可以,PID计算公式用很多看你自己需求。
#include "pid.h"
static double Kp=10;
static double Ki=0;
static double Kd=0;
int shouxie_PID_ZLP(int now , int set)
{
int PWM,Bias,Bias_D;
static int error,last_Bias;
Bias = now - set;
error +=Bias;
Bias_D=Bias-last_Bias;
PWM = Kp*Bias + Ki*error +Kd*Bias_D;
last_Bias = Bias;
return PWM;
}
static double ProportionA=70;
static double IntegralA=25;
static double DerivativeA=35;
int SPEED_PID_A(int now,int set)
{
static int LastError; //Error[-1]
static int PrevError; //Error[-2]
int iError,Output;
iError=set-now;
Output = ((ProportionA * (iError - LastError)) + (IntegralA * iError) + (DerivativeA * (iError - 2*LastError + PrevError)));
PrevError=LastError;
LastError=iError;
return Output;
}
3.对输出进行控制
#include "control.h"
#include "pid.h"
#include "datascope.h"
#include "motor.h"
#include "usart.h"
int para_A;
int Motor_A;
int SetRPMA=100;
#define SetPointA SetRPMA*2496/6000
int myabs(int a){
int temp;
if(a < 0) temp = -a;
else temp = a;
return temp;
}
int Read_Encoder(u8 x)
{
int Encoder_TIM;
switch(x)
{
case 5: Encoder_TIM= (short)TIM5 -> CNT; TIM5 -> CNT=0;break;
default: Encoder_TIM=0;
}
return Encoder_TIM;
}
int Encoder_A;
int Send_Count,i;
extern int adc_data;
int position_out;
int ac_speed_b;
int bigout_B;
void TIM6_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM6, TIM_IT_Update) != RESET)
{
Encoder_A=Read_Encoder(5); //读取编码器得值
para_A=SPEED_PID_A(Encoder_A,SetPointA);
/* 将设定脉冲与测得脉冲带入到PID控制器中 */
printf("%d\r\n",Encoder_A);
if((para_A<-3)||(para_A>3))
{
Motor_A +=para_A;
}
if(Motor_A>7000)Motor_A=7000;//限幅
if(Motor_A<-7000)Motor_A=-7000;
if(Motor_A > 0){
MotorA1 = 0;
MotorA2 = 1;
}else{
MotorA1 = 1;
MotorA2 = 0;
}TIM8->CCR1 = myabs(Motor_A);
/*定时器8 我使用得计数周期为一万,CCR1的值为 myabs(Motor_A)*/
}
TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update);
}
有不懂的或者是我错的可以写在评论区。
版权声明
本文为[ZLP啊~]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_52297353/article/details/122715622
边栏推荐
猜你喜欢
随机推荐
【点云系列】Neural Opacity Point Cloud(NOPC)
1.2 初试PyTorch神经网络
PyTorch 19. PyTorch中相似操作的区别与联系
[dynamic programming] longest increasing subsequence
Exploration of SendMessage principle of advanced handler
Gee configuring local development environment
Thanos. SH kill bully script, easily delete half of the files in the system at random
Compression and acceleration technology of deep learning model (I): parameter pruning
【Tensorflow】共享机制
[Point Cloud Series] SG - Gan: Adversarial Self - attachment GCN for Point Cloud Topological parts Generation
Some common data type conversion methods in pytorch are similar to list and NP Conversion method of ndarray
rearrange 和 einsum 真的优雅吗
【动态规划】杨辉三角
EMMC/SD学习小记
使用 trt 的int8 量化和推断 onnx 模型
Visual Studio 2019安装与使用
被 onnx.checker.check_model 检查出的常见错误
AUTOSAR从入门到精通100讲(五十)-AUTOSAR 内存管理系列- ECU 抽象层和 MCAL 层
. net encountered failed to decode downloaded font while loading font:
Common regular expressions