有没有对ti的EQEP模块非常熟悉的

2019-03-24 09:11发布

本帖最后由 张锋 于 2016-7-12 11:19 编辑

我照着例程写了一段程序测电机转速,但就是测的不对,大神帮我看一下@maychang @dontium
  1. /*-----------------------------------------------------------------------------
  2. Default initializer for the POSSPEED Object.!! mech_scaler = 16384 (Q26格式) 1024线程
  3. -----------------------------------------------------------------------------*/
  4.   #define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16384,2,0,0x0,
  5.         220,0,3000,0,
  6.         0,0,0,
  7.         (void (*)(long))POSSPEED_Init,
  8.         (void (*)(long))POSSPEED_Calc }

  9. void  POSSPEED_Init(void)
  10. {

  11.     EQep1Regs.QUPRD=1800000;         // Unit Timer for 50Hz at 90 MHz SYSCLKOUT

  12.     EQep1Regs.QDECCTL.bit.QSRC=00;      // QEP quadrature count mode

  13.     EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
  14.     EQep1Regs.QEPCTL.bit.PCRM=00;       // PCRM=00 mode - QPOSCNT reset on index event
  15.     EQep1Regs.QEPCTL.bit.UTE=1;         // Unit Timeout Enable
  16.     EQep1Regs.QEPCTL.bit.QCLM=1;        // Latch on unit time out
  17.     EQep1Regs.QPOSMAX=0xffffffff;
  18.     EQep1Regs.QEPCTL.bit.QPEN=1;        // QEP enable

  19.     EQep1Regs.QCAPCTL.bit.UPPS=5;       // 1/32 for unit position
  20.     EQep1Regs.QCAPCTL.bit.CCPS=6;       // 1/64 for CAP clock
  21.     EQep1Regs.QCAPCTL.bit.CEN=1;        // QEP Capture Enable

  22. }

复制代码
  1. void POSSPEED_Calc(POSSPEED *p)
  2. {
  3.      long tmp;
  4.      unsigned int pos16bval,temp1;
  5.      _iq Tmp1,newp,oldp;

  6. //**** Position calculation - mechanical and electrical motor angle  ****//
  7.      p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF;    // Motor direction: 0=CCW/reverse, 1=CW/forward

  8.      pos16bval=(unsigned int)EQep1Regs.QPOSCNT;     // capture position once per QA/QB period
  9.      p->theta_raw = pos16bval+ p->cal_angle;        // raw theta = current pos. + ang. offset from QA

  10.      // The following lines calculate p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]
  11.      // where mech_scaler = 4000 cnts/revolution
  12.      tmp = (long)((long)p->theta_raw*(long)p->mech_scaler);     // Q0*Q26 = Q26
  13.      tmp &= 0x03FFF000;
  14.      p->theta_mech = (int)(tmp>>11);                // Q26 -> Q15
  15.      p->theta_mech &= 0x7FFF;

  16.      // The following lines calculate p->elec_mech
  17.      p->theta_elec = p->pole_pairs*p->theta_mech;  // Q0*Q15 = Q15
  18.      p->theta_elec &= 0x7FFF;

  19. // Check an index occurrence
  20.      if (EQep1Regs.QFLG.bit.IEL == 1)
  21.      {
  22.         p->index_sync_flag = 0x00F0;
  23.         EQep1Regs.QCLR.bit.IEL=1;                   // Clear interrupt flag
  24.      }

  25. //**** High Speed Calcultation using QEP Position counter ****//
  26. // Check unit Time out-event for speed calculation:
  27. // Unit Timer is configured for 100Hz in INIT function

  28.     if(EQep1Regs.QFLG.bit.UTO==1)                    // If unit timeout (one 100Hz period)
  29.     {
  30.         /** Differentiator  **/
  31.         // The following lines calculate position = (x2-x1)/4000 (position in 1 revolution)
  32.         pos16bval=(unsigned int)EQep1Regs.QPOSLAT;                // Latched POSCNT value
  33.         tmp = (long)((long)pos16bval*(long)p->mech_scaler);       // Q0*Q26 = Q26
  34.         tmp &= 0x03FFF000;
  35.         tmp = (int)(tmp>>11);                                     // Q26 -> Q15
  36.         tmp &= 0x7FFF;
  37.         newp=_IQ15toIQ(tmp);
  38.         oldp=p->oldpos;

  39.         if (p->DirectionQep==0)                     // POSCNT is counting down
  40.         {
  41.             if (newp>oldp)
  42.                 Tmp1 = - (_IQ(1) - newp + oldp);    // x2-x1 should be negative
  43.             else
  44.             Tmp1 = newp -oldp;
  45.         }
  46.         else if (p->DirectionQep==1)                // POSCNT is counting up
  47.         {
  48.             if (newp<oldp)
  49.             Tmp1 = _IQ(1) + newp - oldp;
  50.             else
  51.             Tmp1 = newp - oldp;                     // x2-x1 should be positive
  52.         }

  53.         if (Tmp1>_IQ(1))
  54.             p->Speed_fr = _IQ(1);
  55.         else if (Tmp1<_IQ(-1))
  56.             p->Speed_fr = _IQ(-1);
  57.         else
  58.             p->Speed_fr = Tmp1;

  59.         // Update the electrical angle
  60.         p->oldpos = newp;

  61.         // Change motor speed from pu value to rpm value (Q15 -> Q0)
  62.         // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
  63.         p->SpeedRpm_fr = _IQmpy(p->BaseRpm,p->Speed_fr);
  64.         //=======================================

  65.         EQep1Regs.QCLR.bit.UTO=1;                   // Clear interrupt flag
  66.     }

  67. //**** Low-speed computation using QEP capture counter ****//
  68.     if(EQep1Regs.QEPSTS.bit.UPEVNT==1)                 // Unit position event
  69.     {
  70.         if(EQep1Regs.QEPSTS.bit.COEF==0)               // No Capture overflow
  71.             temp1=(unsigned long)EQep1Regs.QCPRDLAT;   // temp1 = t2-t1
  72.         else                                           // Capture overflow, saturate the result
  73.             temp1=0xFFFF;

  74.         p->Speed_pr = _IQdiv(p->SpeedScaler,temp1);    // p->Speed_pr = p->SpeedScaler/temp1
  75.         Tmp1=p->Speed_pr;

  76.         if (Tmp1>_IQ(1))
  77.             p->Speed_pr = _IQ(1);
  78.         else
  79.             p->Speed_pr = Tmp1;

  80.         // Convert p->Speed_pr to RPM
  81.         if (p->DirectionQep==0)                                 // Reverse direction = negative
  82.             p->SpeedRpm_pr = -_IQmpy(p->BaseRpm,p->Speed_pr);   // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
  83.         else                                                    // Forward direction = positive
  84.             p->SpeedRpm_pr = _IQmpy(p->BaseRpm,p->Speed_pr);    // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q

  85.         EQep1Regs.QEPSTS.all=0x88;                  // Clear Unit position event flag
  86.                                                     // Clear overflow error flag
  87.     }

  88. }
