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

PWM PIC24EP64GP204 output help
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
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PWM PIC24EP64GP204 output help
PostPosted: Fri Aug 08, 2014 10:10 pm     Reply with quote

Compiler 4.130
PIC TARGET: pic24EP64GP204

Target Output; ON Pin_C9

I'm attempting to make a basic SawTooth output on this pin c9;

basically 44000 PWM output, and i want to use DUTY for volume output for sound output.

but the code i have makes a very low PWM output and the DUTY cycle just makes a horrible output.

Code:

#include <24EP64GP204.h>



#DEVICE *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PROTECT                //Code not protected from reading
#FUSES   FRC_PLL
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOJTAG                   //JTAG disabled
#FUSES NODEBUG                  //No Debug mode for ICD



#use delay(CLOCK=140Mhz, INTERNAL=6Mhz)


#zero_ram




#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5

#pin_select OC1   = PIN_C9


#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)

#int_TIMER2
void  TIMER2_isr(void)
{

}




void main(){

   setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1);
   set_pwm_duty(1,200);
   setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER2 | COMPARE_TRIG_SYNC_TIMER2);


   setup_spi( FALSE );
   setup_spi2( FALSE );


   setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);


   //enable_interrupts(INT_TIMER2);

   // TODO: USER CODE!!
   printf("\n\n* OK BOOTY\n");
   
   
   
   unsigned int8 log;
   
   while(1){
      log++;
      
      set_pwm_duty(1, log);   
      delay_us(150);
   }

}





---------- THE EQUIVALENT effect successful on this ----
Compiler 5.015

Code:

#include <24EP64GP204.h>

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

#device ICSP=1
#use delay(internal=140MHz)
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#use rs232(UART1, baud=115200, stream=UART_PORT1)

#use pwm(OC1,OUTPUT=PIN_C9,TIMER=1,FREQUENCY=44000,DUTY=50)

void main()
{

   int8 duty;

   while(TRUE)
   {
      duty++;
      //TODO: User Code
      set_pwm_duty(1, duty);   
      delay_us(10);

   }

}


Last edited by neochrome32 on Sat Aug 09, 2014 9:16 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19503

View user's profile Send private message

PostPosted: Sat Aug 09, 2014 2:51 am     Reply with quote

1) Simplify.
Over half the program lines posted are remmed out, or are pointless (*=16, only applies to '14bit parts' etc....).

2) Think. Where are you telling the timer to reset?. This is the optional second value in the timer setup line, which you are omitting....
Look at the example file. ex_pwm.c. It shows how to setup the timer, and PWM.
As it stands, your timer is counting 65536 cycles.
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sat Aug 09, 2014 9:27 am     Reply with quote

i've tidied up the code, and i didnt see the *=16

you say pointless as this device is a 24bit system right? at least its what is said in the data sheet..

OH MAN i see it!! i'll give that a blast..
admittedly i just used a working code from another source project i did..

giving it a try ...


thanks man.......

Code:

   setup_compare(1,COMPARE_PWM_CENTER | COMPARE_TIMER3 );
   set_compare_time(1, 0x1000);// this was the missing key!!
   setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 1);


still didn't work!

i uploaded the wrong code thinking it was THIS code!
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sat Aug 09, 2014 10:50 am     Reply with quote

compiler 4.130

PCD


Code:

#include <24EP64GP204.h>



#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PROTECT                //Code not protected from reading

#FUSES NOIESO                   //Internal External Switch Over mode disabled

#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode


#FUSES NOJTAG                   //JTAG disabled
#FUSES NODEBUG                  //No Debug mode for ICD



#use delay(CLOCK=140Mhz, INTERNAL=8Mhz)

#zero_ram




#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5

#pin_select OC1   = PIN_C9


#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)

#int_TIMER2
void  TIMER2_isr(void)
{

}




void main(){
 unsigned int16 log;

   setup_compare(1,COMPARE_PWM_CENTER | COMPARE_TIMER5 );
   set_compare_time(1, 0x1);
   setup_timer5(TMR_INTERNAL | TMR_DIV_BY_1, 1);


   setup_spi( FALSE );
   setup_spi2( FALSE );
   
   //enable_interrupts(INT_TIMER2);

   // TODO: USER CODE!!
   printf("\n\n* OK BOOTY\n");
   
   
   
 
   
   while(1){
      //log++;
      log+=16;
      
      set_pwm_duty(1, log);   
      delay_us(150);
   }

}


still no joy

please say my clocks are configured correctly! they seem to be while running a simple led blinking, but i just cant get this PWM to get any faster! feels like my clock is still wrong! but i cant see it!
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sat Aug 09, 2014 12:41 pm     Reply with quote

as not to tear out my hair!
could the compiler be too early for what i want to acheive for this chip?

PIC24 EP 64 GP 204?

i read one of my previous posts and Ttelmah says something along those lines, the compiler 5.015 does it all for you using the #use pwm();

kinda wanted to avoid this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19503

View user's profile Send private message

PostPosted: Sat Aug 09, 2014 1:59 pm     Reply with quote

Whoa.

Look at the example. You are still not setting the timer limit properly.

