Other Parts Discussed in Thread: CONTROLSUITE
Hi there,
I'm using F28335 and setting up a 500 line/rev encoder for the QEP-module. I'm using an old TI-example header file for helping with the setup:
// TI File $Revision: /main/2 $
// Checkin $Date: July 30, 2009 18:44:51 $
//###########################################################################
//
// FILE: Example_posspeed.h
//
// TITLE: Pos/speed measurement using EQEP peripheral
//
// DESCRIPTION:
//
// Header file containing data type and object definitions and
// initializers.
//
//###########################################################################
// Original Author: SD
//
// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
// $Release Date: August 4, 2009 $
//###########################################################################
#ifndef __POSSPEED__
#define __POSSPEED__
#include "IQmathLib.h" // Include header for IQmath library
/*-----------------------------------------------------------------------------
Define the structure of the POSSPEED Object
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec; // Output: Motor Electrical angle (Q15)
int theta_mech; // Output: Motor Mechanical Angle (Q15)
int DirectionQep; // Output: Motor rotation direction (Q0)
int QEP_cnt_idx; // Variable: Encoder counter index (Q0)
int theta_raw; // Variable: Raw angle from Timer 2 (Q0)
int mech_scaler; // Parameter: 0.9999/total count, total count = 4000 (Q26)
int pole_pairs; // Parameter: Number of pole pairs (Q0)
int cal_angle; // Parameter: Raw angular offset between encoder and phase a (Q0)
int index_sync_flag; // Output: Index sync status (Q0)
Uint32 SpeedScaler; // Parameter : Scaler converting 1/N cycles to a GLOBAL_Q speed (Q0) - independently with global Q
_iq Speed_pr; // Output : speed in per-unit
Uint32 BaseRpm; // Parameter : Scaler converting GLOBAL_Q speed to rpm (Q0) speed - independently with global Q
int32 SpeedRpm_pr; // Output : speed in r.p.m. (Q0) - independently with global Q
_iq oldpos; // Input: Electrical angle (pu)
_iq Speed_fr; // Output : speed in per-unit
int32 SpeedRpm_fr; // Output : Speed in rpm (Q0) - independently with global Q
void (*init)(); // Pointer to the init funcion
void (*calc)(); // Pointer to the calc funtion
} POSSPEED;
/*-----------------------------------------------------------------------------
Define a POSSPEED_handle
-----------------------------------------------------------------------------*/
typedef POSSPEED *POSSPEED_handle;
/*-----------------------------------------------------------------------------
Default initializer for the POSSPEED Object.
-----------------------------------------------------------------------------*/
#if (CPU_FRQ_150MHZ)
#define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16776,2,0,0x0,\
94,0,6000,0,\
0,0,0,\
(void (*)(long))POSSPEED_Init,\
(void (*)(long))POSSPEED_Calc }
#endif
#if (CPU_FRQ_100MHZ)
#define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16776,2,0,0x0,\
63,0,6000,0,\
0,0,0,\
(void (*)(long))POSSPEED_Init,\
(void (*)(long))POSSPEED_Calc }
#endif
/*-----------------------------------------------------------------------------
Prototypes for the functions in posspeed.c
-----------------------------------------------------------------------------*/
void POSSPEED_Init(void);
void POSSPEED_Calc(POSSPEED_handle);
#endif /* __POSSPEED__ */
However, as mentioned, my encoder is 500l/rev, and thus (by my calculations) the mech_scaler should be set to 16776*2 = 33552. And then i'm getting a warning when building the project, stating that the conversion caused a sign change (because number is too large?).
I'm not completely sure how to program myself out of this problem. I tried changing the type from int to Uint32, but I'm not sure if this is the right way.
I'm aware of the motor-control libraries added in ControlSuite, but I'm not sure how to implement those. And I've spend a great deal of time trying to understand this code, so I'd prefer to just modify this :)
I've seen similar questions on the forum, but not something answering this. I hope you can help :)
Edit: For reference, the code uses the value to calculate position (and speed in another part of the program) with this code:
//**** Position calculation - mechanical and electrical motor angle ****//
p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF; // Motor direction: 0=CCW/reverse, 1=CW/forward
pos16bval=(unsigned int)EQep1Regs.QPOSCNT; // capture position once per QA/QB period
p->theta_raw = pos16bval+ p->cal_angle; // raw theta = current pos. + ang. offset from QA
// The following lines calculate p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]
// where mech_scaler = 4000 cnts/revolution
tmp = (long)((long)p->theta_raw*(long)p->mech_scaler); // Q0*Q26 = Q26
tmp &= 0x03FFF000;
p->theta_mech = (int)(tmp>>11); // Q26 -> Q15
p->theta_mech &= 0x7FFF;