## PWM

30 posts / 0 new
Author
Message

So I have started to try and write a program that will drive a three phase inverter using space vector modulation

I have my hardware

I need to generate three PWM outputs phase corrected so its count up and count down, I would ideally like to generate an interrupt on the peak of the count up to update the modulation indices (duty cycly)

So I am reading the data sheet

As a first stab I will try and have 20kHz switching frequency which looking at the data sheet timer 2 in pahse correct PWM doesn't have the possibilty to vary the TOP value, hence its only possibly to change the prescaler

With 8MHz clock and prescaler of 1 then the PWM switching frequency can only have a maximum frequency of

PWMfreq=8000000/(1*510)

PWM = 15.686kHz

Is this right?, i.e I need to use timer 0 and timer 1 if I want 20kHz switching frequency

Let me look a bit harder at how to setup PWM and generate an interrupt from the same timer, I am on it!

This is taking way longer than I expected it to, why is life never simple

The parameters so far

```TCCR1A|= (1<<WGM11)(1<<COM1A1)(1<<COM1B1)(1<<COM1A0)(1<<COM1B0)// PWM mode 10 where top is set by ICR1, inverted mode

TCCR1B|=(1<<CS10)(1<<WGM13)//prescale of 1

ICR1=200;```

I believe with an 8MHz clock that gives me 20kHz PWM in mode 10, inverted so that the PWM is high when it counts up to the OCR1A value and goes low when it counts under the OCR1A

Am I right so far?

Last Edited: Thu. Oct 2, 2014 - 12:57 PM

Am I right so far?

Which AVR model?

Why are you connecting OC1B to the timer?  What waveform do you expect on that pin?

Have you gone through the Tutorials forum articles with "timer" or "pwm" in the title?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Figure 16-8. Phase Correct PWM Mode, Timing Diagram

What does that diagram and associated text indicate?

Is there a reason to select dual-slope operation?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

So I have started to try and write a program that will drive a three phase inverter using space vector modulation

Isn't there an app note on exactly that?  Hmmm--lots of "generic" motor drive app notes; the "space vector" one is for AT90PWM3.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Which AVR model?

ATMega328P

Why are you connecting OC1B to the timer?  What waveform do you expect on that pin?

I dont think I understand what you mean, I am expecting PWM waveforms on the pins I set up, if I am doing it wrong then or mixing up bits feel free to comment

Have you gone through the Tutorials forum articles with "timer" or "pwm" in the title?

I have and its just a case of looking at the data sheet  which I am doing, its learning all the different bits etc, whats easy to you isn't easy to another

What does that diagram and associated text indicate?

Its table 15-8 in the data sheet I have, it explains what I am trying to do

Is there a reason to select dual-slope operation?

Its centre aligned PWM, it is the best way to perform SVM as only one power device switches at a time and the harmonics cancel the best using this method there are other reasons which I can't remember now

Isn't there an app note on exactly that

I am sure that there is, unfortunately I don't have time to read every single document out there but I don't think I need to, I just need to set up the PWM as I do know what I need to do its just setting up the processor

This is what I have so far

/*
* Three_Phase_SVM.c
*
* Created: 02/10/2014 09:21:22
*  Author: User
*/

#define F_CPU          8000000UL
#include <avr/io.h>
#include <stdio.h>

/*-----------------------------------------------------Function Prototypes------------------------------------------------------*/
void     Setup_PWM(void);

/*------------------------------------------------------------------------------------------------------------------------------*/

int main(void)
{

Setup_PWM();
OCR1A=0;
OCR1B=0;
ICR1=200;
while(1)
{

}
}
/*------------------------------------------------------------------------------------------------------------------------------*/
void Setup_PWM()
{
TCCR1A|= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0);
TCCR1B|= (1<<WGM13)|(1<<CS10);
DDRB  |= (1<<PB1)|(1<<PB2);
}

/*------------------------------------------------------------------------------------------------------------------------------*/

I have an 8000000 MHz clock, I want a 20kHz PWM period so its 400 clicks of the clock, hence I set ICR1 to 200 and it will take 25us to get to top