复制代码

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
dontium
1楼-- · 2019-03-24 10:53
< 楼主这样发帖可不妥啊。

发帖时把问题讲清楚。因为只有你手里有这个板子,电器连接也只有你知道。“ 但就是测的不对 ” 如果能具体一些就好了;程序具体哪出了问题?有没有跟踪一下?

你这样帖上来,就是要看者逐一分析每一句是否正常。帖的时候又把注释也夹在其中,说明帖出来时没有经过考虑。

人们解决问题时,也就是把硬件上的状态(参数)量一量,软件跑一跑看看寄存器及变量等。

我做过的QEP,基本上按照TI的设置方法设置,
张锋
2楼-- · 2019-03-24 11:34
< :TI_MSP430_内容页_SA7 --> 本帖最后由 张锋 于 2016-7-12 11:37 编辑
dontium 发表于 2016-7-12 10:27
楼主这样发帖可不妥啊。

发帖时把问题讲清楚。因为只有你手里有这个板子,电器连接也只有你知道。“ 但 ...

恩,我按照您说的只贴出来配置部分,您看一下,这样对不,
如果我只想测速,那么是不是只需要AB两根线就好了,那程序上还要修改吗?@dontium
dontium
3楼-- · 2019-03-24 16:35
 精彩回答 2  元偷偷看……
张锋
4楼-- · 2019-03-24 20:28
dontium 发表于 2016-7-12 18:18
使用QEP,我只做过具有鼠标中键的功能,其它的没搞过。

你的程序自己使用仿真器跟踪一下,看看有没有 ...

再问你个问题
a = _IQmpy(4500,(Duty+_IQ(0.5)));
这个式子算出来直接就是IQ0格式,这是为什么?
dontium
5楼-- · 2019-03-24 22:39
张锋 发表于 2016-7-13 10:22
再问你个问题
a = _IQmpy(4500,(Duty+_IQ(0.5)));
这个式子算出来直接就是IQ0格式,这是为什么?

我没有感觉到TI的IQ库的优势,所以就没有研究它。

一周热门 更多>

相关问题

    相关文章