|
|
View previous topic :: View next topic |
Author |
Message |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
Motor PWM to Regular PWM |
Posted: Tue Oct 28, 2014 5:48 pm |
|
|
Hi,
I'm trying to use a dsPIC30F6015 in a pwm test.
It's specified in the datasheet that I have 4 channels PWM.
I'm not driving a motor just 4 led for testing purpose.
I have zero experience with the motor pwm function.
I've read in the datasheet that's possible to control the 4 pwm generator separately.
I would like to set pwm duty channel 1 to 4.
So far no success in my test.
Code: |
setup_motor_pwm(1,MPWM_FREE_RUN,1,1,1200); //free rune = always running pwm
setup_motor_pwm(2,MPWM_FREE_RUN,1,1,1200);
setup_motor_pwm(3,MPWM_FREE_RUN,1,1,1200);
setup_motor_pwm(3,MPWM_FREE_RUN,1,1,1200);
set_motor_unit(1,1,MPWM_ENABLE_H ,10,10); //enable H = enable H pin pwm
set_motor_unit(1,2,MPWM_ENABLE_H ,10,10);
set_motor_unit(1,3,MPWM_ENABLE_H,10,10);
set_motor_unit(1,4,MPWM_ENABLE_H,10,10);
set_motor_pwm_duty(1,1,60000); //set pwm 1 close to 100% (16bit value)
set_motor_pwm_duty(1,2,60000);
set_motor_pwm_duty(1,3,60000);
set_motor_pwm_duty(1,4,60000);
|
any example code to help me understand using motor pwm as regular pwm module?
I would like to know how to control these 4 generator and get their outputs on either H or L pins.
A big thank you for your help! _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Wed Oct 29, 2014 3:18 am |
|
|
Start by pulling down DS70046E.pdf from Microchip.
The data sheet for the whole of this family, is split into parts. Annoyingly Microchip are remarkable 'good' at hiding bits of this. So they tell you to refer to DS70046, but a search on their site 'for' this doesn't find it....
If you go through the 'family reference manual' page though, it then points you to the pdf, and it is (of course) the extra 'e' that hides it.
Then pull the ccs power_pwm example.
You need to use all four timing generators, but are only using one in several of the settings. Then you have your 'period' setting at 1200, which implies a maximum duty count of 2400, but then try to put a count as if the period was at the maximum (0x7FFF). You need to use all four output pairs, and enable just one side of each. You should set the dead times to zero in this mode, or use independant mode to ensure the dead time generators are disabled, and ensure the fault override is disabled (it may default to off, but 'better to be safe').
There are then several things then designed to confuse.
In the 'setup_motor_pwm' function, the 'prescale' counts 1,2,3 etc.., but the postscale counts from '0'. So for a 1:1 postscale, you have to put zero in this column. Urgh....
On the current compilers for this chip, the set_motor_pwm_duty function for channel 2, writes to the wrong register. The register is 0x1D8, and the device editor and register list show this, but if you compile the line, it writes to 0x5D8 instead...
So something like (no guarantees, haven't got that chip to test...):
Code: |
setup_motor_pwm(1,MPWM_FREE_RUN,1,0,1200); //free rune = always running pwm
setup_motor_pwm(2,MPWM_FREE_RUN,1,0,1200);
setup_motor_pwm(3,MPWM_FREE_RUN,1,0,1200);
setup_motor_pwm(4,MPWM_FREE_RUN,1,0,1200); //setup four PWM generators
set_motor_unit(1,1,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0); //enable H = enable H pin pwm
set_motor_unit(2,2,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0);
set_motor_unit(3,3,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0);
set_motor_unit(4,4,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0); //Now set each output pair to use different generator
set_motor_pwm_duty(1,1,2300); //set pwm 1 close to 100% (16bit value) - 2*the period = max
set_motor_pwm_duty(2,2,1150); //set PWM 2 to half this
//For some reason the compiler has this address wrong on this chip
PDC2=1150; //correct this.....
set_motor_pwm_duty(3,3,575); //set PWM 3 to 1/4
set_motor_pwm_duty(4,4,288); //Route each to the corresponding output
|
|
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Oct 29, 2014 3:53 am |
|
|
Ttelmah wrote: |
On the current compilers for this chip, the set_motor_pwm_duty function for channel 2, writes to the wrong register. The register is 0x1D8, and the device editor and register list show this, but if you compile the line, it writes to 0x5D8 instead...
] |
Wow thanks Ttelmah for the very precise answer!
I just woke up and need to leave but i've tried quickly the example you posted.
I see 2 issues that I need to investigate further tonight with the scope.
When you talk about wrong register, is there anyway to override this?
Also this particular line:
Code: | PDC2=1150; //correct this..... |
I've looked inside device H file to see if there was a setting named PDC2 otherwise I get a variable undefined when compiling.
For now I only get 2 separate PWM output the two remaining pwm lines are unpowered even at maximum PWM duty.
I'll check tonight with the scope but with the LED test I get nothing.
Thanks again for all the explanations!
_________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Wed Oct 29, 2014 4:26 am |
|
|
Apologies.
You need this line:
#word PDC2=getenv("sfr:PDC2")
Which then allows you to write directly to the PDC2 register and correct the missing entry.
I have pointed this out to CCS. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Oct 29, 2014 3:03 pm |
|
|
Ttelmah wrote: | Apologies.
You need this line:
#word PDC2=getenv("sfr:PDC2")
Which then allows you to write directly to the PDC2 register and correct the missing entry.
I have pointed this out to CCS. |
My test code:
Code: |
#include <30f6015.h>
#FUSES HS2_PLL16,NOWDT,NOPUT,NOMCLR
#use delay(clock=96000000)// freq = HS2_PLL16 = (12mhz crystal /2) * 16
#word PDC2=getenv("sfr:PDC2") //Register workaround from Ttelmah
void main(void)
{
setup_motor_pwm(1,MPWM_FREE_RUN,1,0,1200); //free rune = always running pwm
setup_motor_pwm(2,MPWM_FREE_RUN,1,0,1200);
setup_motor_pwm(3,MPWM_FREE_RUN,1,0,1200);
setup_motor_pwm(4,MPWM_FREE_RUN,1,0,1200); //setup four PWM generators
set_motor_unit(1,1,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0); //enable H = enable H pin pwm
set_motor_unit(2,2,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0);
set_motor_unit(3,3,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0);
set_motor_unit(4,4,MPWM_INDEPENDENT | MPWM_ENABLE_H | MPWM_FAULT_NO_CHANGE,0,0); //Now set each output pair to use different generator
set_motor_pwm_duty(1,1,2400); //set pwm 1 close to 100% (16bit value) - 2*the period = max
set_motor_pwm_duty(2,2,2400); //set PWM 2 to half this
PDC2=1150;
set_motor_pwm_duty(3,3,2400); //set PWM 3 to 1/4
set_motor_pwm_duty(4,4,2400); //Route each to the corresponding output
while (1){
//nothing for now
}
}
|
With this register fix now, I get PWM 1H and 3H only (before the fix it was 1H & 2H)
Scope output:
Yellow = PWM 3
Blue = PWM 1
Now for PWM 2 and 4:
Absolutely nothing!
If you need more information regarding the output, please ask!
Any clue? _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Oct 29, 2014 7:19 pm |
|
|
I've tried Software PWM, the one from PCM Programmer...
It work well but I'd like to use Hardware PWM since I've already have 4 channels which could free up the cycle usage dedicated to timer routine to generate pwm. _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|