Inverted mode

Does this look right?

Any tips

Does this look right?

Again, why are you fussing with OC1B and the COM1Bn bits?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Isn't there an app note on exactly that

I am sure that there is, unfortunately I don't have time to read every single document out there

Perhaps not, but if there is an app note that not unlikely treats the very subject you need help with then IMO you should at least have a look at it.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Does this look right?

You have set both OCR1A and OCR1B to 0 which gives you 0% duty cycle, so you won't see anything on the outputs.

Again, why are you fussing with OC1B and the COM1Bn bits?

Perhaps because he wants output on both OC1A and OC1B.

Regards,
Steve A.

The Board helps those that help themselves.

Again, why are you fussing with OC1B and the COM1Bn bits?

Lee sorry I havent been very clear, I need to generate three PWM signals, I am going for 20kHz and because I want phase correct with an 8MHz clock then

PWMfreq=8000000/(1*510)

PWMmax = 15.686kHz

So that rules out timer 2 and I now am left with timer 0 and timer 1, this thread is just the start and my first task is to get two PWM channels going on timer 1

So I need to set the OC1B and COM1Bn bits

Perhaps not, but if there is an app note that not unlikely treats the very subject you need help with then IMO you should at least have a look at it.

I can't disagree with this comment and the first thing I did after my last post was to check it out and it is quite a good description of SVM but I didnt put myself very clearly, as it does sound like I was saying that I don't read documents or suchlike but what I was trying to say is that for this task it wasn't the SVM stuff I needed help with it was just setting up the PWM, I had the datasheet and a number of tutorials in front of me and I kind of knew what to do looking at appnotes or similar projects just adds another layer with stuff I have read many times and let me tell you out of all those space vector tutorials out there that I have looked at over the years theres not one that explains it as clearly as it can be, I never fully tackled it by just reading books or doing sims

I would say that AT90PWM3 is one of the best I have seen but the software isnt in the documentsit has to be downloaded separately (which is no bigguie) and its spread accross multiple files which drags it out when the reality is I just need to set up the PWM registers which shouldnt be hard

Maybe its me but it took considerable effort for me to understand SVM, I honestly believe that I can explain it better than any of the appnotes do without the crap attached its just working out two ratios which give a third one hence the reason I am reluctant to look at these types of things

You have set both OCR1A and OCR1B to 0 which gives you 0% duty cycle, so you won't see anything on the outputs.

Yes and the reason for doing something that stupid is because I was at my desk with a multimeter handy (no scope) and I was writing a duty cycle to then measure the DC voltage on the pin, I never thought of this when I copied and pasted my code straight on

I have managed to scope the output and I am indeed measuring 20.49kHz PWM frequency with the expected duty cycles so it all looks good

Now I need to set up timer 0 and look at firing an interrupt on the TOP count

I think I have the PWM setup now, I have three 20kHz PWM outputs that I can alter the duty cycle of

I have set the duty cycle to 1 i.e the minimum, and I have scoped them

```/*
* Three_Phase_SVM.c
*
* Created: 02/10/2014 09:21:22
*  Author: User
*/

#define F_CPU          8000000UL
#include <avr/io.h>
#include <stdio.h>

/*-----------------------------------------------------Function Prototypes------------------------------------------------------*/
void     Setup_PWM(void);

/*------------------------------------------------------------------------------------------------------------------------------*/

int main(void)
{

Setup_PWM();
OCR1A=1;
OCR1B=1;
OCR0B=1;

while(1)
{

}
}
/*------------------------------------------------------------------------------------------------------------------------------*/
void Setup_PWM()
{

GTCCR  = (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC);  // halt timers
TCCR0A|= (1<<WGM00)|(1<<COM0B1)|(1<<COM0B0); // Phase correct PWM WGMn0 =1, WGMn2 =1, TOP set by OCRnA, Inverted mode COMnB1=1 COMnA1=1
TCCR0B|= (1<<CS00)|(1<<WGM02);               // Prescale 1 CSn0=1
DDRD  |= (1<<PD5);                           // PD5 as output
OCR0A = 200;                                 // Top set by OCRnA, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz

TCCR1A|= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0);// Phase correct PWM WGMn1 =1, WGMn3 =1, TOP set by ICR1, Inverted mode COMnB1=1 COMnA1=1
TCCR1B|= (1<<WGM13)|(1<<CS10);                                      // Prescale 1 CSn0=1
DDRB  |= (1<<PB1)|(1<<PB2);                                         // PB1 and PB2 outputs
TCNT0  = 0;                                                         // Timer 0 count reset
TCNT1  = 0;                                                         // Timer 1 count reset
ICR1   = 200;                                                       // Top set by ICR1, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz
GTCCR  = 0;                                                         // Restart timers
}
```

