AVR controlled DDS generator software writing
During my spare time I am developing the program for AVR controlled DDS generator. I decided to write software using WinAVR tool-set. How far ahead I have moved with this?
I have implemented:
- Menu system;
- Reading previous generator configuration from EEPROM;
- Setting signal mode;
- Storing last generator configuration to EEPROM to be loaded after reset;
- Four types of signal output (square, sawtooth, triangle and sine wave);
Still need to do:
- Ability to change signal frequency;
- Implement other signals (listed bellow);
- Make program clean-up;
Signals in AVR controlled generator:
- 0 – OUT_|¯|_ - square wave(done);
- 1 – OUT|/|/| - sawtooth(done);
- 2 – OUT|\|\| - reverse sawtooth(awaiting);
- 3 – OUT/\/\/\ - triangle(done);
- 4 – OUT~~~~ - sine wave(done);
- 5 – OUT-NOISE – noise signal(awaiting);
- 20 – PWM-OCC – timer output compare mode(awaiting);
- 21 – PWM-SINMDS – sine wave modulated PWM(awaiting);
- 22 – PWMSQSMDS - sine wave modulated PWM. PWM positive, SQ – negative polarity(awaiting);
- 23 – PWM-CMDS – custom PWM. Will be possible to set custom duty cycle(awaiting);
Signal generation
Square, sawtooth, triangle and sine waves are generated by reading values from flash memory. Fragment of sine wave is as follows:
//———————————————–
//signals saved in flash memory
const uint8_t sinewave[] PROGMEM= //256 values
{
0×80,0×83,0×86,0×89,0×8c,0×8f,0×92,0×95,0×98,0×9c,0×9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0×9f,0×9c,0×98,0×95,0×92,0×8f,0×8c,0×89,0×86,0×83,
0×80,0×7c,0×79,0×76,0×73,0×70,0×6d,0×6a,0×67,0×63,0×60,0×5d,0×5a,0×57,0×54,0×51,
0×4f,0×4c,0×49,0×46,0×43,0×40,0×3e,0×3b,0×38,0×36,0×33,0×31,0×2e,0×2c,0×2a,0×27,
0×25,0×23,0×21,0×1f,0×1d,0×1b,0×19,0×17,0×15,0×13,0×12,0×10,0×0f,0×0d,0×0c,0×0a,
0×09,0×08,0×07,0×06,0×05,0×04,0×03,0×03,0×02,0×01,0×01,0×00,0×00,0×00,0×00,0×00,
0×00,0×00,0×00,0×00,0×00,0×00,0×01,0×01,0×02,0×03,0×03,0×04,0×05,0×06,0×07,0×08,
0×09,0×0a,0×0c,0×0d,0×0f,0×10,0×12,0×13,0×15,0×17,0×19,0×1b,0×1d,0×1f,0×21,0×23,
0×25,0×27,0×2a,0×2c,0×2e,0×31,0×33,0×36,0×38,0×3b,0×3e,0×40,0×43,0×46,0×49,0×4c,
0×4f,0×51,0×54,0×57,0×5a,0×5d,0×60,0×63,0×67,0×6a,0×6d,0×70,0×73,0×76,0×79,0×7c
};
//———————————————–
The same is with square, sawtooth and triangle. Each wave is stored using 256 value table.
Signal is generated using simple function:
//———————————————–
void signalOUT(const uint8_t *signal)
{
uint8_t i;
i=0;
do
{
PORTD=pgm_read_byte(&signal[i++]);
}while(1);
}
//———————————————–
Using this function the maximum generated signal frequency was 6,25kHz. This means that one signal period consists of 256 values from signal table. Crystal frequency is 16MHz. So for one value from table it requires 16000000/(6250*256)=10 clock cycles.
Changing frequency of those signals should be ease. Just insert inside loop delay function regarding to selected frequency. This I will do later.
I still don’t know is it worse to try increase maximum frequency of signal. Now it is 6,25kHz and takes 10 clock cycles for one byte from 256 to output. If I would reach 5 cycles, that would be double frequency 12,5kHz.
In other hand if greater frequencies are needed there will be possibility to use timer signal generator on output compare mode, but only square waves.
Now I going to focus on implementing what I have planned and then think about optimisation.
Bellow are signal pictures I have got at frequency 6,25kHz(picture quality is poor - I really need to get tripod for my camera):

Square

Sawtooth

Triangle

Sine wave
The source code of current program is here:AVR controlled DDS generator software
Full documentation is on its way.
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 … |

August 24th, 2006 at 12:28 am
interesting… i have made some changes for me on this code.
maybee you are intrested in..
how do you want to change the frequency of the output?
August 24th, 2006 at 4:48 pm
I am comming with an improved code where I use DDS algoritm (use accumulator variable) where I can change frequency very easely by changing this value. This algorithm in this article is first one to test my hardware. I hope to finish this project very soon and publish it here.