Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Direct Digital Synthesis. (DDS)
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
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
AdrianJ

Bascom Expert



Joined: 16 Jan 2006
Posts: 2483
Location: Queensland

australia.gif
PostPosted: Mon Mar 27, 2006 9:34 am    Post subject: Reply with quote

Sorry for that, comes from writing code "on the fly"

the statements
lds zl,{low wWavetable}
lds zh,{high wWavetable}

should be
lds zl,{wWavetable}
lds zh,{wWavetable+1}

to get z pointed at the value loaded into the word wWavetable in ram.

It is really easy to get confused about the various forms of syntax for pointers in rom and in ram, and whether you want the value of a variable, or its address.

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

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Mon Mar 27, 2006 11:45 am    Post subject: Reply with quote

Hello Luciano,
Many thanks for the comprehensive answer to my post. I believe I can follow your code but could never had originated it - still many months away from this level.

That's a busy interrupt routine - more than I would have comtemplated. I look forward to trying it.

BTW - back in the '70s when function generators were high tech there was a great myth about dovetail waveform generators. Imagine a square wave with a rise time that goes back in time (T anticipation) and a fall time that also goes back in time (T hesitation) While I never saw a dovetail waveform generator I know a few who made raster scans on their 'scopes that looked like they had "cracked" it.

Thanks again.

Cheers,
David
Back to top
View user's profile
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Mon Mar 27, 2006 12:00 pm    Post subject: Reply with quote

Hello Adrian,
Thanks for the update.
I will go back and revisit this. Luciano has kindly posted all I need to get underway but I also need to understand the process involved rather than just have code handed to me so I will go back and play a bit more to help my understanding.
I agree - even without syntax it's very confusing trying to learn about variable contents and variable addresses. Will keep chipping away.....

Cheers,
David
Back to top
View user's profile
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Mon Mar 27, 2006 12:18 pm    Post subject: Reply with quote

Hi,

Just one quick note to avoid confusion:

The code sample I have posted yesterday and the code sample I have posted last
week have the table(s) in ROM only. (The table is not copied from ROM to RAM).

As far I understand, for now, David is working on code with the tables in
ROM only. It makes sense to load the table in RAM, but if we jump back and
forth between the two solutions this thread will be difficult to follow.

Please specify clearly in your post if the table is copied first from
ROM to RAM and then its values read from RAM.


* * *

David,

You are welcome!

I have edited the sample code posted yesterday.
(Eliminated 3 lines of redundant code, "Set Eifr.6" moved down, comments improved).

About the interrupt routine:

Yes, it looks strange but it will work. If you add a 4x4 keypad
and an LCD, the keypad will be read in polling mode from within
the interrupt routine. (The keypad will also trigger the interrupt).

Best regards,

Luciano
Back to top
View user's profile
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Mon Mar 27, 2006 10:58 pm    Post subject: Reply with quote

Hello Luciano,
Yes I am still using the wave tables in the code space and not in SRAM. May try that later. Will also try the keypad - I had this on my Pic version and it was really nice to tap in the numbers.
I don't have a need for a signal generator as I have good audio generator but DDS has always fascinated me and it also allows you to write your own waveform (dovetails) as well as having programmable precision.

I think it should be possible to make an FSK sender from the DDS by converting the input data to binary and switching between two set frequencies. As mentioned before, it should also be possible to run two (smaller ) accumulators and generate two waveforms, sort of analog DTMF

Thanks again for your input. I will take little steps so I don't break anything.

Cheers,
David
Back to top
View user's profile
jenalcom

Bascom Member



Joined: 10 Apr 2004
Posts: 365
Location: Perth, Western Australia

australia.gif
PostPosted: Fri Mar 31, 2006 5:34 am    Post subject: Reply with quote

Bascom already does that to produce DTMF!

And it will also work with a standard 3.579545MHz crystal so you can run a decoder of the same clock.

Alan
Back to top
View user's profile
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri Mar 31, 2006 8:40 am    Post subject: Reply with quote

David was talking about FSK, not DTMF.
(Read "sort of analog DTMF").

