Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

External DAC and sinus wave generation.

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive
View previous topic :: View next topic  
Author Message
CrazyIgels

Bascom Member



Joined: 26 Oct 2007
Posts: 79

russia.gif
PostPosted: Wed Jan 30, 2008 9:35 am    Post subject: External DAC and sinus wave generation. Reply with quote

Hello All!

I use external SPI DAC to generate sinus wave.

I use next code:

$regfile = "m64def.dat"
$crystal = 7372800

Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 4 , Noss = 0

Dim Angle As Single
Dim Rad_angle As Single
Dim Sinus As Single
Dim Sin_int As Integer
Dim In_ang As Integer
Dim D(2) As Byte

Main:
Angle = Angle + 1
Rad_angle = Deg2rad(angle)
Sinus = Sin(rad_angle)
Sinus = Sinus + 1
Sinus = Sinus * 500
Sin_int = Int(sinus)

Gosub Dac_out;

If Angle = 360 Then
Angle = 0

End If
Goto Main

Dac_out:
D(1) = High(sin_int)
D(2) = Low(sin_int)
Spiinit
Portb.7 = 0
Waitus 1
Spiout D(1) , 2
Waitus 1
Portb.7 = 1
Waitus 1
Portb.6 = 0
Waitus 1
Portb.6 = 1
Return

I have good shape of output signal, but this code working very slow. I have something like 5 Hz output frequency.

I need 5 KHz (5000 Hz) sinus wave vith good shape and i need posibility to change frequency of this wave from my master PC unit. And total range of sinus wave is 5 Volts. (0 - lowest point , 5 higest point).

How i can make this with external SPI based DAC ? Or i need something else?

Thanks All.
Sorry my bad english.
Back to top
View user's profile
mattcro

Bascom Member



Joined: 03 Oct 2007
Posts: 324
Location: Scotland

uk.gif
PostPosted: Wed Jan 30, 2008 1:18 pm    Post subject: Reply with quote

You are trying to do complicated maths (SIN, etc) in realtime on a small microcontroller and this takes *very* many processor cycles. To speed up the sine wave generation, you need to use a lookup table instead of the maths.

Use Excel (or similar) to make a table (array) of SIN values, using perhaps 32 points per cycle (ie 32 "samples" - you probably do not need 360 samples). Then make a DATA table in Bascom using these values and simply READ out each value to the DAC in turn. You can also copy the table into a RAM array, which I think will be even faster.

Do you need to use 16bit samples? 8bit samples will be a fair bit faster.

You can use more or fewer samples/cycle depending on the resolution (ie waveform quality) and frequency you need. You'll probably find that around 16 samples will still give you a reasonable sine wave. You can also use WAITUS or a timer to control the sinewave frequency. Eg: 5kHz sine at 16 samples/cycle requires 80000samples/sec, or 12.5us/sample. That's nearly twice the sample rate of CD players.

_________________
If all else fails, read the manual. Even better: read the manual before something fails. If you can't find it in the manual, search the forum.
BascomAVR 2.0.8.2
Back to top
View user's profile
CrazyIgels

Bascom Member



Joined: 26 Oct 2007
Posts: 79

russia.gif
PostPosted: Wed Jan 30, 2008 1:32 pm    Post subject: Reply with quote

I modify mo soft:

Dim K As Integer
Dim Angle As Single
Dim Rad_angle As Single
Dim Sinus As Single
Dim Sin_int As Integer
Dim In_ang As Integer
Dim D(2) As Byte
Dim Sin_tab(360) As Integer

Main:
For K = 1 To 360 'TABLE GENERATION in RAM
Angle = K
Rad_angle = Deg2rad(angle)
Sinus = Sin(rad_angle)
Sinus = Sinus + 1
Sinus = Sinus * 500
Sin_int = Int(sinus)
Sin_tab(k) = Sin_int
Next K