No, 5.015, does not 'do it all for you'. #use pwm, _attempts_ to, and will more often than not, give the wrong time, and leaves you not knowing what the actual values needed for the duty are. It has been done to 'resemble' setting formats used on the Arduino, but is dangerous for any real application, except for very simple applications....
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sat Aug 09, 2014 11:41 pm     Reply with quote

Thanks Ttelmah, sadly the EX_PWM doesn't compile for the chip.

Oddly the #USE PWM appears to do what i need it to do quite successfully.

Sort of a bodged code, but its doing what i need... so "You just keep going, no matter how crazy it seems".
Ttelmah



Joined: 11 Mar 2010
Posts: 19503

View user's profile Send private message

PostPosted: Sun Aug 10, 2014 3:43 am     Reply with quote

I just took your code, simplified, and put in the one critical number missing, which is in the example:
Code:

   setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1, 1590);
   //The key missing number (Fp/44000)-1


Without this, the timer is going to count to 65536, so will run 41* too slow, and the modulation will be under 0.5%....

It is one of those, 'look, think, understand' major differences.
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 10, 2014 9:09 am     Reply with quote

i took that in hand, and i added it even 1, and it still was too slow, is as though the compiler ignored it... however the SAME CODE (without #use pwm)

worked a treat... very strange,


Thanks for that tip though, but im sure i tried the setup_timer2(TRMP_TERNAL | TMR_DIV_BY_1, 1);

just for kicks, and it still didn't work :(
Honestly this was a mistery

been using PWMs for ages, but for that one chip, didn't seem to work! LOL

Thank you Ttelmah
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 10, 2014 10:46 am     Reply with quote

ok it seems to be as you say Ttelmah, strange as i did this last time on timer 2 didn't work

timer3 ok

but has this... (image link)

Code:

#include <24EP64GP204.h>



#DEVICE *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PROTECT                //Code not protected from reading
#FUSES   FRC_PLL
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOJTAG                   //JTAG disabled
#FUSES NODEBUG                  //No Debug mode for ICD



#use delay(CLOCK=140Mhz, INTERNAL=7.37Mhz)


#zero_ram




#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5

#pin_select OC1   = PIN_C9


#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)

#int_TIMER2
void  TIMER2_isr(void)
{

}




void main(){

   setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 270);
   set_pwm_duty(1,300);
   //setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
   setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);


   setup_spi( FALSE );
   setup_spi2( FALSE );


   setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);


   //enable_interrupts(INT_TIMER2);

   // TODO: USER CODE!!
   printf("\n\n* OK BOOTY\n");
   
   
   
   unsigned int8 log;
   
   while(1){
      log--;
     
      set_pwm_duty(1, log);   
      delay_us(15);
   }

}




there is a block where it looks weird!

i found that the higher the value the stranger the shape! its meant to be a sawtooth, but the above code is as close as i can get it!
NOTE: the 270 in the secondary param? the higher value for 44100Khz the strange shape was WORSE.


[[edit]]

think i know what it is! im trying to use an 8bit value and it might be a 16bit pwm!?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 10, 2014 11:15 am     Reply with quote

Have you looked at the errata for this PIC ? There are tons of PWM
errata on the PIC24EP64GP204:
http://ww1.microchip.com/downloads/en/DeviceDoc/80000533k.pdf
Errata No. 43 talks about a glitch when the duty cycle is updated to 0.
That might be it, or it could be one of the other PWM problems listed.
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 10, 2014 11:46 am     Reply with quote

PWM
Dead-Time Compensation
11.
Dead-time compensation is not enabled for Center-Aligned PWM mode.

seems to be this...... but the EDGE doesn't do anything at all
Ttelmah



Joined: 11 Mar 2010
Posts: 19503

View user's profile Send private message

PostPosted: Sun Aug 10, 2014 12:27 pm     Reply with quote

Can I ask why you always set the sync mode?.

Sync mode is normally only used when the timer is being run of an external clock, so that it updates synchronously to the system clock. Your timer is already running off the system clock.
Probably not the problem, but it will cause a cycle of delay, that will upset the timings at short values.
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 10, 2014 4:35 pm     Reply with quote

because if i dont, it doesn't work at all! LOL
neochrome32



Joined: 09 Jun 2013
Posts: 153

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 10, 2014 8:29 pm     Reply with quote

OK WEIRD

same code;
Code:

#include <24EP64GP204.h>



#DEVICE *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PROTECT                //Code not protected from reading
#FUSES   FRC_PLL
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOJTAG                   //JTAG disabled
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPR



#use delay(CLOCK=140Mhz, INTERNAL=7.37Mhz)


#zero_ram




#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5

#pin_select OC1   = PIN_C9


#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)

#int_TIMER2
void  TIMER2_isr(void)
{

}




void main(){

   setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 1255);
   set_pwm_duty(1,200);
   //setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
   //setup_compare(1, COMPARE_PWM_EDGE | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
   setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);


   setup_spi( FALSE );
   setup_spi2( FALSE );


   setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);


   //enable_interrupts(INT_TIMER2);

   // TODO: USER CODE!!
   printf("\n\n* OK BOOTY\n");
   
   //FOR(;;);
   
   unsigned int8 log;
   
   while(1){
      log--;
     
      if(log!=0) set_pwm_duty(1, log);   
      delay_us(15);
   }

}



Compiles and runs wonderfully on 5.015!
looks like im gonna have to be upgrading :(
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