Building a sine wave lookup table

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I'm trying to generate a 1Mhz sinewave using a tiny45 with its internal oscialltor and PLL.

I'm following Atmel's application note 131 and they say to update the timer OCR with the next value on the lookup.

I know how to build a lookup, but I don't know if it will be appropriated for the job since because I always need positive values and the one I was thinking will have negative values.

int8_t lookup[256];
float j,inc = (flota)(M_PI*2)/(float)256;
int i;
for (i=0;i<256;i++,j+=inc) 
  lookup[i]=sin(j);

I also didn't understand how the lookup value inserted in the OCR will influence the PWM to achieve the wanted results.

Can someone clarify me a little bit this method of sinewave generation?

With my best regards,

Nuno

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I also didn't understand how the lookup value inserted in the OCR will influence the PWM to achieve the wanted results.


Did you read the app note, and look at the pictures?

Can't you start with the table provided in the app note code?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

you receive sine wave after filtering the pwm square wave. as we see in http://www.atmel.com/dyn/resources/prod_documents/DOC2816.PDF

also,
- can define look up table in flash memory instead of RAM
- for OCR value with maximum value of 0xFF

int8_t lookup[256];
float j=0.0,inc = (float)(M_PI*2)/(float)256.0;
int i;
for (i=0;i<256;i++,j+=inc)
  lookup[i]=(int8_t)((sin(j)*(float)128.0)+(float)128.0); 

Regards
A.R.Khorasani
http://www.instrumentalanalysis.com

Regards
A.R.Khorasani
http://www.instrumentalanalysis.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8)

Attachment(s): 

RES

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, the signal is not zero centered? You will have to shift its DC level. At 1MHz, just AC coupling should do. That is all.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
int8_t lookup[256];
float j,inc = (flota)(M_PI*2)/(float)256;
int i;
for (i=0;i<256;i++,j+=inc)
lookup[i]=sin(j);

Quote:
i=0;i<256;i++,j+=inc

Can anyone tell me what is the use of this condition? I mean why we increment 'j' with inc everytime.

Happy Learning, 

ANKITKUMAR CHHEDA

MTech Scholar,

College of Engineering, Pune (COEP)

 

<Joined FORUM in 2009 to seek help, now back on FORUM to HELP>

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So that j gets incremented each time by inc. Have you got a good book on C?

Leon

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If inc is 1, it plays the note at 1/256*sampduration. If inc is 2, it plays the note an octave higher. Nifty eh?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
If inc is 1, it plays the note at 1/256*sampduration. If inc is 2, it plays the note an octave higher. Nifty eh?

Nifty yes if lookup table is used like that on playback but inc is never 1 or 2 when creating the table, it is the angle increment in radians to get one full sine cycle into 256 discrete sample lookup table.

Personally I'd say that calculating the table in code using floats takes more code space than just having a 256-byte lookup table in code. I tend to use a spreadsheet program for this, exporting the values.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have in mind you can have higher resolutions than normal integers if your angle inc has higer resolution
than the lookup (you only output the high byte). If you want more info look for DDS's.
(so if tabel is 8 bit but angle is 16 bit instead of adding 1 you add 256, and for 2 it's 512 and for 1.5 it's 384 etc).(it give a bit of jitter but the freq. is 100% correct.)

Jens

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As no one else mentioned it yet can I just mention Jesper's miniDDS:

http://www.myplace.nu/avr/minidd...

and from there:

http://www.myplace.nu/avr/minidd...

So there's your "tables" as a set of .byte's - should be simple to process that into a C style array.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still use Turbo C from 1988 or so if I need to generate or convert something simple.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Question...

Is it possible to make a sinewave with a 1MHz frequency with a tiny45?

I achieved the sinewave with the lookup values provided in the application note code but the frequency was around 1Khz.

The main clock is set at 16.5MHz and the PLL to 64Mhz.

I had configured a PWM mode with top set on 0xff.

I then tried to raise the frequency, setting a lower top value and giving larger steps in the lookup index.

However, the obtained frequency was not bigger that much.

So, my question is... is it possible to reach such frequency?

If so, should I use another timer mode?

Thanks,

With my best regards,

Nuno

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is it possible to make a sinewave with a 1MHz frequency with a tiny45?

I'd say no. MiniDDS is about as fast as you can get given a hard loop and the full-port DAC, and that can reach a few hundred kHz.

As Jesper says, if you want a real function generator, then use a real chip (AD9832 in his case).
http://www.myplace.nu/avr/minidd...

And as I mentioned earlier, with your interrupt-driven approach you have at least 12 cycles overhead just to process an interrupt. GCC is not known for skinny ISRs; you could perhaps go naked. Let's say you can get your indexing work done in 20 cycles; that would be about 30 AVR cycles for each step change. At max rate, say 2us for each value change. Even with only a few steps for each cycle (then it is so coarse that you might as well just do a square wave and round the edges with a cap) that is at least 10us/cycle or 100kHz.

You can bump that up Jesper-like by flipping your program around and have a tight loop monitoring the timer flag or timer counts--"polling". Then you'd do your user interface/start/stop via interrupts.

Now, with an Xmega and DMA...

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FWIW, I've found that PythonWin is a good tool for generating tables from equations. You need python installed first of course. Build an equation, and output data that can directly be used in a table.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

using an active filter, its possible to convert Square to Sine wave. it means you have to only generate 1MHz 50% Square wave.
Also, do visit http://www.priorartdatabase.com/IPCOM/000005825/ for another idea.

Regards
A.R.Khorasani
http://www.instrumentalanalysis.com

Regards
A.R.Khorasani
http://www.instrumentalanalysis.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

or ...
you can put the table into a FIFO/SRAM and "clock" it :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Output table addresses to an external memory (rom?) and let it output to a DAC. This externalizes the LUT and the D/A function. You could also use an external counter to address the rom so that you only need to toggle a pin to step.

All in all, a bigger uP would probably be a better investment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is it possible to make a sinewave with a 1MHz frequency with a tiny45?

If that is all you do yes.
Each loop in Jespers DDS is 9 clk.
If you only need 16 bit (jesper use 24) it take 8 clk
If you strech the code you can make 7 clk (so the brance only take up 1 clk).
Will not count for the tiny 45 : move the table to RAM
will save 1 clk.
So on a 16MHz tiny 45 cpu you can make upto 16MHz/(2*7)= 1.1428MHz, but it take all the cpu time!

Jens

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So on a 16MHz tiny 45 cpu you can make upto 16MHz/(2*7)= 1.1428MHz, but it take all the cpu time!

But that is 1 million "operations" per second. That would only be 1 output point for each cycle of a 1MHz sine wave. At that coarseness you might as well be outputting a square wave.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

quote]
But that is 1 million "operations" per second. That would only be 1 output point for each cycle of a 1MHz sine wave. At that coarseness you might as well be outputting a square wave.


No it will be 2 so it satisfy Nyquist.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Think this way :
The use of a DDS with a 8 bit DAC add 8 bit to your timer resolution.

Jens

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you need real speed, you better not use a MCU, but something like a CPLD or discrete logic and a fast SRAM.

The AVR could do all the user interfacing and download the waveform into the SRAM.

I think only one page of VHDL is enough to code the CPLD.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have used AD9833 and AD9834 they are good and cheap.
And if you need higher speed use the harmonics.
With a dev. board and a ARM7 I have send AIS packets (162.025MHz) using the normal 25MHz crystal.

Jens