[问答] 利用DSP2812编写直流电机PID调速程序(C语言)

[复制链接]

等待验证会员

发表于 2017-9-6 21:27:11   302 查看 13 回复 显示全部楼层 倒序浏览
分享
本人现在已经通过DSP2812中SCIA接收上位机发送的数据来控制电机的转速,采用CAP3来捕获光电编码器来测量电机的转速,现在想在程序里面添加PID调节电机的转速,主要通过PID输出调整PWM波形的占空比来调节电机的转速,请各位大神赐教
奖励3积分

实习生

发表于 2017-9-6 23:55:57  
赞赞赞赞赞赞赞赞赞赞
回复

点赞 举报

实习生

发表于 2017-9-7 16:26:13  

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
回帖是美德!
回复

点赞 举报

技术员

发表于 2017-9-11 12:04:07  
看楼主所说,现在是由上位机来控制电机转速,现在是想加入PID来实现电机转速的调速。楼主可以先将上位机发送给DSP的数据作为电机转速的目标值,由CAP采集回来的编码器的值作为当前的电机转速值,然后通过标准PID公式进行控制即可(PID这一块可以在网上查点资料了解一下)。祝楼主能够顺利实现串口+PID电机控制!
回复

点赞 举报

技术员

发表于 2017-9-11 21:38:01  
请联系我,数字增量式PID调节,PWM输出
回复

点赞 举报

等待验证会员

发表于 2017-9-12 10:42:56    楼主|
1406093611 发表于 2017-9-11 12:04
看楼主所说,现在是由上位机来控制电机转速,现在是想加入PID来实现电机转速的调速。楼主可以先将上位机发送给DSP的数据作为电机转速的目标值,由CAP采集回来的编码器的值作为当前的电机转速值,然后通过标准PID公式进行控制即可(PID这一块可以在网上查点资料了解一下)。祝楼主能够顺利实现串口+PID电机控制! ...

你好,我已经实现了上位机发送数据控制电机转速,并CAP捕获光电编码器的值计算电机转速,但是我不晓得该把PID程序放在什么位置,什么时候进行调速,可否指导一下
回复

点赞 举报

技术员

发表于 2017-9-12 11:32:40  
MMMEEELLL 发表于 2017-9-12 10:42
你好,我已经实现了上位机发送数据控制电机转速,并CAP捕获光电编码器的值计算电机转速,但是我不晓得该把PID程序放在什么位置,什么时候进行调速,可否指导一下

你可以单独建一个PID源文件,PID主要用于反馈回来的电机实际转速的参数进行矫正,比如在这里,DSP从上位机接收到了电机转速的目标值,而实际的转速值与设定的目标值不一致,就可以通过PID控制让实际转速达到目标值。PID程序放在哪里不重要,重要的是你要调用PID的子程序来实现参数的控制,将PID处理过的数据,转变为控制电机的实际转速值,去主程序执行就可以了。
回复

点赞 举报

等待验证会员

发表于 2017-9-12 15:47:42    楼主|
1406093611 发表于 2017-9-12 11:32
你可以单独建一个PID源文件,PID主要用于反馈回来的电机实际转速的参数进行矫正,比如在这里,DSP从上位机接收到了电机转速的目标值,而实际的转速值与设定的目标值不一致,就可以通过PID控制让实际转速达到目标值。PID程序放在哪里不重要,重要的是你要调用PID的子程序来实现参数的控制,将PID处理过的数据,转变为控制 ...

可以加我QQ:1159461528,跟你请教一下嘛?
回复

点赞 举报

等待验证会员

发表于 2017-9-12 20:47:56    楼主|
1406093611 发表于 2017-9-12 11:32
你可以单独建一个PID源文件,PID主要用于反馈回来的电机实际转速的参数进行矫正,比如在这里,DSP从上位机接收到了电机转速的目标值,而实际的转速值与设定的目标值不一致,就可以通过PID控制让实际转速达到目标值。PID程序放在哪里不重要,重要的是你要调用PID的子程序来实现参数的控制,将PID处理过的数据,转变为控制 ...

你好,想向你请教一下,PID的输出与PWM占空比的关系,如果用PID的输出调节PWM占空比是不是就把PID的输出直接加到PWM占空比上,还是要经过一定的比例关系再加到PWM占空比上?
回复

点赞 举报

技术员

发表于 2017-9-13 11:46:12  
MMMEEELLL 发表于 2017-9-12 20:47
你好,想向你请教一下,PID的输出与PWM占空比的关系,如果用PID的输出调节PWM占空比是不是就把PID的输出直接加到PWM占空比上,还是要经过一定的比例关系再加到PWM占空比上?