There is a slight difference in the clock edges, i.e the PWM waveforms don't line up perfectly they are out by around 200ns(ish)

Is there a way to sychronise the two timers so that they are perfectly aligned?

Syncing timers has been discussed before.

I dare say the method is to determine the number of clocks between enabling both timers then preloading one timer with that offset so when you enable thrm they are in sync ( n sync???)

I tried to put an offset in last night, it seemed no matter what I did it just wouldn't work in fact it seemed to shift it 180 degrees out

OC1A output switches about 200ns before OC0A and OC0B, it seems to be about two clocks

I tried setting TCNT0 and TCNT1 to 1, 199..........

No luck but I havent spent very long yet it was 1am and I was up at 6am, crazy-o-clock

Any tips?

Please correct me if my recollection is poor but....

I believe T0 and T2 are both 8-bit timers and are basically the same with the only difference being T2 supports Async input and an extra prescaler tap at /32.

This being the case, I can't see why you can use T0 for 20kHz PWM but not T2.  If not using Async or /32, then both timers should be pretty much identical.

That aside, given you have to spread your 3 phase across 2 timers anyway, T0 would be a better choice as T0 & T1 share a common prescaler.

Resetting this prescaler is how you synchronise the 2 timers btw.

Steve

Steve,

I can't use timer 2 because the TOP value is fixed and its not possible to alter this

PWMfreq=CPU/(N*510)

PWMfreq=8000000/(1*510)

PWMmax = 15.686kHz

So I am using timer 0 and timer 1

Resetting this prescaler is how you synchronise the 2 timers btw

What do you mean?

Like this?

`TCCR1B|= (1<<CS10); `
`TCCR0B|= (1<<CS00)`

But do it last, is that what you mean?

Thanks

Resetting this prescaler is how you synchronise the 2 timers btw

What do you mean?

