Understanding Interrupt in DDS Sine Gen

Hi,

I’m playing around with Martin Nawrath’s DDS Sinewave Generator (http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/) and I’m trying to understand the code. At it’s most basic, I get what most of it is doing. I’ve been able to create arrays with values for square waves, triangle waves, ramps, and what-not and have them play back but I’m having trouble understanding how it actually reads through the arrays.

The part of the code in question is this:

ISR(TIMER2_OVF_vect) {

  sbi(PORTD,7);          // Test / set PORTD,7 high to observe timing with a oscope

  phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits
  icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
                         // read value fron ROM sine table and send to PWM DAC
  OCR2A=pgm_read_byte_near(sine256 + icnt);    

  if(icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds
    c4ms++;
    icnt1=0;
   }   

 cbi(PORTD,7);            // reset PORTD,7
}

I get that when the timer2 interrupt occurs this function is called and I get what the sbi and cbi calls are doing (though I don’t need that functionality since I don’t have an oscope yet), but I don’t understand how this interrupt outputs the values in the sine256 array at the correct intervals/frequency. I know it’s just a lack of knowledge on my part (this is one of my first ventures into microcontrollers and programming in general) but I’m wondering if anyone can help me. An initial search turned up nothing.

Thanks!

An initial search turned up nothing

Google "phase accumulator"

sbi() and cbi() are assembly instruction to set or clear a bit directly on a port. Those functions are just wrappers around the instruction to make the code as efficiently as possible.

Korman

Sorry, I wasn't clear in my initial post. I understand what sbi() and cbi() are doing just not what the timer2 interrupt as a whole is doing.

Reading about phase accumulator now, thanks.

I think it's a about time that someone should make a complete tutorial for a complete noob how to create a sinewave using the arduino, to explain how timers and their specific registers work,
how interrupts are implemented in such project, how a sine table is calculated and defined. I know there's plenty information on the internet (avrfreaks and such) but that info is for profesional programmers and electronics designers that have plenty of expirience and understanding, and mosto of us are just mere mortals that just have entered the world of microcontrollers so please help. :-/

Don't take this the wrong way I am still a noob and in my current project I need to generate a PWM that in a kind of way mimics sinewave (SPWM), the PWM will switch powerful transistors in a H-bridge (in diagonal pairs) to create this PWM sinewave for a 1PHASE Induction Motor.

THIS IS MY PERSONAL OPINION!

I think it's a about time that someone should make a complete tutorial for a complete noob how to create a sinewave using the arduino

let us know when you are done, and we'll provide feedback.

I don't think noobs who don't understand basic arithmetic (for that is all a phase accumulator is) should be writing software to control 'powerful' hardware that moves and could therefore potentially cause injury.

THIS IS MY PERSONAL OPINION

Well, after researching what a phase accumulator was (fancy name for a counter/address offset) and understanding what pgm_read_byte_near() was doing, I still don't understand how that controls the PWM at pin 11. I see that OCR2A is an output compare register but I can't find any information on how that affects or controls the PWM.

Regardless, I understand how this works at the functional level and I'm curious if there's a way to do the same thing with a parallel 8-bit DAC on PORTD. In my mind, it should work. Just write the value from pgm_read_byte_near(sine256+icnt) to PORTD but I want to know if I'm missing anything.

I don't think noobs who don't understand basic arithmetic (for that is all a phase accumulator is) should be writing software to control 'powerful' hardware that moves and could therefore potentially cause injury.

THIS IS MY PERSONAL OPINION

Well it's not just about the phase accumulator, it's about how the whole proccess of creating that sine is done.
Everyone started from scratch eventually and tries to understand what is before him, nobody was born with the knowledge of those before him( though I don't know to what point the experiments with DNA memory have progressed :slight_smile: ).So this is why I am asking for help.
For starters how the sine look up table is calculated?

And don't worry everything is tested before entering real service and as always there's 'hardware' failsafe solution in parrallel :wink:

To create a array of values for a sinusoid, first decide how many values are going to be in that array. For example, say you're going to use 32 values. Then decide what level of resolution you want on that sine wave. Let's say 8 bits (max value of 255). In a tool like Excel, do something like this: (sin(2[ch8719]/(32x))*127)+127 where x is the index in the array plus 1. That's how I did it, at least. It seemed to work for me but now I'm just having trouble understanding how the OCR2A register controls the PWM.

(I know you were being rhetorical about the sine wave table but hey... ::))

Edit: I think I figured it out.

GtrBMart I'll contact you someday about that DDS Sine Gen for tutoring and clarification so be prepared, I am serious, I hope you're fine with that? :-?

GtrBMart I'll contact you someday about that DDS Sine Gen for tutoring and clarification so be prepared, I am serious, I hope you're fine with that?

If you'd like! I think I understand most of it now. I think my misunderstanding mostly stemmed from not knowing how the ATMega worked. I sure wouldn't mind some clarification though!