This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/EK-TM4C123GXL:速度控制

Guru**** 2465890 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/663599/ccs-ek-tm4c123gxl-velocity-control

器件型号:EK-TM4C123GXL

工具/软件: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 发生器

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    *抱歉
    uint32_t InterruptPeriod = SysCtlClockGet ()* 0.001;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Awais、

    虽然我理解手头的问题、但我并不清楚我们可以在哪些方面提供很多建议。 是否有一些 TM4C 操作、TivaWare API 或其他特定于 TM4C 的问题需要我们帮助解决? 现在、这似乎更多地是应用实现、并且在从 TI 端获得支持方面超出了我们的范围

    此外、如果您提供有关所使用的电机以及如何尝试使其稳定以及遇到的问题的更多详细信息、 这也会让我们的一些社区成员更好地理解、也许其中一位成员能够通过分享自己的经验来帮助您。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    THnx Ralph、我同意其 PID 应用于控制直流电机的速度。
    我遇到的问题是,通过使用上面的代码,电机速度变化非常快,我的意思是,如果我给它一些所需的速度,它会快速旋转,然后减速(或停止),然后再次过冲到快速,我无法将它稳定在所需的速度。
    因此、如果任何人可以指出代码中是否有问题或是否有其他方法来执行所需的任务、那将会很好。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将"差分项"添加到任何"PID"代码始终是一项艰巨的任务。

    在我们的通用技术设计业务的前三位、公司/我将此类"电机控制"排在前面-我们(和其他人)通常/习惯上只会在我们达到"满足/超出规格性能"之后、才会"引入差分术语"、同时采用"PI"术语和控制操纵方式-仅限!

    "D"这个词特别有说服力-如果其他词(P & I)没有得到很好的应用和实施-您的成功机会很小...

    这证明了(又一个) "亲吻"的力量-通过识别 和"可衡量地解决"先前发生的更轻松的挑战、朝着最终成功迈进。

    您在以下方面的写作没有提及:

    • 施加到电机的"负载"
    • 您的功率级-满足电机要求的能力
    • 您的编程、应用负载和功率级-确保您的电机在其运行的所有阶段"保持在其额定规格内"...

     早期定义之一显示: "#define PERIOD_PWM 1250// 2ms 时间段等于1250个周期"...  这表明"F_PWM"为625KHz -这是故意的吗?   如果是-您是如何到达的?

    您的理由和设计选择均未公开。   缺少此类数据会使问题的解决变得复杂和延迟。   如果在"可疑情况"中使用"D"术语-"独立"、我会(非常)感到惊讶。

    KISS 当然会迫使您注意这些领域中的每一个-通过"快速结论"(我们很少发现)得出(正确的)结论...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是、但在我的情况下、微分项始终为零(之前的误差始终等于电流误差、因此存在零差)。
    我也不确定这里的算法对于速度的 PID 控制是正确的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们的帖子已交叉-请阅读详细帖子。

    再次强调-我强烈建议您删除对差分控制项的任何/所有引用。 有许多问题需要回答。 当然、您可以找到多个"PID"(理想情况下)、只需"PI"代码示例...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、我将删除导数项、对于测试操作、我不对电机施加任何负载、它是唯一的转子惯性、是的、一切都在额定规格范围内、我的功率级可以轻松满足电机要求。
    Thnx 以获取您的回复帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请注意、运行您的电机(空载)是"超出"正常运行条件-而(您声称)"所有规格都得到满足"-在"现实世界/实际负载"条件下、情况发生了有力且快速的变化-并且您的程序代码必须准备好"扩展以满足这些"更困难/更苛刻、更真实世界"的条件。

    我会在功率级和电机周围添加一个"独立速度监控器(转速计)、电流监控器和温度传感器"。 事实上、您的 MCU 可以"履行这些角色"、而安全和适当的亲吻程序则指示"独立测量"是最好的、并且很可能会"加快、简化和增强"您的项目的成功。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    (电机转速以不稳定的方式波动)是增益过大的迹象。 这可以通过降低系统中的增益来解决....

    清除您的控制理论教科书所需的时间。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Danny F"]清除您的控制理论教科书的时间。

    呃…  也许"去除了"揭示了" 纽约公共图书馆的财产" (非常暗-但仍然清晰可辨)...

    大家都知道、"金钱也有"速度因素"、还有一本30 (美元)的书"太早了"、这真的需要"大量负面反馈!"   (当然、将逾期费用减至以下!)