AVR DDS signal generator V2.0

Finally second and improved AVR DDS signal generator is here. First AVR DDS V1.0 generator was only an attempt of running DDS algorithm without any amplitude control. This time I still wanted to keep things simple like minimum count of widely accessible components circuit, single sided PCB that comes together with good functionality.

AVR_DDS_signal_generator_V2_0.jpg

AVR DDS specification

AVR DDS signal generator V2.0 is a firmware based DDS signal generator which uses slightly modified Jesper’s DDS algorithm adapted to AVR-GCC C program as in-line ASM. Signal generator has two outputs - one for DDS signal and another for high speed [1..8MHz] square signal - which may be used for reliving microcontrollers with wrong fuse settings or for other purposes as well. High speed (HS) signal is direct output from Atmega16 OC1A(PD5) pin. DDS output is used for all other signals that are generated via R2R resistor network and is adjusted via LM358N offset and amplitude regulating circuits. Offset and amplitude can be regulated by two potentiometers. Offset can be regulated in range +5V..-5V while amplitude in range 0..10V. DDS frequency range is from 0 to 65534Hz that is more than enough for testing audio circuits and other tasks.

Main AVR DDS V2.0 signal generator features:

  • Simple circuit with easily accessible and cheap components;
  • Single sided PCB;
  • In box power supply with external AC plug;
  • Dedicated high speed (HS) signal output up to 8MHz;
  • DDS signal with variable amplitude and offset;
  • DDS signals: sine, square, saw, rev saw, triangle, ECG and noise.
  • 2×16 LCD menu;
  • Intuitive 5 button keypad.
  • Frequency adjusting steps: 1, 10, 100, 1000, 10000Hz;
  • Restoring last configuration after power up.

In the block diagram you may see logical structure of signal generatorV2.0

AVR_DDS_signal_generator_V2_0_block_diagram.jpg

As you can see device requires several voltages: +5V, -12V, +12V, GND. -12V and +12V are used for offset and amplitude control. In this case power supply is constructed by using simple transformer and few voltage regulators.

AVR_DDS_2_0_power_supply_12_5V.PNG

Power supply block is assembled on a separate prototyping PCB board.

AVR_DDS_powersupply_board.jpg

If you do not want to build power supply you may use PC ATX power supply unit where all required voltages are available. You may need to modify molex connector wiring as follows:

ATX_molex_wiring.jpg

LCD menu control

All actions can be viewed in LCD menu. Menu can be controlled with 5 buttons that are next to LCD module

AVR_DDS_front_panel.jpg

Up and down arrow buttons are used for browsing menu while right and left arrow buttons are used for changing frequency value. When middle button is pressed - signal generating starts. Press middle button again to stop signal generator. Here is a complete menu system of signal generator.

Important to notice, that there is a separate menu for changing frequency step. This is convenient if you need to change generator frequencies in wide range. This allows to set any frequency with relatively few button clicks.

Noise generation don’t have frequency setting. It uses simple rand() function where results are continuously output to DDS output.

High speed signal has four frequencies available: 1, 2, 4 and 8MHz.

Circuit diagram and PCB

Circuit diagram of DDS generator (excluding power supply) is very simple with easy accessible components. It uses following parts:

  • AVR Atmega16 microcontroller clocked with 16MHz external crystal;
  • Standard HD44780-based 2×16 LCD module;
  • R2R DAC made of simple resistors;
  • LM358N low power dual op amplifier;
  • Two potentiometers;
  • 5 buttons;
  • several connectors and sockets.

Circuit diagram and PCB:

AVR_DDS_2_0_circuit.png

Single sided PCB:

AVR_DDS_2_0_pcb.JPG

Assembly

DDS generator is assembled in to plastic box:

AVR_DDS_signal_generator_inside_V2_0.jpg

Test run:

AVR_DDS_signal_generator_working.jpg

AVR DDS 2.0 Firmware

As I have mentioned DDS function is a modified Jesper’s DDS algorithm. Main modification is adding additional ASM line which enables to stop DDS generation. In version 1.0 the only option was to reset device, dds function checks if CPHA bit is set in SPCR register which is set during external interrupt service routine (stop button). So now algorithm takes 10 CPU cycles instead 9.

void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0){

asm volatile( “eor r18, r18 ;r18<-0″ “\n\t”

“eor r19, r19 ;r19<-0″ “\n\t”

“1:” “\n\t”

“add r18, %0 ;1 cycle” “\n\t”

“adc r19, %1 ;1 cycle” “\n\t”

“adc %A3, %2 ;1 cycle” “\n\t”

“lpm ;3 cycles” “\n\t”

“out %4, __tmp_reg__ ;1 cycle” “\n\t”

“sbis %5, 2 ;1 cycle if no skip” “\n\t”

“rjmp 1b ;2 cycles. Total 10 cycles” “\n\t”

:

:”r” (ad0),”r” (ad1),”r” (ad2),”e” (signal),”I” (_SFR_IO_ADDR(PORTA)), “I” (_SFR_IO_ADDR(SPCR))

:”r18″, “r19″

);}

