/* =================================================================================
File name: F2803XQEP.H
Target : F2803x family
===================================================================================*/
#ifndef __F2803X_QEP_H__
#define __F2803X_QEP_H__
#include "f2803xbmsk.h"
#include "f2803xdrvlib.h"
/*-----------------------------------------------------------------------------
Initialization states for EQEP Decode Control Register
------------------------------------------------------------------------------*/
#define QDECCTL_INIT_STATE ( XCR_X2 + QSRC_QUAD_MODE ) //上升沿下降沿都计数,正交计数方式
/*-----------------------------------------------------------------------------
Initialization states for EQEP Control Register
------------------------------------------------------------------------------*/
#define QEPCTL_INIT_STATE ( QEP_EMULATION_FREE + \
PCRM_INDEX + \ //在索引事件发生时复位
IEI_RISING + \ //在QEPI上升沿初始化位置计数器
IEL_RISING + \ //在QEPI上升沿将QPOSCNT的值所存在QPOSILAT中
QPEN_ENABLE + \ //使能QEP位置计数器
QCLM_TIME_OUT + \ //在定时器基准单元超时事件时锁存
UTE_ENABLE ) //使能QEP定时器基准单元
/*-----------------------------------------------------------------------------
Initialization states for EQEP Position-Compare Control Register
------------------------------------------------------------------------------*/
#define QPOSCTL_INIT_STATE PCE_DISABLE //禁止位置比较寄存器映射功能
//在QPOSCNT=0时加载
//高电平脉冲输出
//禁止位置比较寄存器
//1*4*SYSCLKOUT周期
/*-----------------------------------------------------------------------------
Initialization states for EQEP Capture Control Register
------------------------------------------------------------------------------*/
#define QCAPCTL_INIT_STATE ( UPPS_X32 + \ //单元位置事件预分频 =QCLK/2^5
CCPS_X128 + \ //捕获单元定时器时钟预分频器 =SYSCLKOUT/2^7
CEN_ENABLE ) //使能捕获单元使能
/*-----------------------------------------------------------------------------
Define the structure of the QEP (Quadrature Encoder) Driver Object
-----------------------------------------------------------------------------*/
typedef struct {int32 ElecTheta; // Output: Motor Electrical angle 电机电角度(Q24)
int32 MechTheta; // Output: Motor Mechanical Angle 机械角度(Q24)
Uint16 DirectionQep; // Output: Motor rotation direction 电机旋转方向(Q0)
Uint16 QepPeriod; // Output: Capture period of QEP signal in number of EQEP capture timer (QCTMR) period EQEP 捕获定时器 (QCTMR) 期间 QEP 信号的捕获周期(Q0)
Uint32 QepCountIndex; // Variable: Encoder counter index (Q0)
int32 RawTheta; // Variable: Raw angle from EQEP Postiion counter初始定位后,电机转子d轴和定子A相绕组之间所相差的码盘计数值 (Q0)
Uint32 MechScaler; // Parameter: 0.9999/total count (Q30)
Uint16 LineEncoder; // Parameter: Number of line encoder (Q0)
Uint16 PolePairs; // Parameter: Number of pole pairs (Q0)
int32 CalibratedAngle; // Parameter: Raw angular offset between encoder index and phase a 电机A相绕组和码盘Index信号之间的夹角,与安装精度有关 (Q0)
Uint16 IndexSyncFlag; // Output: Index sync status (Q0)
} QEP;
/*-----------------------------------------------------------------------------
Default initializer for the QEP Object.
-----------------------------------------------------------------------------*/
#define QEP_DEFAULTS {
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x00020000,
0x0,
2,
0,
0x0
}
/*-----------------------------------------------------------------------------
QEP Init and QEP Update Macro Definitions
-----------------------------------------------------------------------------*/
#define QEP_INIT_MACRO(m,v) \
\
(*eQEP[m]).QDECCTL.all = QDECCTL_INIT_STATE; \
(*eQEP[m]).QEPCTL.all = QEPCTL_INIT_STATE; \
(*eQEP[m]).QPOSCTL.all = QPOSCTL_INIT_STATE; \
(*eQEP[m]).QUPRD = 600000; /* Unit Timer for 100Hz*/ \
(*eQEP[m]).QCAPCTL.all = QCAPCTL_INIT_STATE; \
(*eQEP[m]).QPOSMAX = 4*v.LineEncoder; \
//Make sure that the pin configuration is properly done in ...-DevInit_F2803x.c file like below
/* EALLOW; Enable EALLOW
GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; GPIO20 is EQEP1A
GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; GPIO21 is EQEP1B
GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; GPIO23 is EQEP1I
EDIS; Disable EALLOW
*/
#define QEP_MACRO(m,v) \
\
/* Check the rotational direction */ \
v.DirectionQep = (*eQEP[m]).QEPSTS.bit.QDF; /*0是顺时针,1是逆时针。*/ \
\
/* Check the position counter for EQEP1 */ \
v.RawTheta = (*eQEP[m]).QPOSCNT + v.CalibratedAngle; \
\
if (v.RawTheta < 0) \
v.RawTheta = v.RawTheta + (*eQEP[m]).QPOSMAX; \
else if (v.RawTheta > (*eQEP[m]).QPOSMAX) \
v.RawTheta = v.RawTheta - (*eQEP[m]).QPOSMAX; \
\
/* Compute the mechanical angle in Q24 */ \
v.MechTheta = __qmpy32by16(v.MechScaler,(int16)v.RawTheta,31); /* Q15 = Q30*Q0 */ \
v.MechTheta &= 0x7FFF; /* Wrap around 0x07FFF*/ \
v.MechTheta <<= 9; /* Q15 -> Q24 */ \
这三行程序怎么解读?
/* Compute the electrical angle in Q24 */ \
v.ElecTheta = v.PolePairs*v.MechTheta; /* Q24 = Q0*Q24 */ \
v.ElecTheta &= 0x00FFFFFF; /* Wrap around 0x00FFFFFF*/ \
还有这一行。
/* Check an index occurrence*/ \
if ((*eQEP[m]).Q**.bit.IEL == 1) \
{ \
v.IndexSyncFlag = 0x00F0; \ 这里产生的标志位有什么作用,只是通过外界看到吗。还是有了这个信号,脉冲计数器就清零了。
v.QepCountIndex = (*eQEP[m]).QPOSILAT; \
(*eQEP[m]).QCLR.bit.IEL = 1; /* Clear interrupt flag */ \
}
|