CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

DSPIC33 PWM Setup
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

DSPIC33 PWM Setup
PostPosted: Thu May 04, 2017 11:27 am     Reply with quote

I have a 33EP512MC806. Want to use PWM1. Need to be able to change duty. Works great with P18F4525, but now everything is completely different. Documentation is clear as mud and cannot find example for PIC33 device.

Do I use "#use pwm(...) ?
Is there a pin assignment I need to make?
HELP!!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu May 04, 2017 11:48 am     Reply with quote

The examples are your friend. First look at ex_pwm.c.
This shows the setting up of a standard PWM, and includes 16bit versions. (using the 'compare' function).
There is also ex_pwm_pcd.c that shows this "on it's own".
This doesn't actually use the separate PWM hardware.

Then there is the high speed PWM. This is another ability on some chips (yours included). ex_hspwm.c.

The hspwm, is more complex, but more powerful (larger divisors, and faster maximum speeds, multiple complementary pins etc.). It's more like the power pwm on the PIC18's.

Examples have also been posted here on using both of these.
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Thu May 04, 2017 12:53 pm     Reply with quote

Thank you for the reply, Ttelmah. The examples do not seem to be useful. Here is the setup I derived from ex_hspwm.c. It does not work. I have no idea how to fix this.

Code:

void setup_pwm1() {
   setup_adc_ports(sAN0|sAN1);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   
   setup_hspwm_unit(1, HSPWM_ENABLE | HSPWM_REDUNDANT | HSPWM_TIME_BASE_FROM_PHASE_REGS | HSPWM_FAULT_MODE_DISABLED);                                       
   setup_hspwm(HSPWM_ENABLED | HSPWM_CLOCK_DIV_BY_2, 0xFFFF);                           
   set_hspwm_phase(1, 800);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu May 04, 2017 1:22 pm     Reply with quote

If you don't need the extra features of the HSPWM, then it is pointless using it. Less work to just use the output_compare function.

You are not setting a duty.

It is set to drive both PWM1H, and PWM1L.
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Thu May 04, 2017 1:41 pm     Reply with quote

I hate to have to do it this way, but it seems my only option. :(

Code:

#INT_TIMER1                               // Service Timer 1
void isr_timer1() {
   static int8 Count = 0;
   if (Count == 0) output_low(DSPEN);
   if (Count == gPwmDuty) output_high(DSPEN);
   Count++;
}
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Thu May 04, 2017 1:43 pm     Reply with quote

Ttelmah wrote:
If you don't need the extra features of the HSPWM, then it is pointless using it. Less work to just use the output_compare function.

You are not setting a duty.

It is set to drive both PWM1H, and PWM1L.


The other examples do not even compile. Can you give a setup for DSPIC33 PWM or find problem with my setup?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu May 04, 2017 2:09 pm     Reply with quote

What pin do you actually want to use?.
What frequency do you want?.
What is your clock?.
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Thu May 04, 2017 2:25 pm     Reply with quote

I am using the PWM1 pin as output.
Frequency approx 200 Hz.
#use DELAY(clock=80M, crystal=16M)
Must be able to vary duty from 0% to 100%
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri May 05, 2017 2:07 am     Reply with quote

There is _not_ a 'PWM1' pin on your chip...
There is a PWM1L, and a PWM1H. Which one do you want to use?.....

Assuming PWM1L, just setting up a standard PWM:

Code:

#include <33EP512MC806.h>
#device ICSP=1
#use delay(clock=80000000,crystal=16000000)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOJTAG                   //JTAG disabled

//Map the first output compare peripheral to the required pin
#PIN_SELECT OC1=PIN_E0

void main()
{
   //First a basic PWM on PIN_E0
   //To give 200Hz, need to divide by 200000. Maximum divisor is for a single
   //timer is 65536, so use /8 prescaler (Fp = Fosc/2), and 25000 counts
   setup_timer2(TMR_INTERNAL | TMR_DIV_BY_8, 0x61A7);
 
   setup_compare(1, COMPARE_PWM_EDGE | COMPARE_TIMER2);  //setup the compare peripheral
   
   set_pwm_duty(1,12500); //setup for 50:50 output to start

   while(TRUE)
   {
      //User Code
   }
}


There are 16 output compare peripherals available, that can be mapped to any RP pin. Much the simpler peripheral to use.

Alternatively to use the HS PWM peripheral:
Code:

void main()

   setup_hspwm(HSPWM_ENABLED | HSPWM_CLOCK_DIV_BY_16, 0x61A7);  //HSPWM enabled, PWM Clock = Fosc/16 (not Fp)       
   
   setup_hspwm_unit(1, HSPWM_ENABLE_L | HSPWM_REDUNDANT | HSPWM_TIME_BASE_FROM_PHASE_REGS |
                       HSPWM_FAULT_MODE_DISABLED, 0, 0);    //Frequency set with phase register no dead times
                       //low output enabled, redundant mode
                                                                                         
   set_hspwm_phase(1, 0x61A7); //ensure phase register is loaded
   
   set_hspwm_duty(1, 12500); //and setup a 50:50 duty

   while(TRUE)
   {
      //User Code
   }
}


I hope this is right, but haven't got one of those chips to test.

As I've already said multiple times it is only worth using the HS PWM, if you want it's extra abilities. Programmable dead times, complementary outputs, faults control etc..

It's a pig to get working right, with every chip I've met having differences in the setups that actually work. The standard setup is much easier.
The DSPIC's, don't have a normal 'PWM' as such, they have the output compare function, that can be programmed to give a PWM, and is normally available on many of the pins.
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Fri May 05, 2017 11:00 am     Reply with quote

Thanks for the help Ttelmah. I have it working, sort of...

Setting up as you have I cannot get the full range of duty cycle. It appears that the second parameter of setup_timer2 has no effect. No matter the number it is like 0xFFFF.

I am using this which gives an output of 610 Hz which will work.

Code:

   setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1);
   setup_compare(1, COMPARE_PWM_EDGE | COMPARE_TIMER2); 
   set_pwm_duty(1, 32000); 