DDS Signal tables has to be placed in flash sections where address starts with 0xXX00. So these sections has to be defined in makefile for proper memory placement:

#Define sections where to store signal tables

LDFLAGS += -Wl,-section-start=.MySection1=0×3A00

LDFLAGS += -Wl,-section-start=.MySection2=0×3B00

LDFLAGS += -Wl,-section-start=.MySection3=0×3C00

LDFLAGS += -Wl,-section-start=.MySection4=0×3D00

LDFLAGS += -Wl,-section-start=.MySection5=0×3E00

LDFLAGS += -Wl,-section-start=.MySection6=0×3F00

LCD control library is described here.

I don’t want to go too deep in code discussions. Source code is commented pretty well if there will be any questions and suggestions about source code - feel free to drop a comment.

Testing and discussion

I have tested signal generator with oscilloscope and frequency counter. Signals look like expected in all frequency range [1 to 65535Hz]. Amplitude and offset regulator works OK. If offset is set to 5V, then maximum clear signal amplitude may be 5V as another 5V is already used for offset(same is if offset is -5V).

Here are few test signals on oscilloscope screen:

AVR_DDS_sine.JPG
sine wave signal

 

AVR_DDS_square.JPG
square signal

 

AVR_DDS_triangle.JPG
triangle signal

 

AVR_DDS_saw_tooth.JPG
saw tooth signal

AVR_DDS_rev_saw_tooth.JPG
reverse saw tooth signal

AVR_DDS_ECG.JPG
ECG signal

AVR_DDS_noise.JPG
noise

AVR_DDS_high_speed.JPG
high speed 1MHz signal

I am thinking of adding sinus sweep functionality in future firmware updates. Maybe I will if there will be a need :)

Download latests firmware (WinAVR20071221) and source code version here (source code and hex[120kB])

Download EagleCAD schematic and PCB here ( EagleCAD project[45kB])

Blogsphere: TechnoratiFeedsterBloglines
Bookmark: Del.icio.usSpurlFurlSimpyBlinkDigg
RSS feed for comments on this post
 |  TrackBack URI for this post

