This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Toggling the PWM outputs.



Hi all,

I would like to toggle my PWM outputs on and off, but one should be on when the other is off. For example, I have four PWM signals: PWM1, PWM2, PWM3 and PWM4. PWM1 and PWM3 are a pair, so is PWM2 and PWM4.

When PWM1 and PWM3 are on, PWM2 and PWM4 should be off. I wrote a little bit of code which toggles these outputs, but so far it either toggles them all off or all on. This is the gist of my code.

int i = 0;
bool bArrayTrueFalse = {true, false};
bool bArrayFalseTrue = {false, true};

if(1 second has passed)
{
	
	i++;
	if(i==2)
	{
		i=0;
	}

	PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, bArrayTrueFalse[i]);
	PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, bArrayFalseTrue[i]);
	PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, bArrayTrueFalse[i]);
	PWMOutputState(PWM0_BASE, PWM_OUT_3_BIT, bArrayFalseTrue[i]);

}


Is this even possible? If so, anybody have any suggestions?

  • Hello James,

    A piece of information missing is the configuration of the PWM Generator. What you have done is correct but without knowing the actual configuration of PWM0 and PWM1 it would be difficult to know what is being configured for generation. A full dump of PWM address space may prove useful.

    The PWM Channels 0 and 1 can use a single Generator and Comparator. By using the PWM0GENA and PWM0GENB registers to toggle on CompA in opposite directions, the same effect may be obtained. The register bits ACTCMPAD and ACTCMPAU may be set to 0x2 and 0x3 for one PWM output and 0x3 and 0x2 for the other one allowing for opposite polarity

    Also since you have not mentioned the end application it may be important to note that some applications like Motor Control may require a deadband in between the transitions. You may want to check that as well.

    Regards
    Amit
  • Hi Amit,

    Cheers for the reply. I was quite sure this code should work, as I did a quick check with it by sending the values of the arrays over the UART and it was indeed toggling the correct outputs, maybe it is because I've configured it wrong in my PWM adress space.

    Here is the code dump of the PWM.

    void
    InitPWM(void)
    {
    
    /*	Enable PWM clock.*/
    	PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_8);
    
    /*	Configure the GPIO pins.*/
    	GPIOPinConfigure(GPIO_PF0_M0PWM0);
    	GPIOPinConfigure(GPIO_PF1_M0PWM1);
    	GPIOPinConfigure(GPIO_PF2_M0PWM2);
    	GPIOPinConfigure(GPIO_PF3_M0PWM3);
    
    /*	Configure the GPIO pins as PWM pins.*/
    	GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    
    /*	Calculate period and duty cycle. One period is 41.667 us.*/
    	ui32PWMClockFreq = (ui32SysClkFreq / 8); //(120000000 / 8 = 15000000
    	ui32PWMLoad = ((ui32PWMClockFreq / PWM_FREQUENCY) -1); //15000000 / 24000 = 625
    	//ui32PWMDutyCycle = ui32PWMLoad;
    
    /*	Configure the PWMs to count-down, and sync with each other.*/
    	PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);// | PWM_GEN_MODE_GEN_SYNC_GLOBAL | PWM_GEN_MODE_DB_SYNC_GLOBAL);
    	PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);// | PWM_GEN_MODE_GEN_SYNC_GLOBAL | PWM_GEN_MODE_DB_SYNC_GLOBAL);
    
    /*	Set the periods.*/
    	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ui32PWMLoad);
    	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, ui32PWMLoad);
    
    /*	Set the duty-cycle.*/
    	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, ui32PWMLoad*0.1);
    	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, ui32PWMLoad*0.1);
    
    /*	Enable the dead-time.*/
    	//PWMDeadBandEnable(PWM0_BASE, PWM_GEN_0, deadTime, deadTime); //15 pulses is roughly 1 us (2.4% of total period).
    	//PWMDeadBandEnable(PWM0_BASE, PWM_GEN_1, deadTime, deadTime);
    
    /*	Enable all of the PWM signal outputs.*/
    	PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);//PF0 - PWM
    	PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false);//PF1 - \PWM
    	PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true);//PF2 - PWM
    	PWMOutputState(PWM0_BASE, PWM_OUT_3_BIT, false);//PF3 - \PWM
    
    /*	Enable the sync.*/
    	PWMSyncTimeBase(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT);
    	PWMSyncUpdate(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT);
    
    /*	Enable the PWM gens.*/
    	PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    	PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    
    }

    The end application is to drive a motor for a very short time by rapidly toggling the direction, this essentially causes the motor to "stall" because it can never build up any speed before the direction is changed. I want to do this to take a look at the amount of current the motor is drawing and if I can implement some safety feature to not draw a certain amount of current.

    I appreciate the help!

  • James Kent69 said:
    drive a motor for a very short time by rapidly toggling the direction, this essentially causes the motor to "stall

    While far from vendor Amit's skill/status may I offer past findings which may prove of value?     (I've (some) BLDC Control/Design background)

    Minus the "dead band" insertion - which Amit indeed noted - your method is very likely to cause dreaded, "Shoot-Through" - never pleasant for your Power FET stage.   Now we note that you have provided such, "dead-band" yet may I make 3 additions:

    a) do not "test/verify" this w/the actual motor attached!     Or with a non, current-limited power supply - said current limited to far less than the FETs current rating.

    b) in place of the motor employ simpler (and far lesser) resistive power loads.    These may be more easily monitored - to insure that your "dead-band" truly is working to your (hoped) specification.

     and (el grande follows)

    c) may I note that - even with the motor "not" at speed - such "instant motor reversal" may damage the permanent magnets w/in the motor.   (even your "dead-band" cannot save you here [it's too short!])    Classically a BLDC motor is speed governed - so that a reversal may not occur - when the motor is beyond a limited (safe) speed.     Knowing little (i.e. nothing) of your motor - I pass this on in the attempt to reduce any future "agony."     You "may" be ok - but a check w/motor vendor often proves wise/worthwhile...

    Our small tech firm follows more "conventional" methods to "stall" a motor.    ("locked rotor" being one)     Increasing the load supplied by a Dyno - to beyond the motor's nameplate rating - is another.    Both such methods (may) better approximate "real world" motor operating conditions - thus warrant your consideration...

  • Hello James,

    Thanks for the application info. I believe the following code would show what is required for correcting the configuration (I believe you would soon see the requirements)

    D:\ti\TivaWare_C_Series-2.1.0.12573\examples\peripherals\pwm\dead_band.c

    And of course cb1's valuable inputs into motor control from experience forms a valuable input.

    Regards
    Amit
  • Given the description it sounds like the poster is using an h bridge on a pm DC motor rather than an ac motor like a bldc.

    I have done such in the past and when ccontrol around zero is needed I've used a scheme where at 50% PWM the bridge was balanced. Ie the PWM would drive the high side of one half h and the low side of the other half h, the ccomplementry PWM woul drive the other pair.

    It doesn't require 4 pwms to do that, only one. Two if you include the complement.

    You are right that you have worry about shoot tthrough on each half h and the power ccircuitry should always be tested at lower powers. Running the motor in this ccondition is not a problem though, it takes many cycles to build up current in the rotor, the single cycle alternation will produce a small current draw at zero speed but unless the frequency of the PWM or the motor inductance is low then that will not be an issue. You mUST have ccurrent limits to deal with accel and decel tHough.

    A bbigger danger is that once you drive the motor slower than it is rotating you will get a current bACK to the supply. If you are not using a battery or a supply that can sink current then the voltage will rise until something fails. This will happen quickly, especially if the motor load has a large momentum.

    I will reemphasise my agreement with cb1 on testing. Have a plan for Verifying you power waveforms a lower powers an reverifying at higher powers.

    Robert

    A side note. Reversing the motor has been the conventional way of braking electric forklifts.
  • Let the record show that - once again - inadequate poster guidance has caused Amit, you & I to (blank) into the wind - till a better (i.e. some) description of the motor in question arrives.

    May I ask if "reversing" - while it has been the conventional means - continues today as best/brightest, means of braking?    Seems extremely "harsh" - not only upon the electronics - but upon the entire power-train assembly.      I can see its (likely) utility for "quickness" - but that's achieved at substantial, "wear/tear" cost - is it not?
     
    So much "new/improved" has arrived w/in power field - one wonders if alternate braking schemes (less harsh) have dawned...

  • cb1- said:
    .

    May I ask if "reversing" - while it has been the conventional means - continues today as best/brightest, means of braking?    Seems extremely "harsh" - not only upon the electronics - but upon the entire power-train assembly.      I can see its (likely) utility for "quickness" - but that's achieved at substantial, "wear/tear" cost - is it not?

    So much "new/improved" has arrived w/in power field - one wonders if alternate braking schemes (less harsh) have dawned...

    It's a lot less harsh than it sounds.  Because o  ftheway i is wired you end up with the motor effectively regenerating into itself and a braking diode. It's all under current control so it is quite smooth.  If you get the control wrong though you can get very high torques.

    The scheme is used only on series wound motors. The newest designs from the largest manufacturers have switched to either shunt wound or ac induction and use regenerative braking for most of the braking cycle.

    It does appear that there's still a lot of series wound vehicles out there though.

    Robert

    My edit winow keeps dropping to less than a single character in width. Thus the abbreviated posts

  • I think that's as good as the post is going to get from this platform. Hopefully it's readable with the last edit

    Robert
  • Side note hearsay. Apparently in some places the drivers use the brake rather than reversing. This leads to an increased mmaintenance cost since the brakes need regular servicing under that use.

    Robert
  • Robert Adsett72 said:
    My edit winow keeps dropping to less than a single character in width.

    Not to worry - I'm told (inside info) there's a "booster pack" for that!     No need for search/spec - as it will (almost) plug-in - you're home-free!     Or (maybe) not...

  • @cb1- I'm aware of the problems this can cause, that is the next part of the tests. I've got a few power resistors lying around which I was going to test this on first, wouldn't want to fry my motor! Someone also mentioned what from motor I was using, and it is indeed a DC motor attached to a h-bridge.

    The way the h-bridge is set up, is that I require at least two of the four FETs to be driven open to provide power to the motor in one direction, therefore I need four to toggle directions.

    @Amit, thanks for your reply. I actually used that example as a starting point for my deadband when I was taking a look at how the deadband was inserted into the complimentary PWM signal. I'll have to do some more tests then, as I'm still curious to why all the signals are being toggled, and not the pairs of signals.

    @Robert, cheers for pitching in with regards to the power going back to the power supply, I hadn't thought of that, so I will have to keep that in mind when I'm doing my high power tests!

    I've gotten some good answers here guys, this should keep me busy for an afternoon to see if I can get it all to work, and if it doesn't, I'm sure you'll here from me again!
  • May I suggest, "Slow, logged, & steady" progress toward your goal (i.e. KISS) rather than one "giant gulp?"

    We've done some treadmill designs - where the spinning flywheel can really "goose" the motor's bus voltage - unless we take quick (and proper) action. In that specific case we impose a high power resistor - which pulls the bus down to a safe level - and then automatically releases. Should you "go this route" beware - even though large & well rated - that resistor gets extremely hot - and requires some time to, "cool to the touch." (as some unfortunates here have (bit painfully) discovered)
  • @cb1-, ofcourse, everything will be done in baby steps. I'm working with some rather large loads so I wouldn't want to find out I've done something wrong when I start on the more dangerous end of the spectrum!
  • While you state, "of course" few here know your background and capability - far better that we urge caution & systematic methods.
     
    May I suggest that you keep detailed notes - usually you'll generate substantial design/development and then test data.    I'd seriously date code and secure such - so often we (really) need those (past) findings to solve newly arrived (or discovered) issues.

    As always - the missile (may) fly when the specs, test results & related paperwork (exceeds) the height of the missile!     There's a lesson there...