I did not know of #PIN_SELECT OC1=PIN_E0 because I was looking for PWM not OC1.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri May 05, 2017 11:16 am     Reply with quote

Try with

setup_timer_2(TMR_INTERNAL | TMR_DIV_BY_1, xxxx);

Note the extra underbar.
It should be the same, but worth trying with the alternative syntax.

It should work. If it doesn't, report it to CCS. It works with all the older chips I've tried, and suggests there is a fault in the support for this chip (it is very new...).
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Fri May 05, 2017 12:35 pm     Reply with quote

setup_timer_2 does not exist in PCWHD.

Maybe it is a compiler bug. I tried to find the actual registers this is supposed to set, but could not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri May 05, 2017 1:29 pm     Reply with quote

It's the PR2 register.
So something like:
Code:

   #word PR2=getenv("SFR:PR2")

   PR2 = 24999;


If that doesn't work, then it may be a database error for the actual period register.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri May 05, 2017 2:10 pm     Reply with quote

What compiler version are you on?.

I've just checked with 5.070, and 5.071, and the setup function is correctly loading the PR2 register, and the register is in the correct location.
Code:

//symbolic
....................    setup_timer2(TMR_INTERNAL | TMR_DIV_BY_8, 0x61A7);
00258:  CLR     T2CON
0025A:  MOV     #61A7,W4
0025C:  MOV     W4,PR2
0025E:  MOV     #8010,W4
00260:  MOV     W4,T2CON

//Numeric
....................    setup_timer2(TMR_INTERNAL | TMR_DIV_BY_8, 0x61A7);
00258:  CLR     110
0025A:  MOV     #61A7,W4
0025C:  MOV     W4,10C
0025E:  MOV     #8010,W4
00260:  MOV     W4,110
Ranfo



Joined: 08 Sep 2008
Posts: 38

View user's profile Send private message

PostPosted: Fri May 05, 2017 2:48 pm     Reply with quote

I am using PCWHD 5.071
Have tried a couple more things, but am moving on.

Using
Code:

#word SFR_PR1 = 0x0102
#word SFR_PR2 = 0x010C

Then
Code:

setup_timer1(TMR_INTERNAL|TMR_DIV_BY_64);     
SFR_PR1 = 0x8000;

I can change the timer1 interrupt frequency.
But this is not doing the same for timer2.
At least as seen in the PWM output.
Code:

setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1);
SFR_PR2 = 0x8000; // Same as 0xFFFF
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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