init commit.

Проект каким он достался от Димы.
This commit is contained in:
2021-02-15 09:56:02 +03:00
commit b8a0477c5c
294 changed files with 72365 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
// TI File $Revision: /main/11 $
// Checkin $Date: July 10, 2008 11:06:28 $
//###########################################################################
//
// FILE: Example_2833xEqep_pos_speed_.c
//
// TITLE: EQEP Speed and Position measurement
//
// ASSUMPTIONS:
//
// This program requires the DSP2833x header files.
//
// Test requires the following hardware connections from EPWM1 and
// GPIO pins (simulating QEP sensor) to QEP peripheral
//
// GPIO20/EQEP1A <- GPIO0/EPWM1A (simulates EQEP Phase A signal)
// GPIO21/EQEP1B <- GPIO1/EPWM1B (simulates EQEP Phase B signal)
// GPIO23/EQEP1I <- GPIO4 (simulates EQEP Index Signal)
//
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 2833x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// $Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// PU PU PU PU
// ==========================================
// 1 1 1 1 Jump to Flash
// 1 1 1 0 SCI-A boot
// 1 1 0 1 SPI-A boot
// 1 1 0 0 I2C-A boot
// 1 0 1 1 eCAN-A boot
// 1 0 1 0 McBSP-A boot
// 1 0 0 1 Jump to XINTF x16
// 1 0 0 0 Jump to XINTF x32
// 0 1 1 1 Jump to OTP
// 0 1 1 0 Parallel GPIO I/O boot
// 0 1 0 1 Parallel XINTF boot
// 0 1 0 0 Jump to SARAM <- "boot to SARAM"
// 0 0 1 1 Branch to check boot mode
// 0 0 1 0 Boot to flash, bypass ADC cal
// 0 0 0 1 Boot to SARAM, bypass ADC cal
// 0 0 0 0 Boot to SCI-A, bypass ADC cal
// Boot_Table_End$
//
// DESCRIPTION:
//
// This test will provide position measurement, speed measurement using the capture unit, and
// speed measurement using unit time out. This example uses the IQMath library. It is used
// merely to simplify high-precision calculations.
//
// See DESCRIPTION in Example_posspeed.c for more details on the calculations
// performed in this example.
//
// In addition to this file, the following files must be included in this project:
// Example_posspeed.c - includes all eQEP functions
// Example_EPwmSetup.c - sets up EPWM1A and EPWM1B as simulated QA and QB encoder signals
// Example_posspeed.h - includes initialization values for pos and speed structure
//
// Notes:
// * Maximum speed is configured to 6000rpm(BaseRpm)
// * Minimum speed is assumed at 10rpm for capture pre-scalar selection
// * Pole pair is configured to 2 (pole_pairs)
// * QEP Encoder resolution is configured to 4000counts/revolution (mech_scaler)
// which means: 4000/4 = 1000 line/revolution quadrature encoder (simulated by EPWM1)
// * EPWM1 (simulating QEP encoder signals) is configured for 5kHz frequency or 300 rpm
// (=4*5000 cnts/sec * 60 sec/min)/4000 cnts/rev)
// * 300 rpm EPWM1 speed will be measured by EQEP.
//
// SPEEDRPM_FR: High Speed Measurement is obtained by counting the QEP input pulses
// for 10ms (unit timer set to 100Hz).
//
// SPEEDRPM_FR = { (Position Delta)/10ms } * 60 rpm
//
//
// SPEEDRPM_PR: Low Speed Measurement is obtained by measuring time period of QEP edges.
// Time measurement is averaged over 64edges for better results and
// capture unit performs the time measurement using pre-scaled SYSCLK
//
// Note that pre-scaler for capture unit clock is selected such that
// capture timer does not overflow at the required minimum RPM speed
//
// Watch Variables: qep_posspeed.SpeedRpm_fr - Speed meas. in rpm using QEP position counter
// qep_posspeed.SpeedRpm_pr - Speed meas. in rpm using capture unit
// qep_posspeed.theta_mech - Motor mechanical angle (Q15)
// qep_posspeed.theta_elec - Motor electrical angle (Q15)
//
//###########################################################################
// Original Author S.D.
//
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "Example_posspeed.h" // Example specific Include file
void initEpwm();
interrupt void prdTick(void);
POSSPEED qep_posspeed=POSSPEED_DEFAULTS;
Uint16 Interrupt_Count = 0;
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// For this case only init GPIO for eQEP1 and ePWM1
// This function is found in DSP2833x_EQep.c
InitEQep1Gpio();
InitEPwm1Gpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low
EDIS;
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
initEpwm(); // This function exists in Example_EPwmSetup.c
// Step 5. User specific code, enable interrupts:
// Enable CPU INT1 which is connected to CPU-Timer 0:
IER |= M_INT3;
// Enable TINT0 in the PIE: Group 3 interrupt 1
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
qep_posspeed.init(&qep_posspeed);
for(;;)
{
}
}
interrupt void prdTick(void) // EPWM1 Interrupts once every 4 QCLK counts (one period)
{ Uint16 i;
// Position and Speed measurement
qep_posspeed.calc(&qep_posspeed);
// Control loop code for position control & Speed contol
Interrupt_Count++;
if (Interrupt_Count==1000) // Every 1000 interrupts(4000 QCLK counts or 1 rev.)
{
EALLOW;
GpioDataRegs.GPASET.bit.GPIO4 = 1; // Pulse Index signal (1 pulse/rev.)
for (i=0; i<700; i++){
}
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
Interrupt_Count = 0; // Reset count
EDIS;
}
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EPwm1Regs.ETCLR.bit.INT=1;
}