New on WinAVR Tutorial
Running TX433 and RX433 RF modules with AVR microcontrollers,
Sometimes in embedded design you may want to go wireless. Might be you will want to log various readi …
Programming AVR ADC module with WinAVR,
Most of AVR microcontrollers have Analog to Digital Converter (ADC) integrated in to chip. Such solut …
New on WinARM Tutorial
What are differences between WinARM and WinAVR,
Everyone who is working with AVR microcontrollers knows this powerful tool – WinAVR (http://win …
LPC2000 watchdog timer,
As in all microcontrollers watchdog timers purpose isto reset microcontroller after reasonable amount …

22 Responses to “AVR DDS signal generator V2.0”

  1. Daily DIY Network - Science Projects Plans Guides » Blog Archive » AVR DDS signal generator Says:

    [...] on the website. Signal generators can be very expensive, this version shouldn’t break the bank. - Link [Read this article] [Comment on this article] Source: MAKE [...]

  2. H&B » Blog Archive » AVR DDS signal generator Says:

    [...] on the website. Signal generators can be very expensive, this version shouldn’t break the bank. - Link [Read this article] [Comment on this article] [...]

  3. Electronics-Lab.com Blog » Blog Archive » AVR DDS signal generator Says:

    [...] AVR DDS signal generator - [Link] [...]

  4. AVR DDS Signal Generator V2.0 » project hal0 Says:

    [...] http://www.scienceprog.com/avr-dds-signal-generator-v20 addthis_url = ‘http%3A%2F%2Fwww.ni-c.de%2F2008%2F03%2F11%2Favr-dds-signal-generator-v20%2F’; [...]

  5. DIY Pozostałe i Newsy :: Generator sygnałowy na AVR | Elektronika - schematy elektroniczne Says:

    [...] Źródło http://www.scienceprog.com/avr-dds-signal-generator-v20/ [...]

  6. TK_M Says:

    Excelent project. I wondered thought if others might be interested in my way of making custom “membrane” switches for projects?

    Design the artwork and print it out on a sheet of paper. Cut it out the correct size and put it in the middle of a laminate pouch and run it through the laminator. Mine is not a very good laminator, so I actually run it through again as soon as it comes out.

    Cut out the box and cut the laminated sheet to be at least 10mm larger than the hole. Run hot-melt adhesive around the hole inside the BOX. Place box face-down on a hard surface and place your laminated legend(s) in place. Quickly place a piece of polythene over that and a heavy object to flatten it all while the glue sets.

    using a sharp knife carefully scrape away any hot-melt adhesive that ouzed out onto the face of your legends while cooling.

    Mount the switches onto their own PCB or any inflexible surface and mount them behind the legend, fixing the edge of the board via spacers/washers to the box. the switches should be pressed into the legend just slightly when monuted.

  7. Billikin Says:

    Which fuse-bits is this Atmega16 using??

  8. scienceprog Says:

    Fuse settings with PonyProg
    Atmega16 AVR dds fuse setings

  9. The Vacar Perimeter » Sending mixed signals Says:

    [...] relationship. Instead, I want to bring to you attention the AVR DDS signal 2.0. Scienceprog.com has an article on it which links to the AVR DDS V1.0 generator as [...]

  10. Hazzer123 Says:

    Thankyou for the great tutorial on you signal gen. I was wondering, would you possibly be able to write your DDS algorithm in pseudo code? I am a PIC guy, and all that AVR assembly is driving me nuts :( .

    Thankyou greatly

  11. scienceprog Says:

    krazatchu made PCB modifications in order to get rid of smd. Also he made following modifications:
    1) added the power supply to the board to run from battery…
    2) removed the ISP to save space
    3) changed the pin header for lcd to 1×16
    4) fat traces for toner transfer…
    5) separate ground returns for analog and digital…
    Just follow forum thread
    http://forum.scienceprog.com/viewtopic.php?f=9&t=281&p=399#p399
    So if you like printer toner transfer pcb technology, you can choose this option.

  12. BudFrog99 Says:

    It will be very interesting when we can get our hands onto Xmega chips with the streaming DMA DACs, and what kind of DDS we can cook up then.

  13. Anatoliy Says:

    I’ve assembled V2.0 DDS generator.
    It doesn’t work:
    1) LCD display without any character. There are black rectangles in the upper line only.
    2) There is not any pulse at PC0…PC7 outputs (found by oscilloscope)

    Several times I did READ and WRITE operations. So MEGA16 is in good condition.
    It might be FUSE bits are not O.K.
    Here are the latest FUSE bits, which I got from the chip:

    Fuses
    OSCCAL = B1, B1, AC, AF
    BODLEVEL = 0
    BODEN = 1
    SUT = 2
    CKSEL = E
    BLB1 = 3
    BLB0 = 3
    OCDEN = 1
    JTAGEN = 0
    CKOPT = 0
    EESAVE = 1
    BOOTSZ = 0
    BOOTRST = 1

    Would you please give me advice how to solve this problem?

  14. scienceprog Says:

    It is hard to say now. Above you can see fuse settings done with PonyProg software. According to your settings seems to be that CKSEL is wrong. Should be CKSEL=F.

  15. Anatoliy Says:

    I tried CKSEL=F also, but with the same result.

    I used another ISP programmer. I used it many times for many different projects.

    Would you please answer to my E-mail directly

  16. Ghelesel Says:

    Can you add in software duty cycle??Wich compiler you use??

  17. scienceprog Says:

    Compiler is WinAVR AVR-GCC.
    Adding duty cycle would be a little bit complicated. Probably best solution would be to use HS output and change duty cycle by changing timer output compare parameter. Right now I am not planing on adding this functionality. But you are free to modify the code.

  18. Juris Perkons Says:

    Hello,
    thanks for this interesting project, but i have the same problem as Anatoliy, it wont start, black rectangles on LCD. It is not mt first AVR or/and PIC project, so i am confused, what I do wrong? I use serial COM port programmer and PonyProg software with fuses as in picture in this thread. Any ideas and help please? :)
    Thank You in advance!

  19. Juris Perkons Says:

    It started working, i just didnt write right fuse settings with PonyProg (how typical :) ).

  20. jack Says:

    Hi
    what type of complier did you used?

  21. YO4HFU Says:

    For PonyProg selected fuse:OCDEN, BOOTSE1 and BOOTSE0.Now my DDS work…73!

  22. retro2783 Says:

    Ok…
    I keep getting a non-working atmega16 (LCD top row lit only). I am using STK500 with AVR Studio 4 to program the atmega16. I would guess that it’s not working because of the fuse settings. Can someone who used AVR Studio successfully make a screen shot of the fuse settings please.

    Also, with the osc fuse, should it be set to one of the “ext crystal” settings, because the schematic uses a crystal with 18pf caps.

    PS… This is probably a stupid question but I should be programing the FLASH right? With AVR Studio you can program the FLASH and/or EEPROM.

Leave a Reply