你好,由于白天上班,所以QQ不好回复,请谅解。
PID和PWM的关系是这样的:PID和PWM是独立的,但是PID可以影响PWM占空比的输出,也就是说,PID调整后会产生一个值,那么这个值是一个参考值,你在程序用的时候是需要判断这个参考值在什么范围内,然后在相应的范围内再给出对应的PWM占空比,这是一种PID与PWM的处理方式。

PID就是(比例+积分+微分)P+I+D,实际使用中可以是PI控制,也可以是PD控制,也可以是PID控制,需要根据实际情况做相应的调整。

楼主现在应该分清楚PID只是一种算法,它服务于其他控制类函数,比如就是PWM控制。

给楼主总结一下:1、PID和PWM是独立的个体,不是把PID的处理后的调整值直接作为PWM的占空比,除非你用PID处理后的值是整数并且在PWM占空比精度范围内,那就直接作为PWM占空比是可以的。2、PID处理就包括了比例、积分、微分,是将实际值进行比例积分微分运算后去快速地尽可能地稳定在设定值附近。
回复

点赞 举报

实习生

发表于 7 天前  
这应该挺简单的吧。。。。。PID主要是在固定的时间内,通过负反馈调节当前输出,即目标速度=当前速度+增量;即可达到直流电机线性输出的效果。光编当前速度你已经有了,目标速度有了,解决增量问题需要调节比例、积分、微分值就可以实现了。附上贴,原理一样的,如果适用,麻烦点一下标准答案,谢谢【教程】如何在STM32上实现增量式PID转
http://bbs.elecfans.com/jishu_484125_1_1.html
(出处: 中国电子技术论坛)
回复

点赞 举报

实习生

发表于 7 天前  
对了,关于什么时候调节的问题,可以做一个100MS的定时器,定时器去读出速度,然后进行PID调节,编码器测速也很好做,用M/T法测速直接就可以用了
回复

点赞 举报

等待验证会员

发表于 7 天前    楼主|
1406093611 发表于 2017-9-13 11:46
你好,由于白天上班,所以QQ不好回复,请谅解。
PID和PWM的关系是这样的:PID和PWM是独立的,但是PID可以影响PWM占空比的输出,也就是说,PID调整后会产生一个值,那么这个值是一个参考值,你在程序用的时候是需要判断这个参考值在什么范围内,然后在相应的范围内再给出对应的PWM占空比,这是一种PID与PWM的处理方式。

//主函数
void main(void)
{
        InitSysCtrl();
        DINT;
        IER=0x0000;
        IFR=0x0000;
        InitPieCtrl();
        InitPieVectTable();
        InitCpuTimers();
        InitGpio();
        InitEv();
        InitSci();
        InitPeripherals();
        //变量初始化

        Speedlimit=10;
        OutMax=Speedlimit;
        OutMin=-Speedlimit;
        n1=0;

        for(i=0;i<6;i++)
        {
                Scia_VarRx=0;
        }
        i=0;
        for(j=0;j<200;j++)
        {
                n[j]=0;
        }
        j=0;
    freq=0;
    temp1=temp2=0;
        Ref=Fdb=0;
        Kp=2;
        Ki=1.5;
        Kd=0;
        T=0.005;
        a0=a1=a2=0;
        Err=Err_1=Err_2=0;
        Out=Out_1=0;
    t1cmpr=0;
    kb=hd=de=un=d1=d2=D=0;
    cap1=cap2=0;
    capint3=t2pint=t1pint=0;
    T1=T2=0;
    k=0;
    duty=D=pwm_duty=0;
    pwm=0;
    EvaRegs.T1CMPR=0;

    //中断使能模块
    PieCtrl.PIEIER9.bit.INTx1=1;
        PieCtrl.PIEIER3.bit.INTx1=1;
        PieCtrl.PIEIER3.bit.INTx7=1;
        PieCtrl.PIEIER2.bit.INTx4=1;

    //开CPU中断
    IER|=M_INT9;
        IER|=M_INT3;
        IER|=M_INT2;

    //开全局中断,开实时中断
    EINT;
    ERTM;
        EvaRegs.T1CON.bit.TENABLE=1;
        EvaRegs.CAPCON.bit.CAP3EN=1;


    for(;;)
    {

    }
       
}