View File

@@ -0,0 +1,39 @@
/*
// TI File $Revision: /main/6 $
// Checkin $Date: August 9, 2007 17:15:15 $
//###########################################################################
//
// This .gel file can be used to help load and build the example project.
// It should be unloaded from Code Composer Studio before loading another
// project.
//
//###########################################################################
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
*/
menuitem "DSP2833x eQEP Posspeed"
hotmenu Load_and_Build_Project()
{
GEL_ProjectLoad("Example_2833xEqep_pos_speed.pjt");
GEL_ProjectBuild("Example_2833xEqep_pos_speed.pjt");
Setup_WatchWindow();
}
hotmenu Load_Code()
{
GEL_Load(".\\debug\\Example_2833xEqep_pos_speed.out");
Setup_WatchWindow();
}
hotmenu Setup_WatchWindow()
{
GEL_WatchReset();
GEL_WatchAdd("qep_posspeed.SpeedRpm_fr",,"");
GEL_WatchAdd("qep_posspeed.SpeedRpm_pr",,"");
GEL_WatchAdd("qep_posspeed.theta_mech",,"");
GEL_WatchAdd("qep_posspeed.theta_elec",,"");
GEL_WatchAdd("EQep1Regs,x");
}

View File

@@ -0,0 +1,56 @@
; Code Composer Project File, Version 2.0 (do not modify or remove this line)
[Project Settings]
ProjectName="DSP2833x"
ProjectDir="C:\tidcs\c28\DSP2833x\v120\DSP2833x_examples\eqep_pos_speed\"
ProjectType=Executable
CPUFamily=TMS320C28XX
Tool="Compiler"
Tool="CustomBuilder"
Tool="DspBiosBuilder"
Tool="Linker"
Config="Debug"
Config="Release"
[Source Files]
Source="..\..\DSP2833x_common\source\DSP2833x_ADC_cal.asm"
Source="..\..\DSP2833x_common\source\DSP2833x_CodeStartBranch.asm"
Source="..\..\DSP2833x_common\source\DSP2833x_DefaultIsr.c"
Source="..\..\DSP2833x_common\source\DSP2833x_EPwm.c"
Source="..\..\DSP2833x_common\source\DSP2833x_EQep.c"
Source="..\..\DSP2833x_common\source\DSP2833x_PieCtrl.c"
Source="..\..\DSP2833x_common\source\DSP2833x_PieVect.c"
Source="..\..\DSP2833x_common\source\DSP2833x_SysCtrl.c"
Source="..\..\DSP2833x_common\source\DSP2833x_usDelay.asm"
Source="..\..\DSP2833x_headers\source\DSP2833x_GlobalVariableDefs.c"
Source="..\..\DSP2833x_common\lib\IQmath_fpu32.lib"
Source="Example_2833xEqep_pos_speed.c"
Source="Example_EPwmSetup.c"
Source="Example_posspeed.c"
Source="..\..\DSP2833x_common\cmd\28335_RAM_lnk.cmd"
Source="..\..\DSP2833x_headers\cmd\DSP2833x_Headers_nonBIOS.cmd"
["Compiler" Settings: "Debug"]
Options=-g -q -pdr -fr"C:\tidcs\c28\DSP2833x\v120\DSP2833x_examples\eqep_pos_speed\Debug" -fs"C:\tidcs\c28\DSP2833x\v120\DSP2833x_examples\eqep_pos_speed\Debug" -i".." -i"..\..\DSP2833x_headers\include" -i"..\..\DSP2833x_common\include" -i"..\..\DSP2833x_common\lib" -d"_DEBUG" -d"LARGE_MODEL" -ml -mt -v28 --float_support=fpu32
["Compiler" Settings: "Release"]
Options=-q -o3 -fr"C:\tidcs\c28\DSP2833x\v120\DSP2833x_examples\eqep_pos_speed\Release" -d"LARGE_MODEL" -ml -v28
["DspBiosBuilder" Settings: "Debug"]
Options=-v28
["DspBiosBuilder" Settings: "Release"]
Options=-v28
["Linker" Settings: "Debug"]
Options=-q -c -ecode_start -m".\Debug\Example_2833xEqep_pos_speed.map" -o".\Debug\Example_2833xEqep_pos_speed.out" -stack0x380 -w -x -i"..\..\DSP2833x_headers\include" -l"rts2800_fpu32.lib"
["Linker" Settings: "Release"]
Options=-q -c -o".\Release\Example_2833xEqep_pos_speed.out" -x
["..\..\DSP2833x_common\cmd\28335_RAM_lnk.cmd" Settings: "Debug"]
LinkOrder=1
["..\..\DSP2833x_common\cmd\28335_RAM_lnk.cmd" Settings: "Release"]

