sine routines

does anybody know where to find some FAST sine routines to be run on an

8052? sdcc's math.h is just an empty file... just an #error directive! thank you in advance.
Reply to
CAFxX
Loading thread data ...

On Wed, 14 Jan 2004 21:43:20 +0100, "CAFxX" wrote in comp.arch.embedded:

There are no FAST routines for calculating sine with the 8051 instruction set, and probably no fast ones either. How much accuracy and precision do you need? The fastest approach would be a look-up table.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply to
Jack Klein

and what sort of floating point arithmetic has he available, if any? Does he have polynomial evaluation routines? etc. What input range is required?

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

On Thu, 15 Jan 2004 04:47:12 GMT, CBFalconer wrote in comp.arch.embedded:

All good questions, but do you know of any fast routines to calculate, as opposed to look up, sines on an 8051? Any floating point is hideously slow on that platform, I know, I've used it a few times.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply to
Jack Klein

You can use a Taylor series. And if your angles are small you can get away with a limited number of terms, depending on the required precision. You may do it with integer math and the approprate scaling.

For example, for small angles, sin(x)=x (in radians)

The next refinement: sin(x) = x - x*x /2 For angles below 1 radian this may be sufficient.

Wim

Reply to
Wim Ton

I was thinking of some Tchebychev polynomials or ratio of polynomials I used 25 years ago for 4.5 digit accuracy. I have the source somewhere for the 8080 code I developed for them, which took about 10 millisec on a 2 Mhz 8080, as I recall. Floating multiply was in the order of 300 uSec. and divide headed for 1 millisec.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

Sorry, no such animal. The fastest way to calculate sines is table lookup and interpolation. Also think 'octents' rather than quadrants to preserve accuracy.

-- Regards, Albert

---------------------------------------------------------------------- AM Research, Inc. The Embedded Systems Experts

formatting link
916.780.7623

----------------------------------------------------------------------

Reply to
Albert Lee Mitchell

Fastest I've seen was look-up with linear interpolation on a twice-folded (at pi and pi/2) table of numerators for a fraction with denominator 65535. All of the processing was performed in integer math except the final division. Accuracy was pretty good and the code was completely portable (the application wasn't for an 8052).

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall far from the tree.
Reply to
Morris Dovey

If only sin/cos is required (and not tan), then why use floating point numbers in the first place. Use some fixed point format e.g. the decimal point to the _left_ of the most significant bit or two bits for the integer part and 30 bits for the decimal part, thus avoiding any normalisation and denormalisation required by floating point additions.

The fixed point arithmetic can be done with integer hardware, but some rounding due to discarded low order decimal bits must be done after multiplication and some shifts with a predetermined number of bits may be required if the number of integer bits is something else than 0 or

  1. The polynomial method is just an refined table look up with some multiplications and additions. The quadrant (0..90 degrees) is divided into a few ranges and the polynomial coefficients are extracted from the table. A fourth order polynomial is usually sufficient for single precision accuracy, while 6-8 order is required for double precision. By dividing the quadrant into a larger number of ranges, a lower order polynomial can be used.

Paul

Reply to
Paul Keinanen

what i need to do is to generate a custom-frequency sine wave to be outputted at CD-quality frequency (44100 samples/second) to a DAC. If possible i'd prefer working with 16 bit integers since float needs cpu-time-expensive libraries. thanks to all of you for your replies. "Jack Klein" ha scritto nel messaggio news: snipped-for-privacy@4ax.com...

thank

Reply to
CAFxX

If that is all you have to do, take a look at Analog Device's DDS chips.

Meindert

Reply to
Meindert Sprang

Setting aside the recommendable option of replacing the whole kaboodle you're planning now with a special-purpose chip (a digitally controlled oscillator), there's still no reason to actually evaluate a sine function for this.

A table should be perfectly adequate --- subsample it in steps through the table whose size is governed by the quotient of your target frequency and the frequency of the tabulated signal. E.g. if you have a sine table of (effectively) 44100 samples for a 1 Hz wave, a 1 kHz wave would use every 1000th sample from that table, and wrap around at the 45th iteration to 45*1000 - 44100 = 900. You'll want to handle non-integer step sizes, too --- either using fixed-point fractional arithmetic, or by Bresenham's algorithm.

The actual table should of course store only one quadrant of the wave (0 .. 90 degrees, typically), to keep it short.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

thank