interrupt void SCIRXINTA_ISR(void)     // SCI-A接收中断函数
{
          Scia_VarRx=SciaRegs.SCIRXBUF.all;
          if(Scia_VarRx==48)
          {
          Scia_VarRx=0;
          }
          if(Scia_VarRx==49)
          {
          Scia_VarRx=1;
          }
          if(Scia_VarRx==50)
          {
          Scia_VarRx=2;
          }
            if(Scia_VarRx==51)
          {
          Scia_VarRx=3;
          }
            if(Scia_VarRx==52)
          {
          Scia_VarRx=4;
          }
            if(Scia_VarRx==53)
          {
          Scia_VarRx=5;
          }
            if(Scia_VarRx==54)
          {
          Scia_VarRx=6;
          }
            if(Scia_VarRx==55)
          {
          Scia_VarRx=7;
          }
            if(Scia_VarRx==56)
          {
          Scia_VarRx=8;
          }
            if(Scia_VarRx==57)
          {
          Scia_VarRx=9;
          }

          kb=Scia_VarRx[0]*1000;
          hd=Scia_VarRx[1]*100;
          de=Scia_VarRx[2]*10;
          un=Scia_VarRx[3];
          d1=Scia_VarRx[4];
          d2=Scia_VarRx[5];
          D=kb+hd+de+un;
          pwm_duty=0;

          i++;
          if(i==6)
            {

              i=0;

             }


          EALLOW;
          GpioDataRegs.GPADAT.bit.GPIOA0=d1;        //通过串口助手发送的数据来改变PWM1引脚的高低
          GpioDataRegs.GPADAT.bit.GPIOA1=d2;        //通过串口助手发送的数据来改变PWM1引脚的高低
          EDIS;

          PieCtrl.PIEACK.bit.ACK9=1;

      EINT;
}


interrupt void CAPINT3_ISR(void)
{

        capint3++;

        if(capint3==1)
        {
                EvaRegs.T2CON.bit.TENABLE=1;
                cap1=EvaRegs.T2CNT;
                T1=t2pint;

        }

        if(capint3==2)
        {

                cap2=EvaRegs.T2CNT;
                T2=t2pint;
                temp1=cap2+(T2-T1)*65535-cap1;
                freq=300000;
                n1=freq/(float)temp1;

                for(j=0;j<200;j++)
                {
                        n[j]=n1;
                }

                t2pint=0;
                T1=T2=0;
                capint3=0;
                EvaRegs.T2CNT=0;
                EvaRegs.T2CON.bit.TENABLE=0;

        }

        EvaRegs.EVAIFRC.bit.CAP3INT=1;
        EvaRegs.EVAIMRC.bit.CAP3INT=1;
        PieCtrl.PIEACK.bit.ACK3=1;
}

interrupt void T2PINT_ISR(void)
{

   t2pint++;
   EvaRegs.EVAIFRB.bit.T2PINT=1;
   EvaRegs.EVAIMRB.bit.T2PINT=1;
   PieCtrl.PIEACK.bit.ACK3=1;

   EINT;
}


interrupt void T1PINT_ISR(void)    // 通用定时器T1的周期中断
{

        t1pint++;
        if(t1pint==100)       //达到5ms开始进行PID运算
            {

                Ref=D*10/1500;
                Fdb=n1;
                Err=Ref-Fdb;

                a0=Kp*(1+T/Ki+Kd/T);
                a1=Kp*(1+2*Kd/T);
                a2=Kp*Kd/T;
                Out=Out_1+a0*Err-a1*Err_1+a2*Err_2;

        pwm+=Out;   //增量
        duty=D+(int)pwm;      
     if(duty>1500)
     {
             t1cmpr=1500;
     }
     else
     {
             t1cmpr=duty;
     }
     EvaRegs.T1CMPR=t1cmpr;

            Out_1=Out;
            Err_2=Err_1;
            Err_1=Err;
            }

    EvaRegs.EVAIFRA.bit.T1PINT=1;
    EvaRegs.EVAIMRA.bit.T1PINT=1;
    PieCtrl.PIEACK.bit.ACK2=1;

    EINT;

}

上面是我自己编写的程序,测速采用的T法测速,请你帮忙看一下,谢谢
回复

点赞 举报

技术员

发表于 3 天前  
看看吧!看看吧!
回复

点赞 举报

高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

我的提问

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

DFRobot专区

树莓派论坛

智能硬件论坛

开发快智能硬件开发平台

Intel物联网开发者专区

Waveshare

乐美客SBC专区

Arduino论坛

BeagleBone论坛

机器人论坛

创客神器NanoPi

小钢炮CANNON

比派科技banana pi专区

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

个人版区

阿东Verilog技术专版

直流马达驱动电路设计

LabVIEW英雄联盟

特权同学FPGA专区

-

厂商专区

灵动微电子 MM32

盈鹏飞嵌入式

TI论坛

TI Deyisupport社区

芯灵思嵌入式论坛

Tisan

米尔科技

庆科社区

WIZnet技术专区

Cypress技术论坛

飞凌嵌入式

Qualcomm技术论坛

英创嵌入式

机智云GoKit论坛

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区