Cycle:
For K = 1 To 360 'DAC OUT CYCLE
Sin_int = Sin_tab(k)
Gosub Dac_out;
Next K
Goto Cycle

Dac_out:
D(1) = High(sin_int)
D(2) = Low(sin_int)
Spiinit
Portb.7 = 0
Waitus 1
Spiout D(1) , 2
Waitus 1
Portb.7 = 1
Waitus 1
Portb.6 = 0
Waitus 1
Portb.6 = 1
Return

Works much better, but only 75 Hz Sad frequency...
If i remove Waitus 1 in DAC_out - i have something like 80 Hz... and unstable DAC... Sad

I need 5 KHz...
Any other ideas? I don't have.....
Back to top
View user's profile
mattcro

Bascom Member



Joined: 03 Oct 2007
Posts: 324
Location: Scotland

uk.gif
PostPosted: Wed Jan 30, 2008 5:57 pm    Post subject: Reply with quote

You don't need to call SPIINIT each time you write a value to the DAC. Move the SPIINIT to Main, or just after CONFIG SPI. This will save some time each sample.

Make sure you configure the SPI clock to maximum. You can SET the SPI2X bit (check the SPI registers in the datacheet) to double the SPI clock rate. However, make sure you don't exceed the DAC maximum clock rate.

You need to reduce the number of samples per cycle to get a higher sine frequency. You are using 360 samples at the moment, but you will need to reduce this to only a few samples per cycle unless you can speed up the sample rate (currently 360*75=27kHz).

You will need to optimise the sample loop to make it as fast as possible. For example, put the Dac_out sub directly into the "For K..." loop

Another thing... Double check the clock fuses when programming to make sure you really are using the 7MHz crystal and not a 1MHz internal oscillator or whatever! If you can, use a higher crystal frequency (eg 16MHz).

If you need a really good, accurate sine wave at 5kHz or you want to be able to vary the frequency, this is probably not the best method of doing it. You could use a parallel input DAC for 8 bits resolution. If you need good accuracy/stability, a DDS (direct digital synthesiser) would be better, but is more complicated and expensive - ideal for signal generator test equipment though.

_________________
If all else fails, read the manual. Even better: read the manual before something fails. If you can't find it in the manual, search the forum.
BascomAVR 2.0.8.2
Back to top
View user's profile
AdrianJ

Bascom Expert



Joined: 16 Jan 2006
Posts: 2472
Location: Queensland

australia.gif
PostPosted: Wed Jan 30, 2008 9:47 pm    Post subject: Reply with quote

First you need to work out exactly how good a sine wave you need for the application.

Look up the ( very long ) series of posts about Jesper Hensens "poor mans DDS".

http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=1825&highlight=dds

That might give you some ideas. I use a variation of that idea with parallel DAC ( 8 bit ) and SPI to get the data from a wave table in external serial dataflash. Can get 8 KHz that way using 256 samples per cycle, and 4 MHz clock. You can get much faster ( or more accurate ) by using internal program flash, but then you cant have a variety of arbitrary waveforms - takes too much space, and you cant change the waveform 'on the fly'.

_________________
Adrian Jansen
Computer language is a framework for creativity
Back to top
View user's profile Visit poster's website
mattcro

Bascom Member



Joined: 03 Oct 2007
Posts: 324
Location: Scotland

uk.gif
PostPosted: Fri Feb 01, 2008 2:06 pm    Post subject: Reply with quote

Also have a look at this Elektor project: http://www.elektor-electronics.co.uk/magazines/2006/february/digital-sinewave-reference-generator.58118.lynkx

It's a 1kHz reference tone generator using an AT90S1200 (replaced by ATtiny2313) and TDA1543 16bit I2C DAC. It's programmed in assembler for max speed, but you can get some ideas from the design.

_________________
If all else fails, read the manual. Even better: read the manual before something fails. If you can't find it in the manual, search the forum.
BascomAVR 2.0.8.2
Back to top
View user's profile
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum