8940|5

62

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

有没有对ti的EQEP模块非常熟悉的 [复制链接]

本帖最后由 张锋 于 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. }
复制代码


最新回复

我没有感觉到TI的IQ库的优势,所以就没有研究它。  详情 回复 发表于 2016-7-13 10:36
 
点赞 关注

回复
举报

1万

帖子

25

TA的资源

裸片初长成(高级)

推荐
 
楼主这样发帖可不妥啊。

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

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

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

我做过的QEP,基本上按照TI的设置方法设置,

点评

恩,我按照您说的只贴出来配置部分,您看一下,这样对不, 如果我只想测速,那么是不是只需要AB两根线就好了,那程序上还要修改吗?  详情 回复 发表于 2016-7-12 11:03
 
 

回复

62

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
本帖最后由 张锋 于 2016-7-12 11:37 编辑
dontium 发表于 2016-7-12 10:27
楼主这样发帖可不妥啊。

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

恩,我按照您说的只贴出来配置部分,您看一下,这样对不,
如果我只想测速,那么是不是只需要AB两根线就好了,那程序上还要修改吗?@dontium

点评

使用QEP,我只做过具有鼠标中键的功能,其它的没搞过。 你的程序自己使用仿真器跟踪一下,看看有没有达到自己的目的。 如果只测速,没有必须使用QEP了。使用QEP的A、B输入,可以判断方向及速度。  详情 回复 发表于 2016-7-12 18:18
 
 
 

回复

1万

帖子

25

TA的资源

裸片初长成(高级)

4
 
张锋 发表于 2016-7-12 11:03
恩,我按照您说的只贴出来配置部分,您看一下,这样对不,
如果我只想测速,那么是不是只需要AB两根线就 ...

使用QEP,我只做过具有鼠标中键的功能,其它的没搞过。

你的程序自己使用仿真器跟踪一下,看看有没有达到自己的目的。

如果只测速,没有必须使用QEP了。使用QEP的A、B输入,可以判断方向及速度。

点评

再问你个问题 a = _IQmpy(4500,(Duty+_IQ(0.5))); 这个式子算出来直接就是IQ0格式,这是为什么?  详情 回复 发表于 2016-7-13 10:22
 
 
 

回复

62

帖子

1

TA的资源

一粒金砂(中级)

5
 
dontium 发表于 2016-7-12 18:18
使用QEP,我只做过具有鼠标中键的功能,其它的没搞过。

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

再问你个问题
a = _IQmpy(4500,(Duty+_IQ(0.5)));
这个式子算出来直接就是IQ0格式,这是为什么?

点评

我没有感觉到TI的IQ库的优势,所以就没有研究它。  详情 回复 发表于 2016-7-13 10:36
 
 
 

回复

1万

帖子

25

TA的资源

裸片初长成(高级)

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

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

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表