|
1.位置检测,计算过程中的变量的定义
/*--------------------------------------------------------------------
Define the structure of the QEP (Quadrature Encoder) Driver Object
-----------------------------------------------------------------------------*/
typedef struct {int16 ElecTheta; // Output: Motor Electrical angle (Q15)
//(输出的电角度?)
int16 MechTheta; // Output: Motor Mechanical Angle (Q15)
//(输出的机械角度?)
Uint16 DirectionQep; // Output: Motor rotation direction (Q0)
//(电机转向?)
Uint16 QepCountIndex; // Variable: Encoder counter index (Q0)
//(编码器输出的脉冲数?)
Uint16 RawTheta; // Variable: Raw angle from Timer 2 (Q0)
//(某一时刻转子对于定子A相的绝对角度?)
Uint32 MechScaler; // Parameter: 0.9999/total count (Q30)
//(每个脉冲所转过的机械角度?)
Uint16 LineEncoder; // Parameter: Number of line encoder (Q0)
//(编码器每转输出的脉冲个数?)
Uint16 PolePairs; // Parameter: Number of pole pairs (Q0)
//(极对数)
int16 CalibratedAngle; // Parameter: Raw angular offset between encoder //index and phase a (Q0)
//翻译过来是编码器与定子A相之间的角度偏量,//但不知道到底这个偏移量是指什么,请教高人
Uint16 IndexSyncFlag; // Output: Index sync status (Q0) (?)
void (*init)(); // Pointer to the init function
//(初始化函数)
void (*calc)(); // Pointer to the calc function
//(位置测量,计算函数)
void (*isr)(); // Pointer to the isr function
//(Z信号的捕获中断)
} QEP;
上面的汉语解释不知道对不对,请高人过目,指出问题。
2、变量的初始化
#define QEP_DEFAULTS { 0x0, 0x0,0x0,0x0,0x0,0x00020C4A,0x0,4,-1250,0x0, \
(void (*)(Uint32))F281X_EV1_QEP_Init, \
(void (*)(Uint32))F281X_EV1_QEP_Calc, \
(void (*)(Uint32))F281X_EV1_QEP_Isr }
QEP qep1 = QEP_DEFAULTS;
// Applied-motion PMSM motor: 24-v, 8-pole, 2000 line encoder, CalibratedAngle = -1250
// MechScaler = 1/8000 = 0x00020C4A (Q30)
主程序里还有QEP模块的初始化,与上面的初始化有一点点重复的地方。
// Initialize QEP module
qep1.LineEncoder = 2000;
qep1.MechScaler = _IQ30(0.25/qep1.LineEncoder);
qep1.PolePairs = P/2;
qep1.CalibratedAngle = -1250;
qep1.init(&qep1);
此处要请教高手指导的问题就是:CalibratedAngle到底是什么东西?
3、功能模块程序
3、1 在进行正交编码,捕获Z之前对2812的寄存器进行初始化,设置定时器2为QEP电路提供基准时钟
void F281X_EV1_QEP_Init(QEP *p)
{
EvaRegs.CAPCONA.all = 0X9004; // Set up capture units
EvaRegs.T2CON.all = 0X9870; // Set up capture timer
EvaRegs.T2PR = 4*p->LineEncoder; // Init Timer 1 period Register
EvaRegs.EVAIFRC.bit.CAP3INT = 1; // Clear CAP3 flag
EvaRegs.EVAIMRC.bit.CAP3INT = 1; // Enable CAP3 Interrupt
EALLOW; // Enable EALLOW
GpioMuxRegs.GPAMUX.all |= 0x0700; // Set up the capture pins to primary functions
EDIS; // Disable EALLOW
}
此处要请教高手问题就是:EvaRegs.T2PR = 4*p->LineEncoder,根据上面初始化的定义,4*2000=8000个脉冲对应的就应该是一个360度的机械角度,也就该是一个定时周期,此时一个周期计算完毕,超过360度的角度就从新开始?假如此时的角度是200度,是不是对应的脉冲数就该是8000*200/360=4444个脉冲?
3、2
void F281X_EV1_QEP_Calc(QEP *p)
{
int32 Tmp;
// Check the rotational direction
p->DirectionQep = 0x4000&EvaRegs.GPTCONA.all;
//(GPTCONA的第14位为定时器2的状态,只读,如果是递增记数就是电机正转,递减就是电机反转?和4000相与就是为了只保留第14位信号?)
p->DirectionQep = p->DirectionQep>>14;
//得到电机的转向,是0是1就知道是正转还是反转?
// Check the timer 2 counter for QEP
p->RawTheta = EvaRegs.T2CNT + p->CalibratedAngle;
//按照定义RawTheta为转子即时的位置对应的脉冲,那就应该是转子对应定子A相的初始位置的角度+转过的相对角度,在TI的例程里定义
//的转子对应定子A相的初始位置的角度为0吗?如果是那此处就应该是p->RawTheta = EvaRegs.T2CNT+0。为何有CalibratedAngle?
// Compute the mechanical angle in Q15
Tmp = __qmpy32by16(p->MechScaler,p->RawTheta,31); // Q15 = Q30*Q0
p->MechTheta = (int16)(Tmp); // Q15 -> Q15
p->MechTheta &= 0x7FFF; // Wrap around 0x07FFF
//__qmpy32by16()我好象没找到是什么含义,理解起来应该是p->MechScaler*p->RawTheta,再转换格式对吧?能否请高人说下
//p->MechTheta 为何要和0x7FFF相与?按我的理解,TMP已经计算得到了即时的机械角
//度,消除第0到11位,保留高位的15为,这样不仅对整个角度的大小没有大的影响,并//且转换成了Q15格式,而Q15格式里,7FFF最大,代表360度,也代表的是1,相与是
//是为了将大于360度的角度转换过来。此处我还是不大清楚。烦请高人解释下下。
// Compute the electrical angle in Q15
p->ElecTheta = p->PolePairs*p->MechTheta; // Q0*Q15 = Q15
//计算电角度,电角度=极对数*机械角度
p->ElecTheta &= 0x7FFF; // Wrap around 0x07FFF
}
void F281X_EV1_QEP_Isr(QEP *p)
{
p->QepCountIndex = EvaRegs.T2CNT; // Get the timer 2 counter for one mechanical revolution
EvaRegs.T2CNT = 0; // Reset the timer 2 counter
p->IndexSyncFlag = 0x00F0; // Set the index flag
// p->IndexSyncFlag是个什么信号?
}
按照道理,PMSM应该有个初始定位的过程,采用最简单的6个区的定位,也就是针对编码器发出的UVW信号判断在哪个60度的区,然后再给定角度完事,这段程序应该放在主程序里系统初始化之后吧?假设此时UVW信号为101,这时候转子在第一个区,也就是0-60度范围之内,那么就设定转子在相对于定子A相30度的地方,这样做有最大30度的误差,会导致电机可能不会以最大转矩启动,但启动是没问题。
此时是不是应该把这些角度转换为脉冲个数,送给EvaRegs.T2CNT做为初始角度去计算?
//转子初始定位
if(GpioDataRegs.GPADAT.bit.GPIOA8==1&&GpioDataRegs.GPADAT.bit.GPIOA9==0&&GpioDataRegs.GPADAT.bit.GPIOA10==1)
InitAngle=30度;
if(GpioDataRegs.GPADAT.bit.GPIOA8==1&&GpioDataRegs.GPADAT.bit.GPIOA9==0&&GpioDataRegs.GPADAT.bit.GPIOA10==0)
InitAngle=90;
if(GpioDataRegs.GPADAT.bit.GPIOA8==1&&GpioDataRegs.GPADAT.bit.GPIOA9==1&&GpioDataRegs.GPADAT.bit.GPIOA10==0)
InitAngle=150;
if(GpioDataRegs.GPADAT.bit.GPIOA8==0&&GpioDataRegs.GPADAT.bit.GPIOA9==1&&GpioDataRegs.GPADAT.bit.GPIOA10==0)
InitAngle=210;
if(GpioDataRegs.GPADAT.bit.GPIOA8==0&&GpioDataRegs.GPADAT.bit.GPIOA9==1&&GpioDataRegs.GPADAT.bit.GPIOA10==1)
InitAngle=270;
if(GpioDataRegs.GPADAT.bit.GPIOA8==0&&GpioDataRegs.GPADAT.bit.GPIOA9==0&&GpioDataRegs.GPADAT.bit.GPIOA10==1)
InitAngle=330; |
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|