Luciano


(Click to enlarge the picture)


Last edited by Luciano on Mon Dec 04, 2006 5:57 pm; edited 1 time in total
Back to top
View user's profile
jenalcom

Bascom Member



Joined: 10 Apr 2004
Posts: 365
Location: Perth, Western Australia

australia.gif
PostPosted: Fri Mar 31, 2006 12:18 pm    Post subject: Reply with quote

He actually did mention DTMF Smile

<quote>
As mentioned before, it should also be possible to run two (smaller ) accumulators and generate two waveforms, sort of analog DTMF
</quote>

Using the same (similar) code it should also be able to generate FSK.

Personally I always use square waves for FSK, especially as most FSK (I use) is sent over severely limited bandwidth links (eg radio with 2.4KHz b/w). I normally use a timer in auto reload mode to generate the square wave. I have thought about using DDS for this but never got that far with the idea.

Of course if you wanted to get really clever you would be able to do Phase Shift Keying as well or perhaps even QAM and other modulation schemes. Unfortunately I think the loop size would probably get too large too quickly. May be worth investigating if you have a high enough cloak frequency.

Alan
Back to top
View user's profile
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Sun Apr 02, 2006 12:00 am    Post subject: Reply with quote

Hi,
I did indeed mention FSK and DTMF, not for any specific task but more to highlight the flexibility of the DDS.
Phase shift keying should be straight forward as would quadrature waveforms (or any phase)
It should be possible to generate 3 phase sinewave using three output ports but a single accumulator and three table reads. These would be the calculated table value, table value plus 60 degree offset, table value plus 120 degree offset. Not sure if it would have any applications but the theory is nice.

Cheers,
David
Back to top
View user's profile
AdrianJ

Bascom Expert



Joined: 16 Jan 2006
Posts: 2483
Location: Queensland

australia.gif
PostPosted: Tue Apr 04, 2006 2:20 am    Post subject: Reply with quote

Yes, I do more things with this DDS than just a single tone. In fact I have twin outputs from the same wavetable, but I can adjust both independently for both amplitude and relative phase. So I can synthesise a "stereo" effect by both delaying one wave with respect to the other, and reducing its amplitude, to give the effect of turning the head. Only works with phones on, but its fairly effective. The amplitude effect seems to be the most obvious, the phase effect is difficult to pick by itself.
_________________
Adrian Jansen
Computer language is a framework for creativity
Back to top
View user's profile Visit poster's website
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Fri May 12, 2006 6:52 am    Post subject: DDS Reply with quote

Hi,
Over the last month I have had stolen just enough time to make a real pigs ear of the code that Luciano posted and have got myself in to trouble.

I have learned how to add the keypad and LCD to this Mega168 DIP but was not impressed with the chip pin layout or the peripheral feature placement.
Why did they put the xtal on one of the full 8 bit ports and the UART on the other full port, leaving the incomplete 7 bit port alone? Huh? Surely you would trash an incomplete port first?

Anyway, I have removed the xtal and are running off the internal osc for the time being but I have made a mess of the interrupts. I currently have portb.7 as an interrupt but would like to use the keypad eventually. I have used a GOTO instead of return for the ISR just to make something happen but I know it's not correct. The present code starts with the preset frequency values then the interrupt clears it and waits for the keypad input. The value input is then loaded in to the phase register and the new frequency is output. Then nothing else happens - no interrupt. BTW the lookup table offset is not indexed to a boundary either but this is minor compared to the other problems.

Can someone show me how to get my interrupt to be more than a one shot?

Best regards,
David
Back to top
View user's profile
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri May 12, 2006 9:54 am    Post subject: Reply with quote

David,

From the Bascom Help file:

ON INTERRUPT

The first RETURN statement that is encountered that is outside a condition will generate a RETI instruction. You may have only one such RETURN statement in your interrupt routine because the compiler restores the registers and generates a RETI instruction when it encounters a RETURN statement in the ISR. All other RETURN statements are converted to a RET instruction.


From the code you have attached:
Code:

lowerline
lcd add16 ; "   " ; add8 ; "   " ; add0
return


This RETURN will make the compiler generate a RETI instruction and the execution
will go back to the main loop. Because of that, "Enable PCInt0" will never be
executed.

Best regards,

Luciano
Back to top
View user's profile
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Fri May 12, 2006 11:20 am    Post subject: Reply with quote

Hello Luciano,
Thanks for that. That return is the return from the regval gosub. I tried restructuring that to in-line code rather than the gosub and although it appears to be working it does not load the correct values in to the phase accumulator anymore.

Will do some more fiddling now you have pointed that out.

Thanks again.

Cheers,
David
Back to top
View user's profile
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri May 12, 2006 12:07 pm    Post subject: Reply with quote

Hi David,

The 6 assembly lines below are the main loop. When the
interrupt occurs, the execution will stop somewhere in
these 6 lines of code. When you return from the interrupt,
the execution will resume where it was left when the interrupt
occurred. Again, you don't know where in these 6 lines of code.

Code:

Main_loop:

  add  r28,r24        ' 1 cycle
  adc  r29,r25        ' 1 cycle
  adc  r30,r26        ' 1 cycle
  lpm                 ' 3 cycles
  Out Portb , R0      ' 1 cycle
  rjmp Main_loop      ' 2 cycles
 
 

==========================================

Interrupt code:

The last lines of code before you go back to the main loop
must be like that:

Code:
' Your interrupt code in Basic or assembly
...
...
...
...
...
' The final lines of the interrupt code

If wave_form = 0 Then

   'Must be last two lines of code in this IF
   !ldi  ZH,high (Sine_table * 2)     ' setup Z pointer hi
   !ldi  ZL,low (Sine_table * 2)      ' setup Z pointer lo

End If


If wave_form = 1 Then

   'Must be last two lines of code in this IF
   !ldi  ZH,high (Square_table * 2)   ' setup Z pointer hi
   !ldi  ZL,low (Square_table * 2)    ' setup Z pointer lo

End If


If wave_form = 2 Then  

   'Must be last two lines of code in this IF  
   !ldi  ZH,high (Triangle_table * 2)  ' setup Z pointer hi
   !ldi  ZL,low (Triangle_table * 2)   ' setup Z pointer lo


End If


If wave_form = 3 Then  

   'Must be last two lines of code in this IF
   !ldi  ZH,high (Sawtooth_table * 2)  ' setup Z pointer hi
   !ldi  ZL,low (Sawtooth_table * 2)   ' setup Z pointer lo

End If


Set EIFR.6   ' clear Int0 flag set by contacts bouncing.
' See the datasheet of your AVR for the location of the "External Interrupt Flag"

!ldi  r29,$00     ' clear accumulator
!ldi  r28,$00     ' clear accumulator

Loadadr Adder_bits_0_7 , X       'load the address of the variable into R26 and R27 (X)
!ld r24, X                       'load the value of the variable into R24

Loadadr Adder_bits_8_15 , X      'load the address of the variable into R26 and R27 (X)
!ld r25, X                       'load the value of the variable into R25

Loadadr Adder_bits_16_23 , X     'load the address of the variable into R26 and R27 (X)
!ld r26, X                       'load the value of the variable into R26

Enable Int0

Return

 

======================================

From your code:

Code:

ldi r30, $00
 


This is wrong. R30 and R31 are the Pointer-register Z.
Remove this line.

Best regards,

Luciano


Last edited by Luciano on Fri May 12, 2006 2:03 pm; edited 1 time in total
Back to top
View user's profile
davidapex

Bascom Member



Joined: 12 Mar 2006
Posts: 42
Location: Auckland

newzealand.gif
PostPosted: Fri May 12, 2006 1:25 pm    Post subject: Reply with quote

Hi,
I think I follow that. That also explains why it sort of worked when I used a goto Begin: instead of the Return. I had got confused about where the interrupt was actually happening. I need to have a long hard look at it again - good thing it's the weekend.

Cheers,
David
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
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 2 of 6

 
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