Based on a discussion about poly-phase signal generation in one of the ARV forums a week or so ago, I am looking at implementing a software derived single phase sine-wave generator, using two hardware timers and any necessary software schemes at my disposal. Once this goal is worked out, the plan is to move on to creating a 3-phase sine wave reference sub-system.
The following represents about a week of writing and rewriting a theoretical thesis on for a 3-phase system. As the process of that thought experiment progressed, I realized there was much I did not know about creating a simply single phase sine wave generation. As such, I have taken a step back and wrote the following detailed theoretical analysis required to create a low distortion single phase sine wave using the hardware/software resources of the AVR.
I really don't think there is much in the way of actually creating the software for this endeavor. The real timer consuming part will be creating the 256 sine wave data table.
At any rate, I figured I would offer up my work on the forum, in the hopes that others with more experience in this area would have some meaningful input and direction.
GOAL: My initial concept is to use two hardware timers. One hardware timer is to be used to generate a 20.000KHz PWM carrier frequency. The duty cycle of the 20.000KHz PWM carrier would then be modulated by a data table that builds a complete sine wave. The frequency of this PWM derived sine wave will be selectable between 50Hz or 60Hz and, if possible, incorporate the ability to be continuously variable from 0Hz to 400Hz, with the mode of operation to be determined at system initialization. APPROACH: The first hardware timer, the Alpha timer, will be used to generate the PWM sin-wave being modulated onto the 20.000KHz PWM carrier, using 8-bit CTC PWM mode and generate no output. The second hardware timer, the Beta timer, will be used to actually generate the 20.000KHz PWM being modulated Alpha timer by the incremental addressing of the sine wave data table. The PWM hardware I/O output pin will be directly controlled by the Beta timer in 8-bit CTC PWM mode. The final result should be a sine-wave output that, with proper filtering, will produce a low distortion sine-wave. RESOURCES & PARAMETERS: The following resources and parameters are what I believe will be the absolute basic requirements for the implementation of a digitally derived sine-wave generator. uC = ATMega328P. Fosc - 18.432MHz. Modulation frequency = 50Hz/60Hz - eventually, continuously variable. Carrier frequency = 20.000KHz. One 8-bit Alpha hardware modulation timer = 60 x 256 = 15.360 interrupts per second. One 8-bit Beta hardware PWM timer = 20.000 interrupts per second ---> 20.000KHz PWM. Private: One 256 element array, used for the sine-wave data table, holding the 256 pre-calculated sine-wave PWM modulation data points that will be accessed via the Beta timer interrupt handler. Private: One data table address counter - the source of the address used to access the sine wave data table Global: One Dwell-time register - Dwell time interrupt handler simply increments the Dwell-time register by 1 with every entry. Upon entry, the Beta Dwell time interrupt handler will take the current data table address counter and copy it into the Dwell-time register. This address is used by the Beta timer interrupt handler to access the 256 element sine wave data table, the value of which, gets stored it in the Beta timer OCR register. Control of the PWM I/O pin is automatically turned on and off by the Beta timer. I'm thinking that, the interrupt frequency relationship between the Alpha hardware timer interrupt event rate needing to be slower than the Beta hardware timer interrupt event rate is pretty important. I think this relationship is important because, at least one Beta PWM timer interrupt event MUST be performed (or at least started) for every Alpha timer interrupt event - more beta events per Alpha event would be preferable. This is necessary to ensure that the Beta counter never misses a sine wave data point. As defined above, the ratio between the Alpha & Beta timers, is: 20,000 / 15,360 = 1.3. SCOPE: As stated above, the data used to generate the single phase sine-wave will be pre-calculated and held in a 256 element sine wave data table. And, the data held in the Sine wave data table constitutes one complete sine wave cycle. That is, a complete sine wave will be generated using all 256 elements or data points being held in the sine wave data table. The PWM frequency of the Beta phase timer will be set to generate a 20.0KHz PWM output and needs to be established using a hardware timer with the highest interrupt priority. The sine wave modulator, the Alpha timer, will generate an interrupt at a rate of 256 interrupts per single 50Hz or 60Hz sine-wave cycle and will be the lower of the two timer interrupt priorities. Using the pre-calculated sine-wave data in the 256 element sine-wave data table, the Alpha and Beta counters will work in concert to modulate the duty cycle of the 20.000KHz frequency being generated by the Beta timer at the respective PWM I/O pin. While the Beta timer has a higher interrupt priority over the Alpha timer, the movement of sine-wave data between the Alpha timer interrupt handler and the Beta timer interrupt handler is directly dependent on the incrementing of the 256 element data table address counter within the Alpha timer interrupt handler. On entry, the Alpha timer interrupt handler moves the current value of data table address counter and copies it to the Dwell-time register. The data table address counter is then incremented by 1, pointing to the address to be used in the next Alpha timer interrupt event. The Beta timer interrupt handler uses the current data table address being held in the Dwell-time register to access the current sine-wave data point and store it in the Beta timer respective OCR register. This process is repeated until the entire 50Hz/60 Hz wave form is constructed. What I am not sure of at this time is if there is a need to for some form of synchronization or hardware/software handshaking between the Alpha & Beta timer interrupt handlers, for smooth, reliable sine-wave data point transfer to take place. Or, is the creation of a single phase sine-wave really that simple that data movement between the Alpha & Beta interrupt handlers be done asynchronously. WHAT TIME IS IT, EXACTLY? With the Fosc, PWM modulation (Alpha timer) and PWM carrier (Beta timer) frequencies defined, time and instruction budget calculations seem in order. I.E. the interrupt processing times and the number of instruction cycles for the Alpha & Beta interrupt. Starting off, the Instruction Cycle Time is: ICT = 1 / Fosc = 1 / 18.432000 = 54.25347222nS - non terminating. If the waveform we are trying to develop is say, 60Hz (the more time constrained between 50Hz & 60Hz) and, if it takes 256 steps to build one complete waveform then: the allotted Alpha Interrupt Cycle Time is: 1 / (60 * 256) = 65.1uS. Similarly, the allotted Beta Interrupt Cycle Time is: 1 / (20.000KHz) = 50.0uS. The number of single CLK cycle instructions that can be executed per Alpha interrupt event is: n = 65.1uS / 54.25nS = 1,200 single cycle instructions per Alpha interrupt. The number of single CLK cycle instructions that can be executed per Beta interrupt event is: n = 50.0uS / 54.253nS = 921.6 single cycle instructions per Beta interrupt. The interrupt time/instruction cycle budgets calculated above should be enough time to build a low distortion sine-wave using the ATMega328P microcontroller, running with an Fosc of 18.432MHz
If the above analysis of correct, I'm thinking that a 0Hz to 400Hz option isn't possible.
Thoughts and suggestions are most welcome !