Open up the data sheet. Press ctrl-F (or whatever your PDF reader uses to start the "Find" function. Type "prescaler  reset". browse through the hits until you get to a section describing the GTCCR register and specifically the PSRSYNC bit.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Isn't T2 mostly the same as T0?  T2 appears to have a "phase correct" mode with OCRA holding the top count, same as T0.

Tom Pappano
Tulsa, Oklahoma

Last Edited: Fri. Oct 3, 2014 - 02:32 PM

Yes, both timer2 and timer0 have the same modes (mode 5 is phase correct with OCRxA as TOP). But there is one other difference that may be critical here: timer0 and timer1 share the same prescaler. This should make it easier to synchronize them.

Regards,
Steve A.

The Board helps those that help themselves.

Open up the data sheet. Press ctrl-F (or whatever your PDF reader uses to start the "Find" function. Type "prescaler  reset". browse through the hits until you get to a section describing the GTCCR register and specifically the PSRSYNC bit.

Thanks for holding my hand to the data!, I have been looking at this tutorial which ties up

https://www.avrfreaks.net/forum/t...

And I have read the data sheet

The prescaler is free running, i.e., operates independently of the Clock Select logic of the Timer/Counter, and it is shared by Timer/Counter1 and Timer/Counter0. Since the prescaler is not affected by the Timer/Counter’s clock select, the state of the prescaler will have implications for situations where a prescaled clock is used. One example of prescaling artifacts occurs when the timer is enabled and clocked by the prescaler (6 > CSn2:0 > 1). The number of system clock

cycles from when the timer is enabled to the first count occurs can be from 1 to N+1 system clock cycles, where N equals the prescaler divisor (8, 64, 256, or 1024). It is possible to use the prescaler reset for synchronizing the Timer/Counter to program execution. However, care must be taken if the other Timer/Counter that shares the same prescaler also uses prescaling. A prescaler reset will affect the prescaler period for all Timer/Counters it is connected to.

• Bit 7 – TSM: Timer/Counter Synchronization Mode

Writing the TSM bit to one activates the Timer/Counter Synchronization mode. In this mode, the value that is written to the PSRASY and PSRSYN C bits is kept, hence keeping the corresponding prescaler reset signals asserted. This ensures that the corresponding Timer/Counters are halted and can be configured to the same value without the risk of one of them advancing during configuration. When the TSM bit is written to zero, the PSRASY and PSRSYNC bits are cleared by hardware, and the Timer/Counters start counting simultaneously.

• Bit 0 – PSRSYNC: Prescaler ResetWhen this bit is one, Timer/Counter1 and Timer/Counter 0 prescaler will be Reset. This bit is normally cleared immediately by hardware, except if the TSM bit is set. Note that Timer/Counter1 and Timer/Counter0 share the same prescaler and a reset of this prescaler will affect both timers

I look at the diagram and I can see both timers are prescaled with their CS bits and how the clock source passes through a 10 bit prescaler, its clear the timers CS bits select which input to use for the timers clock and because my CS bits are 1 then I am using the clock source directly, its an 8MHz clock so for a 50us period I count up 200 ticks and back down so I am not using the clock source prescaler

I think this is the reason that no matter what I do with the tutorial code it doesn't make any difference and I have tried a lot

for example

```/*
* Three_Phase_SVM.c
*
* Created: 02/10/2014 09:21:22
*  Author: User
*/

#define F_CPU          8000000UL
#include <avr/io.h>
#include <stdio.h>

/*-----------------------------------------------------Function Prototypes------------------------------------------------------*/
void     Setup_PWM(void);

/*------------------------------------------------------------------------------------------------------------------------------*/

int main(void)
{

Setup_PWM();
OCR1A=1;
OCR1B=1;
OCR0B=1;

while(1)
{

}
}
/*------------------------------------------------------------------------------------------------------------------------------*/
void Setup_PWM()
{

GTCCR = (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC); // halt all timers

// place all timer setup code here
TCCR0A|= (1<<WGM00)|(1<<COM0B1)|(1<<COM0B0);                          // Phase correct PWM WGMn0 =1, WGMn2 =1, TOP set by OCRnA, Inverted mode COMnB1=1 COMnA1=1
TCCR0B|= (1<<CS00)|(1<<WGM02);                                        // Prescale 1 CSn0=1
DDRD  |= (1<<PD5);                                                    // PD5 as output
OCR0A = 200;                                                          // Top set by OCRnA, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz

TCCR1A|= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0);  // Phase correct PWM WGMn1 =1, WGMn3 =1, TOP set by ICR1, Inverted mode COMnB1=1 COMnA1=1
TCCR1B|= (1<<WGM13)|(1<<CS10);                                        // Prescale 1 CSn0=1
DDRB  |= (1<<PB1)|(1<<PB2);                                           // PB1 and PB2 outputs
ICR1   = 200;
TCNT0  = 0;                                                           // Timer 0 count reset
TCNT1  = 0;                                                           // Timer 1 count reset
// do not do any timer setup before this section

// set all timers to the same value
TCNT0 = 0; // set timer0 to 0
TCNT1H = 0; // set timer1 high byte to 0
TCNT1L = 0; // set timer1 low byte to 0

GTCCR = 0; // release all timers

}```

And I get timer one switching 124ns before timer 0, which is one clock cycle, I have tried a lot of different combos of all kinds and its always out so in the name of adventure I set out trying to fudge the TCNT value, I realised why my late night endeavours last night were in vain because I failed to factor in the direction of the count so I couldn't put timer one a cycle behind because it needs to be set to 1 in the downwards direction

Anyway I have managed to get both in sequence with the below

```/*
* Three_Phase_SVM.c
*
* Created: 02/10/2014 09:21:22
*  Author: User
*/

#define F_CPU          8000000UL
#include <avr/io.h>
#include <stdio.h>

/*-----------------------------------------------------Function Prototypes------------------------------------------------------*/
void     Setup_PWM(void);

/*------------------------------------------------------------------------------------------------------------------------------*/

int main(void)
{

Setup_PWM();
OCR1A=1;
OCR1B=1;
OCR0B=1;

while(1)
{

}
}
/*------------------------------------------------------------------------------------------------------------------------------*/
void Setup_PWM()
{

TCCR0A|= (1<<WGM00)|(1<<COM0B1)|(1<<COM0B0);                          // Phase correct PWM WGMn0 =1, WGMn2 =1, TOP set by OCRnA, Inverted mode COMnB1=1 COMnA1=1
TCCR0B|= (1<<CS00)|(1<<WGM02);                                        // Prescale 1 CSn0=1
DDRD  |= (1<<PD5);                                                    // PD5 as output
OCR0A = 200;                                                          // Top set by OCRnA, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz

TCCR1A|= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0);  // Phase correct PWM WGMn1 =1, WGMn3 =1, TOP set by ICR1, Inverted mode COMnB1=1 COMnA1=1
TCCR1B|= (1<<WGM13)|(1<<CS10);                                        // Prescale 1 CSn0=1
DDRB  |= (1<<PB1)|(1<<PB2);                                           // PB1 and PB2 outputs
ICR1   = 200;
TCNT0  = 0;                                                           // Timer 0 count reset
TCNT1  = 6;                                                           // Timer 1 count reset
// Top set by ICR1, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz
// Restart timers
}

```

Is there a better way to do this, manually measuring the error and fudging doesn't leave me feeling very good

Isn't T2 mostly the same as T0?  T2 appears to have a "phase correct" mode with OCRA holding the top count, same as T0.

Looking at the datasheet(properley!) you are right

Notice in the data sheet for timer 2  phase correct PWM the equation for frequency has a fixed 510 in the place of TOP on the other timers it has a TOP in the equation which indicates its variable, couple that with a tutorial I was following (which I can't find now) that had the mode missing from the table and it looked to me like it wasn't possible to change the TOP value with timer two, it was the first question I had but I don't think I put it very clearly when no one said that I could have a higher frequency than I calculated on timer 2 I moved on to timer 0 and timer 1 and I have learnt a bit

Thanks

Last Edited: Fri. Oct 3, 2014 - 03:32 PM

Yes, both timer2 and timer0 have the same modes (mode 5 is phase correct with OCRxA as TOP). But there is one other difference that may be critical here: timer0 and timer1 share the same prescaler. This should make it easier to synchronize them.

Yes, I had gotten my wires crossed which doesn't matter its actually a good thing, however  I think I am right in that by not using the prescaler block I can't sync them in the normal way but hey... what do I know

Lots of progress for you...

So that rules out timer 2 and I now am left with timer 0 and timer 1, ...

I'm a little confused--what facilities does Timer0 have that Timer2 does not?

Table 15-8. Waveform Generation Mode Bit Description
and

Table 18-8. Waveform Generation Mode Bit Description
appear identical to me.

however  I think I am right in that by not using the prescaler block I can't sync them in the normal way

I don't see why using the /1 vs. /n has any bearing on using GTCCR facilities.

Is there a way to sychronise the two timers so that they are perfectly aligned?

... and doesn't the datasheet discussion of GTCCR address that?  Among other things, TSM..."ne"> • Bit 7 – TSM: Timer/Counter Synchronization Mode" ... "

This ensures that the corresponding Timer/Counters are halted and can be configured to the same value without
the risk of one of them advancing during configuration. When the TSM bit is written to zero, the PSRASY and
PSRSYNC bits are cleared by hardware, and the Timer/Counters start counting simultaneously.
"

Did you follow up and find the very-recent thread where this was discussed?

https://www.avrfreaks.net/forum/c...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

I'm a little confused--what facilities does Timer0 have that Timer2 does not?

Like I said, the equations for PWM frequency in the datasheet differ.  Timer 1 and timer 0 have a variable TOP,  timer 2 has a constant of 510, this coupled with a tutorial I was  following that had a different table it made me think that timer 2 was different which was the first question I had, I can see now they are the same thing

I don't see why using the /1 vs. /n has any bearing on using GTCCR facilities.

Looking at figure 16-2 in the datasheet it looks (to me) like the clocksource doesn't pass through the 10bit prescaler if no prescale is used,  four lines come out, CLK/8 CLK/64, CLK/256 and CLK/1024

If using the clock directly then it looks like it passes straight to the timer counter block bypassing the prescaler block, the PSRSYNC feeds into the prescaler block hence the reason for me thinking /1 /n makes a difference

.. and doesn't the datasheet discussion of GTCCR address that?

Well yes it does seem to indicate that I can synchronise them using this method and it sounds simple

Write one to TSM

Set up timers

When write 0 to TSM they count together

But this

```GTCCR = (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC); // halt all timers

TCCR0A|= (1<<WGM00)|(1<<COM0B1)|(1<<COM0B0);                          // Phase correct PWM WGMn0 =1, WGMn2 =1, TOP set by OCRnA, Inverted mode COMnB1=1 COMnA1=1
TCCR0B|= (1<<CS00)|(1<<WGM02);                                        // Prescale 1 CSn0=1
DDRD  |= (1<<PD5);                                                    // PD5 as output
OCR0A = 200;                                                          // Top set by OCRnA, 8MHz clock, 200 ticks to reach top, 200 ticks to reach bottom 400 ticks of 8MHz clock = 20kHz

TCCR1A|= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0);  // Phase correct PWM WGMn1 =1, WGMn3 =1, TOP set by ICR1, Inverted mode COMnB1=1 COMnA1=1
TCCR1B|= (1<<WGM13)|(1<<CS10);                                        // Prescale 1 CSn0=1
DDRB  |= (1<<PB1)|(1<<PB2);                                           // PB1 and PB2 outputs
ICR1   = 200;

TCNT0  = 0;                                                           // Timer 0 count reset
TCNT1  = 0;                                                           // Timer 1 count reset
GTCCR m= 0; // release all timers```

Does nothing to help me

Is there any advice you can give me on why the above doesnt work no matter what I do? I am clearly doing something wrong as its always a clock cycle out

Edit

Or am I doing something wrong?, figure 16-2 looks like PSRSYNC can never help me because I am using system clock directly, I have bypassed the prescaler block

Last Edited: Sat. Oct 4, 2014 - 01:59 PM

Like I said, the equations for PWM frequency in the datasheet differ.

I see the equation, and you seem very fixed on that apparent typo.  Didja look at the text immediately above the equation, which has the same wording for both timers?  Or the identical charts?  One equation trumps one paragraph plus one chart.

PSRSYNC feeds into the prescaler block hence the reason for me thinking /1 /n makes a difference

As the timer is stopped, AND the prescaler held in reset,  what difference could it make whether it uses that block or not?  Did you try it?  Does it work differently than the datasheet?

the above doesnt work no matter what I do?

What "doesn't work"?  What did you expect to happen?  What >>does<< happen?  I thought you said the timers >>did<< start together?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

From some quick testing it appears that the PSRSYNC has effect (also with no prescaler) but it is also clear that it doesn't  work as expected for this case (as OP has stated several times "doesn't work" as in timer 0 output is late by one cycle).

/Lars

From some quick testing it appears that the PSRSYNC has effect (also with no prescaler) but it is also clear that it doesn't  work as expected for this case (as OP has stated several times "doesn't work" as in timer 0 output is late by one cycle).

/Lars

Interesting.  Must be because it "doesn't go though the prescaler block".

I thought joey posted a cycle-correct Timer0/Timer1 example in the link I posted.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

This may be a dumb question, but why would the PWM pulses applied to the three phases need to be aligned with each other?  Assuming a motor power factor less than one, each driver is looking into the inductance of the motor windings which should be integrating those pulses.  Does the pwm frequency applied to each phase even need to be the same as long as the duty cycles are still modulated to produce the desired voltages?

Tom Pappano
Tulsa, Oklahoma

I see the equation, and you seem very fixed on that apparent typo

Lee what are you talking about fixed?, I am explaining why I had the train of thought I did, I wanted 20kHz frequency so I was looking at the equations as a first stop. I have already stated that I know the error of my ways but to be honest you don't seem to read what I type.

what difference could it make whether it uses that block or not?  Did you try it?  Does it work differently than the datasheet?

You tell me what difference it makes, if any, in none crpytic terms, it would be really appreciated. I have already stated its a clock different so I don't need to go back to the datasheet on this occasion, the clocks arent synced with the code that I tried and posted and explained my problem

What "doesn't work"?  What did you expect to happen?  What >>does<< happen?  I thought you said the timers >>did<< start together?

And then go on to say

Interesting.  Must be because it "doesn't go though the prescaler block".

Which seems like you are being purposely obtuse, its not really interesting is it Lee its obvious to you and your not assuming anything to use the term must be

I thought...........

Did you think or do you really know?, come on Lee don't hold back make it easy for me

Looking at joeys method

It ends up in assembler because the cpu executes the instructions one at a time theres going to be a difference which he offsets with assembly

Thats me goosed so unless I am missing something my code that offsets the time counts by 6 to get synced clocks will have to do

This may be a dumb question, but why would the PWM pulses applied to the three phases need to be aligned with each other?  Assuming a motor power factor less than one, each driver is looking into the inductance of the motor windings which should be integrating those pulses.  Does the pwm frequency applied to each phase even need to be the same as long as the duty cycles are still modulated to produce the desired voltages?

With a tiny shift of 125ns the real world effects will be none existant and you are right in that even with different PWM frequencies as long as the duty cycles vary sinusoidal then it will work the placement of the pulse has no effect on the fundamental output magnitude but it has dramatic effect on the harmonic content of the output voltage from a converter (these are voltage source inverters) it has been shown that by having a power converters acive pulses centred then this decreases current ripple and gives the best harmonic performance

PWM for power converters is a very good book on this complicated subject, if you can get access to section 4.5 it explains with a 50% duty cycle the difference in ripple frequency is double and as harmonic losses in the load are proportional to the RMS ripple current these losses can differ by a factor of 4. Its true a motor will filter harmonics currents but the harmonics are still present in the output voltage and the harmonic performance is very different indeed which is important from an EMC point of view

Sorry if I am boring you by now but you asked for it!, with lined up waveforms then its possible to limit switching to only one power device at a time

Look here at the SVM hexagon, notice the six states of an inverter, state 100 indicates only phase A high side device is active the lower devices are complimentary

Look at the hexagon, for a full 60degres of a cycle one device is clamped and the other two are modulated according to

The modulation indices are calculated from the pulse widths Ta and Tb, in SVM you have freedom over the placement of the zero vector (the point when no voltage is applied to the motor) which gives further control over the spectrum of the outputs which is the only difference between third harmonic injection PWM and SVM it is a big difference

Look how they need to line up to calculate the duty cycles, if they didnt line up then I wouldn't know how to do it!

Last Edited: Sat. Oct 4, 2014 - 07:32 PM

Interesting, but the vectors aren't updated every pwm cycle but after a group of pwm cycles.  My little contraption runs a carrier freq of 15.6 khz and has a sampling rate of about 1400 hz yielding  about 11 pwm pulses for each step.  With SVM aren't you pretty much doing the same type of thing?  I'm still not sure that alignment or misalignment of the pulses should matter that much, but I should try forcing it and see what it looks like on the scope. Now as far as EMC goes, my various products have to be in close quarters with commercial motor drives anywhere from 5 to 125 HP, and from my testing it became clear that if a VFD is not producing absolutely horrible levels of EMI it either is not running or it is broken 8)

Tom Pappano
Tulsa, Oklahoma

the vectors aren't updated every pwm cycle but after a group of pwm cycles

Now I don't pretend to be an expert in these matters at the end of the day I am just a student in this subject but I have never seen a power converter modulation strategy where the modulation indices aren't updated every switching cycle and it is an interesting train of thought for me as its not something I have ever considered and no literature I ever seen covers it, double update modulation is quite common where the duty cycles are updated on both the peak and the minimum of the carrier

When I think about it then I think that your method with 1400 Hz update is closer to square wave mode, if you are familiar with it?, no PWM occurs and the converter clamps the output to the relevant state for 1/6 of a cycle ie it will go

100-110-010-011-001-101-100................

It you had twelve states then you will have 30 degrees between updates (for 50Hz) so I think (but I am not certain) you would have decreased harmonic performance to updating the indices every switching interval, if you were doing vector control then the 1400Hz sampling seriously messes up the torque response, I just simulated it I kept the switching frequency constant but by only updating the control loop at 1.4kHz the torque response is really bad however from the quick sims I did with open loop V/Hz I was struggling to see any drawbacks and it is very interesting to me to do what you have done, if I get time I might simulate it further as I didn't go far, no real motor just a coil and no harmonic measurements etc

With SVM aren't you pretty much doing the same type of thing

SVM is related to sine reference PWM but its quite different at the same time, the reference vector rotates  and we sample it, the six switching states of an inverter map out a hexagon and angle of the reference determines which sector we are in, we use two adjacent vectors to the reference to make up the reference

So we have an inverter that only has six output states and we want to make up our reference that lies between two of the states so what we do is decide what proportion of one inverter state plus a proportion of the other makes up the reference i.e use two vectors with 60 degrees apart and vary their magnitude so that they add together to our reference, if we apply an inverter state for half the time its as if we only switched it on half way! the time not needed is allocate to the zero vector and this is how we can vary not only the frequency of an output voltage but also its magnitude, an electronic transformer if you like

I'm still not sure that alignment or misalignment of the pulses should matter that much

You should check out PWM for Power Converters by Lipo and Holmes, its got chapters devoted to this subject and there is frequency spectrum plots THD calcs comparisons and lots and lots of things that I don't understand its a very complicated subject, one thing for sure that book spells out is that the pulse placement does make a difference and it actually distiguishes modulation strategies from each other

Can I ask is it standard sine reference modulation you use or do you add a third harmonic for another 15% output?

In my case a 125 ns shift will not matter a dot, I can offset the clocks anyway and get them synced perfectly so why not, my curiosity has cost me loads of time here and I think looking at Joey's post that adding an offset and measured to confirm is the best way for me as I am unable to do the assembly stuff

(I just re-read the thread to see if its just me being thick)

I thought joey posted a cycle-correct Timer0/Timer1 example in the link I posted

And he expects me of all people to be just at home with stuff like

```__asm__ __volatile__ (
"in   __tmp_reg__, __SREG__    \n\t"
"cli                           \n\t"
"out  %[gtccr],    %[psr10]    \n\t"
"out  %[tccr1b],   %[cs12]     \n\t"
"out  %[tccr0b],   %[cs00]     \n\t"
"out  __SREG__,    __tmp_reg__ \n\t"
:
:
[psr10]   "r" ((uint8_t)(1<<PSR10)),
[cs12]    "r" ((uint8_t)(1<<CS12)),
[cs00]    "r" ((uint8_t)(1<<CS00))
:
"r0"
);```

And expect that to be the end of it for me, I mean, HELLO, Lee, have you seen my other threads?, Sorry but thats not the end of it for me and it feels like your trying to put me off programming or something, pull the other one dude!

Last Edited: Sun. Oct 5, 2014 - 04:09 AM