Basic trigonometric subroutines for the ADMC331

advertisement
a Basic trigonometric subroutines for the ADMC331
AN331-10
a
Basic trigonometric
subroutines for the ADMC331
AN331-10
© Analog Devices Inc., January 2000
Page 1 of 11
a Basic trigonometric subroutines for the ADMC331
AN331-10
Table of Contents
SUMMARY...................................................................................................................... 3
1
THE TRIGONOMETRIC LIBRARY ROUTINES....................................................... 3
1.1
Using the Trigonometric Routines ................................................................................................................3
1.2
Formats of inputs and outputs.......................................................................................................................3
1.3
Implemented algorithms ................................................................................................................................4
1.4
Usage of the DSP registers .............................................................................................................................4
1.5
The program code...........................................................................................................................................4
1.6
Access to the library: the header file.............................................................................................................6
2
SOFTWARE EXAMPLE: GENERATION OF THREE-PHASE SINE-WAVES......... 7
2.1
The main program: main.dsp........................................................................................................................7
2.2
The main include file: main.h ........................................................................................................................8
2.3
Example output...............................................................................................................................................9
3
PRECISION OF THE ROUTINES ............................................................................ 9
3.1
Sine and Cosine functions ..............................................................................................................................9
3.2
Arctangent function......................................................................................................................................10
4
DIFFERENCES BETWEEN LIBRARY AND ADMC331 “ROM-UTILITIES” ......... 11
© Analog Devices Inc., January 2000
Page 2 of 11
AN331-10
a Basic trigonometric subroutines for the ADMC331
Summary
This application note illustrates the usage of some basic trigonometric subroutines such as sine and
cosine. They are implemented in a library-like module for easy access. The realisation follows the one
described in chapter 4 of the DSP applications handbook1. Then, a software example will be described
that may be downloaded from the accompanying zipped files. Finally, some data will be shown
concerning the accuracy of the algorithms.
1 The Trigonometric Library Routines
1.1
Using the Trigonometric Routines
The routines are developed as an easy-to-use library, which has to be linked to the user’s application. The
library consists of two files. The file “trigono.dsp” contains the assembly code for the subroutines. This
package has to be compiled and can then be linked to an application. The user simply has to include the
header file “trigono.h”, which provides function-like calls to the routines. The following table summarises
the set of macros that are defined in this library. Note that every trigonometric function stores the result in
the ar register.
Operation
Usage
Operands
Initialisation
Set_DAG_registers_for_trigonometric;
none
Sine
Sin(angle);
angle = dreg2 or constant
Cosine
Cos(angle);
angle = dreg3 or constant
Arctangent
Atan(integer_part, fractional_part);
integer_part = dreg4 or constant
fractional_part = dreg5 or constant
Table 1: Implemented routines
The routines do not require any configuration constants from the main include-file “main.h” that comes
with every application note. For more information about the general structure of the application notes and
including libraries into user applications refer to the Library Documentation File. Section 2 shows an
example of usage of this library. In the following sections each routine is explained in detail with the
relevant segments of code which is found in either “trigono.h” or “trigono.dsp”. For more information see
the comments in those files.
1.2
Formats of inputs and outputs
The implementation of the routines is such that values for angles are expected to be in the usual scaled
1.15 format. Therefore, +1 (0x7FFF) corresponds to +π radians or 180 degrees, and –1 (0x8000) to -π
radians or -180 degrees. The sine and cosine functions use this format for their input. Since the output of
these functions is limited to the range [-1, 1], the scaled 1.15 format is the natural choice for it.
1
a ”Digital Signal Applications using the ADSP-2100 Family”, Volume 1, Prentice Hall, 1992
2
Any data register of the ADSP-2171 core
3
Any data register of the ADSP-2171 core
4
Any data register of the ADSP-2171 core except mr0
5
Any data register of the ADSP-2171 core except mr1
© Analog Devices Inc., January 2000
Page 3 of 11
AN331-10
a Basic trigonometric subroutines for the ADMC331
The arctan function requires a different format. Since its argument may sweep from –∞ to +∞, the scaling
is no longer feasible. The argument is represented by a (signed) 32-bit value in the 16.16 format. The
overall range is therefore from –32768 (0x8000.0000) to +32768-2-16 (0x7FFF.FFFF). The output value is
an angle in the range from -½π to +½π, corresponding in the above-defined 1.15 format to –0.5 to +0.5.
1.3
Implemented algorithms
The calculation is achieved through approximation of the functions by means of a fifth order Taylor series
expansion. The equations that are used are reported hereafter:
α ∈ [0,1[
sin (α ) = 3.140625α + 0.02026367α 2 − 5.325196α 3 + 0.5446778α 4 + 1.800293α 5
arctan(x ) = 0.318253 x + 0.003314 x − 0.130908 x + 0.068542 x − 0.009159 x
2
3
4
x ∈ [- 1,1]
5
st
The approximation for the sine function is accurate for any angle in the 1 quadrant. Values in the other
quadrants are reported the 1st quadrant for the known symmetries of the functions. The cosine is
calculated with the same approximation since cos(α ) = sin (π2 − α ) . The arctangent is valid for any
argument of absolute value less or equal than 1. For arguments outside this interval, the following
property is used:
( )
arctan(x ) = 12 − arctan x −1 .
Refer to the above-mentioned DSP applications handbook for more details.
1.4
Usage of the DSP registers
The following table gives an overview of the registers that are used by the functions. It may be noted that
the DAG registers M5 and L5 must be set to 1 and 0 respectively and that they are not modified by the
trigonometric routines. The already mentioned call to Set_DAG_registers_for_trigonometric prepares
these registers for the trigonometric functions. It now becomes clear that this routine is necessary only
once if M5 and/or L5 are not modified in another part of the user’s code, as shown in the example in
section 3.
Subroutine
Input
Output
Modified registers
ay0, ay1, af, ar,
Sin_
ax0
ar
mx1, my1, mf, mr,
sr, I5
ay0, ay1, af, ar,
Cos_
ax0
ar
mx1, my1, mf, mr,
sr, I5
ax0, ax1, ay0, ay1, af, ar,
Atan_
mr1, mr0
ar
mx1, my0, my1, mf, mr,
sr, si, I5
Other registers
M5 = 1,
L5 = 0
M5 = 1,
L5 = 0
M5 = 1,
L5 = 0
Table 2: Usage of DSP core registers
1.5
The program code
The following code defines the three routines Sine, Cosine and Arctangent.
© Analog Devices Inc., January 2000
Page 4 of 11
a Basic trigonometric subroutines for the ADMC331
AN331-10
The functions are declared as globally accessible to other applications. The code is almost identical to the
one described in the handbook. Both the Sine and Cosine routine make use of the core sine approximation
that is documented in the handbook. The coefficients have been moved into program memory instead of data
memory (which implies the use of I5 instead of I3). Therefore, the initial part of these routines simply
modifies the argument in order to lie within the 1st quadrant where the adopted approximation by Taylor
series is valid. The final result is then obtained by making use of the well known symmetries of these
functions and the relation cos(α)=sin(½π-α).
{***************************************************************************************
* Routines Defined in this Module
*
***************************************************************************************}
.ENTRY
.ENTRY
.ENTRY
Sin_;
Cos_;
Atan_;
{***************************************************************************************
* Local Variables Defined in this Module
*
***************************************************************************************}
.VAR/PM/RAM/SEG=USER_PM1 SIN_COEFF[5];
.INIT
SIN_COEFF : 0x324000, 0x005300, 0xAACC00, 0x08B700, 0x1CCE00;
.VAR/PM/RAM/SEG=USER_PM1 ATN_COEFF[5];
.INIT
ATN_COEFF : 0x28BD00, 0x006D00, 0xEF3E00, 0x08C600, 0xFED400;
Cos_:
Sin_:
ar=abs ax0;
ay0=0x4000;
ay1=0x7fff;
ar=ay0-ar;
ay0=ar;
ar=abs ar;
jump sin_approx;
{
{
{
{
{
{
{ abs(x)}
pi/2 = 0.5 }
pi = 1.0 }
pi/2 - |x|}
store sign of result in ay0}
abs value for approx }
skip to Taylor series }
ay0=0x4000;
ay1=0x7fff;
ar=ax0 and ay1;
af=ay0-ar;
if LT ar=ay1-ar;
ay0=ax0;
{
{
{
{
{
{ pi/2 }
pi = 1 }
take |x| }
pi/2 - |x| check for LHS angle}
if x > pi/2 x = pi -x }
store sign of result in ay0}
sin_approx:
I5=^sin_coeff;
{Pointer to coeff. buffer}
my1=ar;
{Coeffs in 4.12 format}
mf=ar*my1 (rnd), mx1=pm(i5,m5);
{mf = x**2}
mr=mx1*my1 (ss), mx1=pm(i5,m5);
{mr = c1*x}
cntr=3;
do approx1 until ce;
mr=mr+mx1*mf (SS);
{Do summation }
approx1:
mf=ar*mf (RND), mx1=PM(I5,M5);
mr=mr+mx1*mf (SS);
sr=ASHIFT mr1 by 3 (HI);
sr=sr or LSHIFT mr0 by 3 (LO);
{Convert to 1.15 format}
ar=pass sr1;
if LT ar=pass ay1;
{Saturate if needed}
af=pass ay0;
if LT ar=-ar;
{Negate output if needed}
rts;
Atan_:
I5 = ^ATN_COEFF;
ay0=0;
ax1=mr1;
ar=pass mr1;
if GE jump posi;
ar=-mr0;
© Analog Devices Inc., January 2000
{point to coefficients}
{Check for positive input}
{Make negative number positive}
Page 5 of 11
a Basic trigonometric subroutines for the ADMC331
AN331-10
mr0=ar;
ar=ay0-mr1+c-1;
mr1=ar;
posi:
sr=LSHIFT mr0 by -1 (LO);
{Produce 1.15 value in SR0}
ar=sr0;
ay1=mr1;
af=pass mr1;
if EQ jump noinv;
{If input < 1, no need to invert}
se=exp mr1 (HI);
{Invert input}
sr=norm mr1 (HI);
sr=sr or NORM mr0 (LO);
ax0=sr1;
si=0x0001;
sr=NORM si (HI);
ay1=sr1;
ay0=sr0;
divs ay1,ax0;
divq ax0; divq ax0; divq ax0;
divq ax0; divq ax0; divq ax0;
divq ax0; divq ax0; divq ax0;
divq ax0; divq ax0; divq ax0;
divq ax0; divq ax0; divq ax0;
ar=ay0;
noinv: my0=ar;
mf=ar*my0 (RND), my1=PM(I5,M5);
mr=ar*my1 (SS), mx1=PM(I5,M5);
cntr=3;
do approx2 until CE;
mr=mr+mx1*mf (SS), mx1=PM(I5,M5);
approx2:
mf=ar*mf (RND);
mr=mr+mx1*mf (SS);
ar=mr1;
ay0=0x4000;
af=pass ay1;
if NE ar=ay0-mr1;
af=pass ax1;
if LT ar=-ar;
rts;
1.6
Access to the library: the header file
The library may be accessed by including the header file “trigono.h” in the application code.
The header file is intended to provide function-like calls to the routines presented in the previous section. It
defines the calls shown in Table 1. The file is self-explaining and needs no further comments.
It is worth adding a few comments about efficiency of these routines. The first macro simply sets the DAG
registers M5 and L5 to its correct values. The user may however just replace the macro with one of its
instructions when the application code modifies just one of these registers. The sine and cosine subroutines
expect the argument to be placed into ax0. This is what the macros do. However, if the angle is already
stored in ax0, the user may just place an instruction call Sin_; instead of Sin(ax0) in order to avoid an
additional instruction ax0 = ax0; in the expanded code. Similarly, a instruction Atan(mr1, mr0) should be
avoided or replaced by the direct call to the subroutine Atan_.
.MACRO Set_DAG_registers_for_trigonometric;
M5 = 1;
L5 = 0;
.ENDMACRO;
.MACRO Sin(%0);
ax0 = %0;
call Sin_;
.ENDMACRO;
.MACRO Cos(%0);
ax0 = %0;
call Cos_;
© Analog Devices Inc., January 2000
Page 6 of 11
AN331-10
a Basic trigonometric subroutines for the ADMC331
.ENDMACRO;
.MACRO Atan(%0, %1);
mr1= %0;
mr0= %1;
call Atan_;
.ENDMACRO;
2 Software Example: Testing the Trigonometric Functions
2.1
The main program: main.dsp
The example demonstrates how to use the routines. All it does is to cycle through the whole range of
definition of the sine function and converting the results by means of the digital to analog converter. The
application has been adapted from two previous notes6,7. This section will only explain the few and
intuitive modifications to those applications.
The file “main.dsp” contains the initialisation and PWM Sync and Trip interrupt service routines. To
activate, build the executable file using the attached build.bat either within your DOS prompt or clicking
on it from Windows Explorer. This will create the object files and the main.exe example file. This file
may be run on the Motion Control Debugger.
In the following, a brief description of the additional code (put in evidence by bold characters) is given.
Start of code – declaring start location in program memory
.MODULE/RAM/SEG=USER_PM1/ABS=0x30
Main_Program;
Next, the general systems constants and PWM configuration constants (main.h – see the next section) are
included. Also included are the PWM library, the DAC interface library and the trigonometric library.
{***************************************************************************************
* Include General System Parameters and Libraries
*
***************************************************************************************}
#include <main.h>;
#include <pwm331.h>;
#include <dac331.h>;
#include <trigono.h>;
The argument variable Theta is defined hereafter.
{***************************************************************************************
* Local Variables Defined in this Module
*
***************************************************************************************}
.VAR/DM/RAM/SEG=USER_DM Theta;
.INIT Theta : 0x0000;
{ Current angle
}
First, the PWM block is set up to generate interrupts every 100µs (see “main.h” in the next Section). The
variable Theta, which stores the argument of the trigonometric functions, is set to zero. Before using the
trigonometric functions, it is necessary to initialise certain registers of the data-address-generator (DAG) of
the DSP core. This will be discussed in more detail in the next section. However, note that this is done only
once in this example. If those registers are modified in other parts of the user’s code, then it must be repeated
before a call to a trigonometric function.
The main loop just waits for interrupts..
{********************************************************************************************}
6
AN331-03: Three-Phase Sine-Wave Generation using the PWM Unit of the ADMC331
7
AN331-06: Using the Serial Digital to Analog Converter of the ADMC Connector Board
© Analog Devices Inc., January 2000
Page 7 of 11
AN331-10
a Basic trigonometric subroutines for the ADMC331
{ Start of program code
}
{********************************************************************************************}
Startup:
PWM_Init(PWMSYNC_ISR, PWMTRIP_ISR);
DAC_Init;
IFC = 0x80;
ay0 = 0x200;
ar = IMASK;
ar = ar or ay0;
IMASK = ar;
{ Clear any pending IRQ2 inter.
{ unmask irq2 interrupts.
}
}
{ IRQ2 ints fully enabled here
}
ar = pass 0;
DM(Theta)= ar;
Set_DAG_registers_for_trigonometric;
Main:
jump Main;
{ Wait for interrupt to occur }
rts;
The interrupt service routine simply shows how to make use of the trigonometric routines. It invokes the three
routines (the integer part of the Atan_ function is set to zero – it is intended to illustrate the possibility of
constant arguments). The result of Sin, Cos and Atan (in register ar) are stored in channels 1, 2 and 3
respectively and send to the DAC (refer to the above mentioned application note AN331-6 for details). Then
Theta is incremented, so that the whole range of definition of the sine functions is swept. Refer to Section 1.2
for the used formats of inputs and outputs. After 65536 interrupts (corresponding to approx. 6.55s) the whole
period is completed. Since only the fractional part of the arctan argument is used, this function will generate
the output from 0 to π/4 (hexadecimal 0x2000).
{********************************************************************************************}
{ PWM Interrupt Service Routine
}
{********************************************************************************************}
PWMSYNC_ISR:
ax0 = dm(Theta);
Sin(ax0);
DAC_Put(1, ar);
Cos(ax0);
DAC_Put(2, ar);
Atan(0, ax0);
DAC_Put(3, ar);
DAC_Update;
ax1= DM(Theta);
ar= ax1 +1;
DM(Theta)= ar;
rti;
2.2
The main include file: main.h
This file contains the definitions of ADMC331 constants, general purpose macros and the configuration
parameters of the system and library routines. It should be included in every application. For more
information refer to the Library Documentation File.
This file is mostly self-explaining. As already mentioned, the trigonometric library does not require any
configuration parameters. The following defines the parameters for the PWM ISR used in this example.
{********************************************************************************************}
{ Library: PWM block
}
{ file
: PWM331.dsp
}
{ Application Note: Usage of the ADMC331 Pulse Width Modulation Block
}
.CONST PWM_freq
= 10000;
{Desired PWM switching frequency [Hz]
}
.CONST PWM_deadtime
= 1000;
{Desired deadtime [nsec]
}
.CONST PWM_minpulse
= 1000;
{Desired minimal pulse time [nsec]
}
.CONST PWM_syncpulse
= 1540;
{Desired sync pulse time [nsec]
}
{********************************************************************************************}
© Analog Devices Inc., January 2000
Page 8 of 11
a Basic trigonometric subroutines for the ADMC331
2.3
AN331-10
Example output
The signals that are generated by this demonstration program is shown in the following figure. Note that
the use of only the fractional part for the arctan function limits it’s output to the range of 0 to 0.25
(corresponding to ¼π = arctan(1)). Refer to section 1.2 for details on the format of inputs and outputs.
Figure 1 Produced output of the example program.
The waveforms represent the signals on the DAC outputs 1 (sine), 2 (cosine) and 3 (arctangent).
3 Precision of the routines
3.1
Sine and Cosine functions
The following figure plots the obtained error of the implemented sine function (16 bit fixed point
arithmetic) versus the result of floating point calculations. The graph is limited to the 1st quadrant for the
usual symmetry properties and may obviously be extended to the cosine function as well. Its maximum is
found to be of approx. 0.016%, resulting in a precision of 12.7 bits for the sine and cosine functions.
© Analog Devices Inc., January 2000
Page 9 of 11
a Basic trigonometric subroutines for the ADMC331
AN331-10
π). The x-axis is scaled to 1.15 format.
Figure 2 Error of sine function in the 1st quadrant (0 to ½π
3.2
Arctangent function
The following figures plot the obtained error of the implemented arctangent function (16 bit fixed point
arithmetic) versus the result of floating point calculations. The analysis has been split into the two cases
of the argument laying in the range of 0 to 1 (increments of 2-14 - Figure 3) and in the range from 1 to
2048 (steps of 0.5 - Figure 4). The maximum error is found to be of approx. 0.0059%, resulting in a
precision of 14 bits for the arctangent function. The result may obviously be extended to negative values
for the usual symmetry properties.
Figure 3 Error of arctangent function in the range of 0 to 1. The y-axis is scaled to 1.15 format.
© Analog Devices Inc., January 2000
Page 10 of 11
AN331-10
a Basic trigonometric subroutines for the ADMC331
Figure 4 Error of arctangent function in the range of 1 to 2048. The y-axis is scaled to 1.15 format.
4 Differences between library and ADMC331 “ROM-Utilities”
The main purpose of this application note is to document, to analyse and to standardise the trigonometric
functions on this part. The routines presented herein do not differ from the ones present in the ROM of the
ADMC331, except for the atan_ routine, which now uses I5, M5 and L5 instead of I4, M4 and L4. This
choice has been made in order to use the same pointers for all of the trigonometric functions. However,
the ones present in the ROM may still be used.
© Analog Devices Inc., January 2000
Page 11 of 11
Download