View previous topic :: View next topic |
Author |
Message |
evan
Joined: 02 Apr 2012 Posts: 22
|
PWM with PIC24FJ128GA310 |
Posted: Mon Jun 04, 2018 11:08 am |
|
|
Hi all,
I am stuck trying to set up PWM on a PIC24FJ128GA310.
This has 5 output compare channels and also 5 timers.
A PWM output is generated but I can't change the period. For example a duty of 200 produces a tiny pulse, 100% duty needs 65535 no matter what values I use for period in the timer setup or set_pwm_period() command.
As a result the frequency of the square wave is too low for my filter to smooth out to an analogue voltage.
I have tried timer2, same result.
I have 16MHz internal clock and am using code as below.
Does anyone have a working example on this chip, or can spot if I've made an obvious mistake?
Many thanks
Evan
Code: |
#include <24FJ128GA310.h>
#use delay(int=16000000)
#pin_select OC5=PIN_D4 // for 0-5out1
#INCLUDE <math.h>
void main()
{
setup_timer1(TMR_INTERNAL | TMR_DIV_BY_1, 254);
setup_compare(5, COMPARE_PWM_EDGE| COMPARE_TIMER1);
set_pwm_period(5, 254);
set_pwm_duty(5,200);
while(1)
{
}
}
|
CCS PCD C Compiler, Version 5.078, 41712 04-Jun-18 18:32 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jun 04, 2018 12:08 pm |
|
|
Look at the PCD PWM example file. It shows how to set this up. Don't get confused by the old PIC16/18 difference, that the timer period is 4* the PWM period, on these chips they use the same units. |
|
|
evan
Joined: 02 Apr 2012 Posts: 22
|
|
Posted: Mon Jun 04, 2018 12:18 pm |
|
|
Ttelmah wrote: | Look at the PCD PWM example file. It shows how to set this up. Don't get confused by the old PIC16/18 difference, that the timer period is 4* the PWM period, on these chips they use the same units. |
Hi Ttelmah. Thanks, ex_pwm_pcd is how I got this far! But the period still can't be changed, even if I use the setup exactly the same as that example (it uses a value of 65472 which is almost the maximum anyway). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jun 04, 2018 12:42 pm |
|
|
Remember the fault input needs to be turned off.
This thread had basically the same problem:
<http://www.ccsinfo.com/forum/viewtopic.php?t=56176&highlight=output+compare>
There was a partcular problem there with the even timer, but the standard setups I posted did work for me. |
|
|
evan
Joined: 02 Apr 2012 Posts: 22
|
|
Posted: Mon Jun 04, 2018 2:31 pm |
|
|
OK, that thread helped... Thanks.
Interrupts for the timer have to be turned on, it does say that in the datasheet but it wasn't in the example so I missed it.
Now I can change the period. However, now I can't change the duty! It's stuck at some very small value no matter what value I compile with. Argh!
Last edited by evan on Mon Jun 04, 2018 4:07 pm; edited 1 time in total |
|
|
evan
Joined: 02 Apr 2012 Posts: 22
|
|
Posted: Mon Jun 04, 2018 4:05 pm |
|
|
Right, further investigation.
The bottom line is, the example is no use for the output compare modules on this chip.
It can now generate PWM by itself based on the main clock, no need to use a timer in conjunction with it.
[edit] this has been pretty frustrating. I wish the manual and examples were more up to date with the devices.
Code that works is below, if anyone else needs to get PWM working.
Code: |
#include <24FJ128GA310.h>
#use delay(int=16000000)
#pin_select OC5=PIN_D4 // for 0-5out1
#INCLUDE <math.h>
#word OC5RS=0x01BC
#word OC5R=0x01BE
#word OC5TMR=0x01C0
#word OC5CON1=0x01B8
#word OC5CON2=0x01BA
long pwm=0;
void main()
{
OC5R=2000; // duty
OC5RS=10000; // period
OC5CON2|=0x1F;
OC5CON1|=0x1C00;
OC5CON1|=0x6;
while(1)
{
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Jun 05, 2018 12:27 am |
|
|
I think the examples given should work fine.
However your settings need to say to use free running mode. The default otherwise will be to be in synchronous mode.
I don't have the include files handy here at present, but there should be an option to use the peripheral clock rather than the peripheral clock. |
|
|
maffewFlee
Joined: 05 May 2020 Posts: 1
|
Possible Fix |
Posted: Tue May 05, 2020 8:02 pm |
|
|
Hello Evan and Ttelmah,
I was working on creating a pwm signal on a dsPIC33EV...106 and I ran into the same issue that you were discussing here. I believe I found a way to make setting the timer period affect the pwm period.
If you OR the COMPARE_TRIG_SYNC_TIMER2 when setting up the CPP PWM, it uses the timer correctly. Thus, using Timer2 and CPP1, the setup should be (replace pwmPeriod and pwmDuty with your values):
Code: |
setup_timer2(TMR_INTERNAL|TMR_DIV_BY_8, pwmPeriod);
setup_compare(1, COMPARE_PWM_EDGE | COMPARE_TIMER2 | COMPARE_TRIG_SYNC_TIMER2);
set_pwm_duty(CMP_MOD, pwmDuty);
|
Hope this helps! |
|
|
|