This is a very fast but quite imprecise method of generating a sine-like wave. I guess whether it is suitable depends what you want to use for. I used it years ago on a PIC in conjunction with a software PWM and decay function to generate a pleasing bell-like tone. I tried it out just now on C++Builder, so I'll just paste the code and let you play with it to see if it works for you. I seem to remember it may decay over time by itself due to rounding errors:

void __fastcall TForm1::FormCreate(TObject *Sender) { int s=Image1->Height/4; int c=0; for( int x=0; xWidth; x++ ) { c = c+s/16; s = s-c/16; Image1->Canvas->Pixels[x][s+Image1->Height/2] =(TColor)0x00FF0000; } }

Peter.

Reply to
CodeSprite
44100 samples / sec = 22,676 microseconds per sample.

Are you sure the 8051 is fast enough to handle that ?

Using a lookup table may help. Doing 16-bit calculations seems impossible. Calculating a floating point sine IS impossible.

It depends on the derivative you use. A standard 8051 will certainly not be able to do the job.

grtnx /jan

CAFxX schrieb in im Newsbeitrag: bu634c$7g9$ snipped-for-privacy@lacerta.tiscalinet.it...

an

Reply to
Jan Homuth

That's less than 23 usec, just to make it clear.

A phase accumulator with a LUT ought be able to do it, using a faster ("very" faster..) variant of the 8051 such as the Cygnal parts. Best to write and simulate the short (assembler!) code now and see how long it will take to execute, including the interrupt and timer reload overhead.. at 50 so-called MIPS there are ~1150 cycles between interrupts. If you can jig the frequency a bit to fit into an integral number of sample periods you can simplify it and reduce the size of the LUT.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

Because it causes confusion. Why is topposting evil and rude.

It would have been simpler if you had stated your real requirements originally. Hans Broeker and Morris Dovey have the right idea. You can limit your table to the range 0..45 degrees and use (1 - sin(90-x)) for 45 to 90. Similarly -sin(-x) for

-90..0. Etc.

It is probably easiest if you keep the table as signed integers to be divided by 32768 for the actual result. Not 65535 or 32767.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

Sine? Not quite...

You can generate a square function - not a square wave but an x^2 function. Imagine x^2 between 0 and 1. It looks a bit like a quarter cycle of sine.

You can generate an arbitrary amplitude and frequency wave in real time by stringing together four such sections with appropriate manipulation. The result is slightly 'fatter' than a sinusoid to look at on a 'scope, but the difference can only really be seen with a direct comparison.

I've used this for controlling hydraulic machinery from almost 0 to

100Hz with great success - it really depends on your application. I don't know if your processor is up to it, but it's much easier than a real sine and more flexible than a LUT.

Unless of course your application allows you to pre-calculte a LUT before sending it to the DAC.

--
Syd
Reply to
Syd Rumpo

ok i understood that i have to use a lookup table. before asking some more question i just want to explain what i am really trying to do. it will simply be a sort of musical keyboard (a synth). it takes the input of 24 keys (using 3 of the four raw i/o ports of the 8052) and sends 16 bit samples to the dac (even if it accepts only 24 bits samples - i simply leave the LS 8 all low). what i'm wondering here is how to implement the lookup table (actually the problem is that the sine function generate variable frequency sine waves) i mean:

short s> > what i need to do is to generate a custom-frequency sine wave to be

Reply to
CAFxX

i meant (real world math):

sin(mod(counter, frequency) * pi * 2 / frequency)

counter simply is the sample counter.

"CAFxX" ha scritto nel messaggio news:bu6k2g$s4s$ snipped-for-privacy@lacerta.tiscalinet.it...

bit

leave

values

Reply to
CAFxX

You should have stated this in your first posting.

You might get away with a phase accumulator and a look-up-table even without interpolation between the steps. The truncation errors will on some output frequencies contribute with wide band noise at the DAC output, while on other frequency settings all the noise power is concentrated in discrete sidebands.

Depending your requirements for the signal to noise ratio and the maximum level allowed for discrete tones, the size of the LUT can be determined. Also the situation is simpler if all the generated frequencies are well below the sampling frequencies.

Most literature about numeric controlled oscillators (NCO) also evaluates the size of the phase accumulator vs. steps size, the number of address bits into the sin(x) table and the number of DAC bits and the spurious levels.

If a simple table look up is not accurate enough, some very simple interpolation with shifts and one or two adds should do the trick. Use a spreadsheet to evaluate the error between the interpolated value and the "exact" 64 bit double precision value and select your table size and interpolation strategy to minimise the number of clock cycles required for the calculations.

Paul

Reply to
Paul Keinanen

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.