工具/软件:Code Composer Studio
大家好、
我尝试使用 PID 控制直流电机的速度、但我无法稳定任何所需的速度、而且导数项始终保持为零。
/*直流电机速度*/ #include "Config.h" #define PERIOD_PWM 1250 // 2ms 时间周期等于1250个节拍 #define GET_MAG (X)(X > 0? X:-X) #ifndef DEGPS_RPM #define DEGPS_RPM 0.16667 #endif float encdrRdShldr、rotDirShldr、dpsShldr、rpmShldr、errVelShldr、 intgErrShldr、dErrShldr、pidVelShldr、pillErrVelShldr; float desVelShldr、 kpVelShldr、kiVelShldr、kdVelShldr、PWM、D; float scaledOutVelShldr; float accVelShldr; int a; int main (void) { SysCtlClockSet (SYSCTL_SYSDIV_2|SYSCTL_USE_PLL|SYSCTL_MAIN|SYSCTL_XTAL_16MHz);// 400/2=200MHz (2是默认分频器)、200/5=40MHz (rtpsr/ rrrrrnh 配置);//系统时钟 配置(rtrrrrrrrrrrrrrt1)/ rrtrnrrrrrrrmrnh 配置(rt1);rrrrrtrrmrt1) kiVelShldr = 1;kdVelShldr = 2; /* 方向引脚*/ SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); GPIOPINTypeGPIOOutput (GPIO_PORTB_BASE、(GPIO_PIN_0 | GPIO_PIN_1_GPIO_PIN_2)); MAG = 99; A = 0; } void Timer0IntHandler (void) { encdrRdShldr = QEIVelocityGet (QEI0_BASE); rotDirShldr = QEIDirectionGet (QEI0_BASE); if (rotDirShldr = 1) //CCW { dpsShldr =-1*(encdrRdShldr * 0.1124); rpmShldr = dpsShldr * DEGPS_RPM; } 否则、if (rotDirShldr =-1)//cw { dpsShldr =(encdrRdShldr * 0.1124); rpmShldr = dpsShldr * DEGPS_RPM; } if (desVelShldr > 60) { desVelShldr = 60; } 否则、如果(desVelShldr <-60) {desVelShldr =-60; } errVelShldr = desVelShldr - rpmShldr; intgErrShldr =(accErrVelShldr)* 0.0001; dErrShldr =(errVelShldr - pillErrVelShldr)* 10000; PWM = desVelShldr * 1.35;//根据所需的速度进行 PWM pidVelShldr =(kpVelShldr * errVelShldr + kiVelShldr * intgErrShldr + kdVelShldr * dErrShldr)+PWM; d= kdvelShldr * dErrShldr; accErrVelShldr += errVelShldr; if (pidVelShldr >= 0) { if (pidVelShldr >= 254) pidVelShldr = 254; if (pidVelShldr <= 1) pidVelShldr = 1; } 否则、如果(pidVelShldr < 0) { if (pidVelShldr <=-254) pidVelShldr =-254; if (pidVelShldr >=-1) pidVelShldr =-1; } if (pidVelShldr >= 0) { //设置方向位以顺时针旋转电机 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_0、GPIO_PIN_0); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_1、0x00); } 其他 { //设置方向位以逆时针旋转电机 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_0、0x00); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_1、GPIO_PIN_1); } scaledOutVelShldr = get_MAG (pidVelShldr)* 5.0; if (scaledOutVelShldr > 1250) {scaledOutVelShldr = 1250;} PWMPulseWidthSet (PWM1_base、PWM_OUT_7、scaledOutVelShldr); A++; if (a = 1){ GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2); }if (a ==2){ GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0x00); A = 0;} pellErrVelShldr = errVelShldr; TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);//清除计时器中断 }
这是 Config.c 源文件的代码
#include "Config.h"
浮动 MAG;
空 initlzVarConfig (空)
{
MAG = 0.0;
}
void encdrShldrConfig (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
//解锁 GPIOD7
HWREG (GPIO_PORTD_BASE + GPIO_O_LOCK)= GPIO_LOCK_KEY;
HWREG (GPIO_PORTD_BASE + GPIO_O_CR)|= 0x80;
HWREG (GPIO_PORTD_BASE + GPIO_AFSEL)&&~0x80;
HWREG (GPIO_PORTD_BASE + GPIO_O_DEN)|= 0x80;
HWREG (GPIO_PORTD_BASE + GPIO_O_LOCK)= 0;
SysCtlPeripheralEnable (SYSCTL_Periph_QEI0);//启用 QEI 外设
//将引脚设置为 PHA0和 PH0
GPIOPinConfigure (GPIO_PD6_PHA0);//GPIOPinConfigure (0x00031806);//0x00031806 => GPIO_PD6_PHA0
GPIOPinConfigure (GPIO_PD7_PHB0);//GPIOPinConfigure (0x00031C06);// 0x00031C06 => GPIO_PD7_PHB0
GPIOPinTypeQEI (GPIO_PORTD_BASE、(GPIO_PIN_6 | GPIO_PIN_7));//设置 QEI 的 GPIO 引脚
//配置正交编码器,使用任意上限2000并启用 QEI
QEIConfigure (QEI0_BASE,(QEI_CONFIG_CAPTURE_A | QEI_CONFIG_RESET_IDX | QEI_CONFIG_QUIPOTIY | QEI_CONFIG_NO_SWaP),640000);
QEIEnable (QEI0_BASE);
//配置和启用速度
QEIVelocityConfigure (QEI0_BASE、QEI_VELDIV_1、SysCtlClockGet ());//除以时钟速度以获得计数/秒
QEIVelocityEnable (QEI0_BASE);
}
void tmr0IntrptConfig (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
TimerConfigure (TIMER0_BASE,TIMER_CFG_A_PERIODICRACASE);
uint32_t InterruptPeriod = SysCtlClockGet ()* 0.0001;
TimerLoadSet (TIMER0_BASE、TIMER_A、InterruptPeriod - 1);
IntEnable (INT_TIMER0A);
TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
IntMasterEnable();
TimerEnable (TIMER0_BASE、TIMER_A);
}
void pwmShldrConfig (void)
{
//启用此程序使用的外设。
SysCtlPeripheralEnable (SYSCTL_Periph_PWM1);
while (!SysCtlPeripheralReady (SYSCTL_Periph_PWM1));
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
GPIOPinTypePWM (GPIO_PORTF_BASE、GPIO_PIN_3);//将 PF3引脚配置为 PWM
GPIOPinConfigure (GPIO_PF3_M1PWM7);
SysCtlPWMClockSet (SYSCTL_PWMDIV_64);// 40/64=0.625MHz,625KHz
PWMDeadBandDisable (PWM1_base、PWM_GEN_3);
PWMGenConfigure (PWM1_base、PWM_GEN_3、PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);//配置 PWM 选项
uint32_t PWMPeriod=1250;//PWM_GEN_2涵盖 M1PWM4和 M1PWM5
PWMGenPeriodSet (PWM1_base、PWM_GEN_3、PWMPeriod);//PWM_GEN_3涵盖 M1PWM6和 M1PWM7
PWMOutputState (PWM1_base、PWM_OUT_7_BIT、true);//打开输出引脚
PWMGenEnable (PWM1_base、PWM_GEN_3);//启用 PWM 发生器
}