TI E2E™ 设计支持论坛将于 5 月 30 日至 6 月 1 日进行维护。如果您在此期间需要技术支持,请联系 TI 的客户支持中心寻求帮助。

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/TMS320F28379D:F28379 eQEP Pos-Speed 示例未注册索引

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/910790/ccs-tms320f28379d-f28379-eqep-pos-speed-example-not-registering-index

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

您好!

我的软件示例有问题:

eQEP_pos_speed_CPU1 (V210、但尝试使用不同版本)

 

我尝试使用该示例来使用 TI 2-MTR-DYNO 封装的编码器。 eQEP1A 和 eQEP1B 已正确注册、但是在任何情况下、QEP1I 都不会注册。 我尝试了:

-将 GPIO 引脚4连接到 EQEP1I 引脚以仿真索引脉冲

-将编码器直接连接到引脚接头

-将3.3V 电压直接连接到 EQEP1I 引脚以强制进行索引检测

这些似乎都不起作用、因此一旦 theta_raw 溢出、它就会产生一个错误的 theta_mech 生成、从而使编码器无用。

有关我的设置的信息:

- Code Composer 10.0

-编译器 TI v20.2.1.LTS

提前感谢您的帮助!

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

    您好、Rick、

    您是否将 GPIO4用作 EQEP1I? 如果您查看数据表、GPIO4没有连接到 eQEP Index 引脚。

    您可以将 GPIO13与多路复用器选项5结合使用。

    此致、

    Nirav

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

    Nirav、您好!

    我不使用 GPIO4作为 EqepI、而是从外部将其连接到 eqep1引脚接头的 eqep1I 引脚。 (示例中也建议这样)由于我尝试了不同的方法来创建索引脉冲(并使用示波器进行测量以验证是否生成了 DE 脉冲)、我假设该脉冲是由 DE 控制器记录的 NOG、但我不知道导致此情况的原因是什么。

    如果我列出负责处理中断的代码:

    //检查索引出现
    //
    if (EQep1Regs.QDLG.bit.IEL =1)
    {
    p->index_SYNC_FLAG = 0x00F0;
    EQep1Regs.QCLR.bit.IEL = 1;//清除__interrupt 标志
    } 

    当我在这个代码内放置一个断点时、即使一个外部索引脉冲被应用于 GPIO23、它也不会达到。 (也在 e2e.ti.com/.../634607 中讨论)

    更新:

    设置:


    我已经对 C2000Ware 示例进行了同样的尝试、它仍然无法检测到索引脉冲。 我已经使用示波器进行检查、EQEPI 引脚确实会接收到一个索引脉冲。 还有什么可以检查的吗?

    此致、

    Rick

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

    您好!

    当前工作范围 I 的实现方式是将 QPOSMAX 设置为4000、这与编码器的分辨率相同、但是、这不是一个合适的解决方案、因为它不使用索引信号来缓解任何计数错误。 我仍在尝试解决索引脉冲未注册的问题。 有关 GPIO 和 EqepRegs 设置的一些额外信息:(与更改最大 QPOSCNT 的示例相同)

    文件:F2837xD_eQEP.c (系统文件)
    void InitEQep1Gpio (void)
    {
    EALLOW;
    
    //
    //禁用所选输出引脚的内部上拉
    //以降低功耗
    //用户可以启用或禁用上拉。
    //注释掉其他不需要的行。
    
    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 1;//禁用 GPIO20上的上拉电阻(EQEP1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 1;//禁用 GPIO21上的上拉电阻(EQEP1B)
    GpioCtrlRegs.GPAPUD.bit.GPIO22 = 1;//禁用 GPIO22上的上拉电阻(EQEP1S)
    GpioCtrlRegs.GPAPUD.bit.GPIO23 = 1;//禁用 GPIO23上的上拉电阻(EQEP1I)
    
    //
    //将输入同步到 SYSCLK
    //同步可由用户启用或禁用。
    //注释掉其他不需要的行。
    //
    
    GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0;//将 GPIO20与 SYSCLK 同步(EQEP1A)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0;//将 GPIO21同步到 SYSCLK (EQEP1B)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0;//将 GPIO22同步到 SYSCLK (EQEP1S)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0;//将 GPIO23同步到 SYSCLK (EQEP1I)
    
    //
    //使用 GPIO 寄存器配置 eQEP-1引脚
    //这指定哪些可能的 GPIO 引脚将是 EQEP1功能
    //引脚。
    //注释掉其他不需要的行。
    //
    
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1;//将 GPIO20配置为 EQEP1A
    GpioCtrlRegs.GPAMUX2.bit.GPIO21=1;//将 GPIO21配置为 EQEP1B
    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1;//将 GPIO22配置为 EQEP1S
    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1;//将 GPIO23配置为 EQEP1I
    
    EDIS;
    }
    
    文件:posspeed_example (示例 c2000Ware)
    //
    // POSISPEED_Init -初始化 EQEP1配置
    //
    void Encoder_Init (void)
    {
    EQep1Regs.QUPRD = 2000000; //频率为200MHz 时频率为100Hz 的单位定时器
    // SYSCLKOUT
    EQep1Regs.QDECCTL.bit.QSRC = 00; // QEP 正交计数模式
    EQep1Regs.QEPCTL.bit.free_soft = 2;
    EQep1Regs.QEPCTL.bit.PCRM = 00; // PCRM=00模式- QPOSCNT 复位打开
    //索引事件
    EQep1Regs.QEPCTL.bit.UTE = 1; //设备超时启用
    EQep1Regs.QEPCTL.bit.QCLM = 1; //锁存装置超时
    EQep1Regs.QPOSMAX = 0xFA0;
    EQep1Regs.QEPCTL.bit.QPEN = 1; // QEP 使能
    EQep1Regs.QCAPCTL.bit.UPP=5; // 1/32表示单元位置
    EQep1Regs.QCAPCTL.bit.CCPS = 6; 对于 CAP 时钟、为//1/64
    EQep1Regs.QCAPCTL.bit.CEN = 1; // QEP 捕捉使能
    }
    
    //
    POSISPEED_CALC -执行位置计算
    //
    void Encoder_Update (EncoderState *p)
    {
    长温度;
    unsigned int pos16bval、temp1;
    _iq Tmp1、newp、oldp;
    
    //
    //位置计算-机械和电动机角度
    //
    P->DirectionQep = EQep1Regs.QEPSTS.bit.QDF;//电机方向:
    // 0 = CCV/反向,1 = CW/正向
    
    pos16bval =(unsigned int) EQep1Regs.QPOSCNT;//捕捉位置一次
    //每个 QA/QB 周期
    p->theta_raw = pos16bval+ p->cal_angle; //原始 θ=当前位置。 +
    //对。 来自 QA 的偏移
    
    if (p->theta_raw > 4000){
    p->theta_ray=p->theta_ray-4000;
    } 否则为(p->theta_raw <-4000){
    p->theta_ray=p->theta_ray+4000;
    }
    
    //
    //下面的行计算
    // p->theta_mech ~= QPOSCNT/mech_scaler [当前 cnt/(1修订版中的总 cnt)]
    //其中 mech_scaler = 4000 cnts/Revolution
    //
    tmp =(long)(((long) p->theta_ray*(long) p->mech_scaler);// q0*Q26 = Q26
    tmp &= 0x03FFF000;
    p->theta_mech =(int)(Tmp>>11); //Q26 -> Q15
    p->theta_mech &= 0x7FFF;
    
    p->th_rad =2*M_pi-((double) p->theta_mech/32765)*2*M_pi;
    p->th_deg =360-(((double) p->theta_mech/32765)*360;
    
    if (p->th_deg<0){
    p->th_deg=p->th_deg;
    }
    
    //
    //以下行计算 p->elec_mech
    //
    p->theta_elec = p->pole _pairs*p->theta_mech; // q0*q15 = q15
    p->theta_elec &= 0x7FFF;
    
    //
    //检查索引出现情况
    //
    if (EQep1Regs.QDL.bit.IEL = 1)
    {
    P->index_SYNC_FLAG = 0x00F0;
    EQep1Regs.QCLR.bit.IEL = 1;//清除__interrupt 标志
    }
    
    //
    //使用 QEP 位置计数器进行高速计算
    //
    //检查单位时间超时事件以计算速度:
    //初始化函数中的单位计时器配置为100Hz
    //
    if (EQep1Regs.QFLG.bit.UTO = 1)//如果单元超时(一个100Hz 周期)
    {
    //
    //微分器
    //
    //下面的行计算
    //位置=(x2-x1)/4000 (1转的位置)
    //
    pos16bval =(unsigned int) EQep1Regs.QPOSLAT;//锁定的 POSCNT 值
    tmp =(long)((long) pos16bval*(long) p->mech_scaler);// q0*Q26 = Q26
    tmp &= 0x03FFF000;
    tmp =(int)(Tmp>>11); //Q26 -> Q15
    tmp &= 0x7FFF;
    newp =_IQ15toIQ (tmp);
    oldp = p->oldp;
    
    if (p->DirectionQep=0) // POSCNT 正在递减计数
    {
    if (newp>oldp)
    {
    Tmp1 =-(_IQ (1)- newp + oldp);// x2-x1应该为负
    }
    其他
    {
    Tmp1 = newp -oldp;
    }
    }
    否则,如果(p->DirectionQep=1) // POSCNT 正在递增计数
    {
    if (newp _iq (1))
    {
    P->Speed_fr =_IQ(1);
    }
    否则、IF (Tmp1 <_IQ(-1))
            {
                p->speed_fr =_IQ (-1);
    }
    其他
    {
    P->Speed_fr = Tmp1;
    }
    
    //
    //更新电角
    //
    p->oldpos = newp;
    
    //
    //将电机转速从 pu 值更改为 rpm 值(Q15 -> Q0)
    // q0 = q0*global_Q =>_IQXmpy(),X = global_Q
    //
    p->SpeedRpm_fr =_IQmpy (p->BaseRpm、p->Speed_fr);
    
    EQep1Regs.QCLR.bit.UTO=1; //清除__interrupt 标志
    }
    
    //
    //使用 QEP 捕捉计数器进行低速计算
    //
    if (EQep1Regs.QEPSTS.bit.UPEVNT = 1) //单位位置事件
    {
    if (EQep1Regs.QEPSTS.bit.COEF = 0) //没有捕捉溢出
    {
    TEMP1 =(无符号长整型) EQep1Regs.QCPRDLAT;// temp1 = T2-T1
    }
    否则//捕获溢出,使结果饱和
    {
    TEMP1 = 0xFFFF;
    }
    
    //
    // p->Speed_pr = p->SpeedScaler/temp1
    //
    P->Speed_pr =_IQdiv (p->SpeedScaler, temp1);
    Tmp1 = p->Speed_pr;
    
    IF (Tmp1>_IQ (1))
    {
    P->Speed_pr =_IQ(1);
    }
    其他
    {
    P->Speed_pr = Tmp1;
    }
    
    //
    //将 p->Speed_pr 转换为 RPM
    //
    if (p->DirectionQep =0)//反向=负
    {
    //
    // q0 = q0*global_Q =>_IQXmpy(),X = global_Q
    //
    P->SpeedRPM_pr =-_IQmpy (p->BaseRpm、p->Speed_pr);
    }
    其他 //正向=正
    {
    //
    // q0 = q0*global_Q =>_IQXmpy(),X = global_Q
    //
    P->SpeedRPM_pr =_IQmpy (p->BaseRpm、p->Speed_pr);
    }
    
    EQep1Regs.QEPSTS.ALL = 0x88;//清除单元位置事件标志
    //清除溢出错误标志
    }
    } 

    此致、

    Rick

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

    您好、Rick、

    对延迟回复表示歉意。 您的所有配置看起来都很好、因此我尝试弄清您为什么看不到索引脉冲。 最后、我想我可能已经发现了问题。  

    由于您使用的是 Launchpad、因此必须将 QEP 信号连接到接头 J14 (eQEP1A、eQEP1B 和 eQEP1I)。 如果您浏览 Launchpad 的原理图、您会发现 eQEP1A 和 eQEP1B 分别连接到 GPIO20和 GPIO21、但 eQEP1I 连接到 GPIO99 (而非 GPIO23)。 因此、在您的代码中、您需要使用多路复用器选项5设置 GPIO99。

    请尝试一下、如果您仍遇到任何问题、请告诉我。

     此致、

    Nirav

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

    Nirav、您好!

    这确实解决了问题! 谢谢! 下次我一定要仔细检查 Launchpad 的原理图!

    此致、

    Rick