View File

@@ -0,0 +1,69 @@
// TI File $Revision: /main/9 $
// Checkin $Date: April 21, 2008 15:42:18 $
//###########################################################################
//
// FILE: Example_EpwmSetup.c
//
// TITLE: Pos speed measurement using EQEP peripheral
//
// DESCRIPTION:
//
// This file contains source for the ePWM initialization for the
// pos/speed module
//
//###########################################################################
// Original Author: SD
//
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "Example_posspeed.h" // Example specific Include file
#if (CPU_FRQ_150MHZ)
#define CPU_CLK 150e6
#endif
#if (CPU_FRQ_100MHZ)
#define CPU_CLK 100e6
#endif
#define PWM_CLK 5e3 // 5kHz (300rpm) EPWM1 frequency. Freq. can be changed here
#define SP CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL 0x200E // up-down count, timebase=SYSCLKOUT
void initEpwm()
{
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS =0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA=SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
EPwm1Regs.AQCTLB.all=0x09; // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=0x0A; // Interrupt on PRD
EPwm1Regs.ETPS.all=1;
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
}

View File

@@ -0,0 +1,245 @@
// TI File $Revision: /main/9 $
// Checkin $Date: April 21, 2008 15:42:23 $
//###########################################################################
//
// FILE: Example_posspeed.c
//
// TITLE: Pos/speed measurement using EQEP peripheral
//
// DESCRIPTION:
//
// This file includes the EQEP initialization and position and speed calcuation
// functions called by Example_2833xEqep_posspeed.c. The position and
// speed calculation steps performed by POSSPEED_Calc() at SYSCLKOUT = 150 MHz
// and 100 MHz are described in detail below:
//
// For 150 MHz Operation:
// ----------------------
//
// 1. This program calculates: **theta_mech**
//
// theta_mech = QPOSCNT/mech_Scaler = QPOSCNT/4000, where 4000 is the number of
// counts in 1 revolution.(4000/4 = 1000 line/rev. quadrature encoder)
//
// 2. This program calculates: **theta_elec**
//
// theta_elec = (# pole pairs) * theta_mech = 2*QPOSCNT/4000 for this example
//
// 3. This program calculates: **SpeedRpm_fr**
//
// SpeedRpm_fr = [(x2-x1)/4000]/T - Equation 1
// Note (x2-x1) = difference in number of QPOSCNT counts. Dividing (x2-x1) by
// 4000 gives position relative to Index in one revolution.
// If base RPM = 6000 rpm: 6000 rpm = [(x2-x1)/4000]/10ms - Equation 2
// = [(x2-x1)/4000]/(.01s*1 min/60 sec)
// = [(x2-x1)/4000]/(1/6000) min
// max (x2-x1) = 4000 counts, or 1 revolution in 10 ms
//
//
// If both sides of Equation 2 are divided by 6000 rpm, then:
// 1 = [(x2-x1)/4000] rev./[(1/6000) min * 6000rpm]
// Because (x2-x1) must be <4000 (max) for QPOSCNT increment,
// (x2-x1)/4000 < 1 for CW rotation
// And because (x2-x1) must be >-4000 for QPOSCNT decrement,
// (x2-x1)/4000>-1 for CCW rotation
// speed_fr = [(x2-x1)/4000]/[(1/6000) min * 6000rpm]
// = (x2-x1)/4000 - Equation 3
//
// To convert speed_fr to RPM, multiply Equation 3 by 6000 rpm
// SpeedRpm_fr = 6000rpm *(x2-x1)/4000 - Final Equation
//
//
// 2. **min rpm ** = selected at 10 rpm based on CCPS prescaler options available (128 is greatest)
//
// 3. **SpeedRpm_pr**
// SpeedRpm_pr = X/(t2-t1) - Equation 4
// where X = QCAPCTL [UPPS]/4000 rev. (position relative to Index in 1 revolution)
// If max/base speed = 6000 rpm: 6000 = (32/4000)/[(t2-t1)/(150MHz/128)]
// where 32 = QCAPCTL [UPPS] (Unit timeout - once every 32 edges)
// 32/4000 = position in 1 revolution (position as a fraction of 1 revolution)
// t2-t1/(150MHz/128), t2-t1= # of QCAPCLK cycles, and
// 1 QCAPCLK cycle = 1/(150MHz/128)
// = QCPRDLAT
//
// So: 6000 rpm = [32(150MHz/128)*60s/min]/[4000(t2-t1)]
// t2-t1 = [32(150MHz/128)*60 s/min]/(4000*6000rpm) - Equation 5
// = 94 CAPCLK cycles = maximum (t2-t1) = SpeedScaler
//
// Divide both sides by (t2-t1), and:
// 1 = 94/(t2-t1) = [32(150MHz/128)*60 s/min]/(4000*6000rpm)]/(t2-t1)
// Because (t2-t1) must be < 94 for QPOSCNT increment:
// 94/(t2-t1) < 1 for CW rotation
// And because (t2-t1) must be >-94 for QPOSCNT decrement:
// 94/(t2-t1)> -1 for CCW rotation
//
// speed_pr = 94/(t2-t1)
// or [32(150MHz/128)*60 s/min]/(4000*6000rpm)]/(t2-t1) - Equation 6
//
// To convert speed_pr to RPM:
// Multiply Equation 6 by 6000rpm:
// SpeedRpm_fr = 6000rpm * [32(150MHz/128)*60 s/min]/[4000*6000rpm*(t2-t1)]
// = [32(150MHz/128)*60 s/min]/[4000*(t2-t1)]
// or [(32/4000)rev * 60 s/min]/[(t2-t1)(QCPRDLAT)]- Final Equation
//
//
// For 100 MHz Operation:
// ----------------------
//
// The same calculations as above are performed, but with 100 MHz
// instead of 150MHz when calculating SpeedRpm_pr.
// The value for freqScaler_pr becomes: [32*(100MHz/128)*60s/min]/(4000*6000rpm) = 63
// More detailed calculation results can be found in the Example_freqcal.xls
// spreadsheet included in the example folder.
//
//
//
// This file contains source for the posspeed module
//
//###########################################################################
// Original Author: SD
//
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "Example_posspeed.h" // Example specific Include file
void POSSPEED_Init(void)
{
#if (CPU_FRQ_150MHZ)
EQep1Regs.QUPRD=1500000; // Unit Timer for 100Hz at 150 MHz SYSCLKOUT
#endif
#if (CPU_FRQ_100MHZ)
EQep1Regs.QUPRD=1000000; // Unit Timer for 100Hz at 100 MHz SYSCLKOUT
#endif
EQep1Regs.QDECCTL.bit.QSRC=00; // QEP quadrature count mode
EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
EQep1Regs.QEPCTL.bit.PCRM=00; // PCRM=00 mode - QPOSCNT reset on index event
EQep1Regs.QEPCTL.bit.UTE=1; // Unit Timeout Enable
EQep1Regs.QEPCTL.bit.QCLM=1; // Latch on unit time out
EQep1Regs.QPOSMAX=0xffffffff;
EQep1Regs.QEPCTL.bit.QPEN=1; // QEP enable
EQep1Regs.QCAPCTL.bit.UPPS=5; // 1/32 for unit position
EQep1Regs.QCAPCTL.bit.CCPS=7; // 1/128 for CAP clock
EQep1Regs.QCAPCTL.bit.CEN=1; // QEP Capture Enable
}
void POSSPEED_Calc(POSSPEED *p)
{
long tmp;
unsigned int pos16bval,temp1;
_iq Tmp1,newp,oldp;
//**** 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;
// The following lines calculate p->elec_mech
p->theta_elec = p->pole_pairs*p->theta_mech; // Q0*Q15 = Q15
p->theta_elec &= 0x7FFF;
// Check an index occurrence
if (EQep1Regs.QFLG.bit.IEL == 1)
{
p->index_sync_flag = 0x00F0;
EQep1Regs.QCLR.bit.IEL=1; // Clear interrupt flag
}
//**** High Speed Calcultation using QEP Position counter ****//
// Check unit Time out-event for speed calculation:
// Unit Timer is configured for 100Hz in INIT function
if(EQep1Regs.QFLG.bit.UTO==1) // If unit timeout (one 100Hz period)
{
/** Differentiator **/
// The following lines calculate position = (x2-x1)/4000 (position in 1 revolution)
pos16bval=(unsigned int)EQep1Regs.QPOSLAT; // Latched POSCNT value
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->oldpos;
if (p->DirectionQep==0) // POSCNT is counting down
{
if (newp>oldp)
Tmp1 = - (_IQ(1) - newp + oldp); // x2-x1 should be negative
else
Tmp1 = newp -oldp;
}
else if (p->DirectionQep==1) // POSCNT is counting up
{
if (newp<oldp)
Tmp1 = _IQ(1) + newp - oldp;
else
Tmp1 = newp - oldp; // x2-x1 should be positive
}
if (Tmp1>_IQ(1))
p->Speed_fr = _IQ(1);
else if (Tmp1<_IQ(-1))
p->Speed_fr = _IQ(-1);
else
p->Speed_fr = Tmp1;
// Update the electrical angle
p->oldpos = newp;
// Change motor speed from pu value to rpm value (Q15 -> Q0)
// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
p->SpeedRpm_fr = _IQmpy(p->BaseRpm,p->Speed_fr);
//=======================================
EQep1Regs.QCLR.bit.UTO=1; // Clear interrupt flag
}
//**** Low-speed computation using QEP capture counter ****//
if(EQep1Regs.QEPSTS.bit.UPEVNT==1) // Unit position event
{
if(EQep1Regs.QEPSTS.bit.COEF==0) // No Capture overflow
temp1=(unsigned long)EQep1Regs.QCPRDLAT; // temp1 = t2-t1
else // Capture overflow, saturate the result
temp1=0xFFFF;
p->Speed_pr = _IQdiv(p->SpeedScaler,temp1); // p->Speed_pr = p->SpeedScaler/temp1
Tmp1=p->Speed_pr;
if (Tmp1>_IQ(1))
p->Speed_pr = _IQ(1);
else
p->Speed_pr = Tmp1;
// Convert p->Speed_pr to RPM
if (p->DirectionQep==0) // Reverse direction = negative
p->SpeedRpm_pr = -_IQmpy(p->BaseRpm,p->Speed_pr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
else // Forward direction = positive
p->SpeedRpm_pr = _IQmpy(p->BaseRpm,p->Speed_pr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
EQep1Regs.QEPSTS.all=0x88; // Clear Unit position event flag
// Clear overflow error flag
}
}

View File

@@ -0,0 +1,85 @@
// TI File $Revision: /main/6 $
// Checkin $Date: August 9, 2007 17:15:33 $
//###########################################################################
//
// 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 Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#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__ */