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

set_pwm1_duty(0); Is not outputing 0%!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

set_pwm1_duty(0); Is not outputing 0%!
PostPosted: Thu Jul 05, 2012 5:32 pm     Reply with quote

Hello guys! I am currently working in a project with the PIC18F2550 and when I use the set_pwm1_duty(0); function call I still get a very small pulse of 1uS, but I was expecting to get a flat line i.e. 0% PWM right?

My configurations are:
Code:

#include <18F2550.h>
#device adc=10

//#FUSES HS                    //No Watch Dog Timer
#FUSES PLL5                     //Divide By 5(20MHz oscillator input)
#FUSES CPUDIV1

#FUSES HSPLL                    //High Speed Crystal/Resonator with PLL enabled


//#use delay(crystal=20000000,  clock=10000000)
#use delay(clock=20000000)

setup_timer_2(T2_DIV_BY_16,125,1);

using an 20MHz crystal.

I have also tried to configure the registers myself using this:
#byte CCP1CON = getenv("SFR:CCP1CON")
#byte CCPR1L = getenv("SFR:CCPR1L")
#byte CCP2CON = getenv("SFR:CCP2CON")
#byte CCPR2L = getenv("SFR:CCPR2L")

bit_clear(CCP2CON,5);
bit_clear(CCP2CON,4)

but still it behaves the same way....

My test code is a very simple one...I mixed the test inside an old code, so that's why I am setting so many things
Code:

void main(void)
{
   
   delay_us(10);   
   output_a(0x04);
   output_b(0x00);
   output_c(0x00);
   
   output_high(DISABLE);
   
   set_tris_a(0b00000011);
   set_tris_b(0b11010111);
   set_tris_c(0b10000001);
   
   output_high(DISABLE);
   
   output_low(BHI);
   output_low(AHI);
   output_low(LED);
   output_low(ALI);
   output_low(BLI);
     
   port_b_pullups(FALSE);
   
   if (!input(CONFIG_EMR))
      configuraLimitesRC();
     
   carregaConfiguracoes();
   
   //configurando o PWM
   //setup_timer_2(T2_DIV_BY_4,249,1);      //200 us overflow, 200 us interrupt
   setup_timer_2(T2_DIV_BY_16,125,1);      //200 us overflow, 200 us interrupt
   
   set_pwm1_duty(0);   
   set_pwm2_duty(0);
   
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
     
   set_pwm1_duty(0);   
   set_pwm2_duty(0);
   
   delay_ms(10);
   set_pwm1_duty(499);   
   set_pwm2_duty(499);
   
   delay_ms(10000);

   set_pwm1_duty(0);   
   set_pwm2_duty(0);
       
    /*bit_clear(CCP2CON,5);
    bit_clear(CCP2CON,4);
    CCPR2L = 0;
    bit_clear(CCP1CON,5);
    bit_clear(CCP1CON,4);
    CCPR1L = 0;    */
    delay_ms(20000);
     
   //configurando o ADC
   setup_adc_ports(AN0_TO_AN1);
   setup_adc(ADC_CLOCK_INTERNAL );
   
   //configurando os timers
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);      //26.2 ms overflow 0.4us resolution, usado em  Tempo inicial e final do RC e Fail Safe   
   
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   
   setup_comparator(NC_NC_NC_NC);
   
   //configurando as interrupcoes
   enable_interrupts(INT_EXT2);
   
   enable_interrupts(GLOBAL);
   
   output_low(DISABLE);
   
   
   while(TRUE)
   {
     
   }
}

As you can see I am setting the PWM to 100% and then bringing it to 0%....but I dont get 0%! I still get a 1us pulse! (I know this code makes more than that, but I am looking at the behavior of the begining, sice there are 30s to look at).

In another function call this behavior is intermintent...I call this function many time, and sometimes there is a flat line, sometimes there is the 1us pulse....does anyone has any ideas why is this happening?

Thank's a lot!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 6:16 pm     Reply with quote

Your test program is too complicated. Try this program instead and see
what you get:
Code:

#include <18F2550.h>
#fuses INTRC_IO, NOWDT, PUT, BROWNOUT, NOLVP, CPUDIV1
#use delay(clock=4M)

//=================================
void main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 125, 1);

while(1)
  {
   // Run for 3 seconds.
   set_pwm1_duty(63);    // 50% duty cycle
   delay_ms(3000);

   // Stop for 3 seconds.
   set_pwm1_duty(0);    // PWM off
   delay_ms(3000);
  }


}
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 6:33 pm     Reply with quote

I got

Error 111: Unknown keyword in #fuses INTRC_IO
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 6:40 pm     Reply with quote

What is your CCS compiler version ? Compile a test program so that
it doesn't give any errors (remove the INTRC_IO and put in HS).
Then go to your project directory and view the .LST file. At the top, it
will have a 4-digit number, like the ones in this list:
http://www.ccsinfo.com/devices.php?page=versioninfo

What is your version ?
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 6:41 pm     Reply with quote

I modified your code to:
Code:

#include <18F2550.h>
#fuses  NOWDT, PUT, BROWNOUT, NOLVP, CPUDIV1
#use delay(clock=20M)

//=================================
void main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 125, 1);

while(1)
  {
   // Run for 3 seconds.
   set_pwm1_duty(99);    // 50% duty cycle
   delay_ms(3000);

   // Stop for 3 seconds.
   set_pwm1_duty(0);    // PWM off
   delay_ms(3000);
  }

and it compiled and worked! 0 was 0 as expected ! I think my problem is my timer configurations in the FUSES.... I am using an 20MHz crystal and I want to bring the PIC to 48MHz with PLL and everything else....can you see any problems in my #FUSES?

Thanks!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 7:03 pm     Reply with quote

Nope. No version, no help. Different versions have different bugs.
I can't give a real answer without the version. I'm going home for
the day now.
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Thu Jul 05, 2012 7:32 pm     Reply with quote

Version 4.120...no problem, this is not urgent, I can wait your reply!

CCS PCM C Compiler, Version 4.120, 5967 06-jul-12 04:43
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 06, 2012 12:49 pm     Reply with quote

Quote:
Version 4.120.
I am using an 20MHz crystal and I want to bring the PIC to 48MHz with PLL.

This program will run the PIC at 48 MHz. The PWM frequency will be
5.952 KHz:
Code:

#include <18F4550.h>
#fuses HSPLL, NOWDT, PUT, BROWNOUT, NOLVP,PLL5, CPUDIV1
#use delay(clock=48M)

//=================================
void main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 125, 1);

while(1)
  {
   // Run for 3 seconds.
   set_pwm1_duty(63);    // 50% duty cycle
   delay_ms(3000);

   // Stop for 3 seconds.
   set_pwm1_duty(0);    // PWM off
   delay_ms(3000);
  }

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Sat Jul 07, 2012 12:59 pm     Reply with quote

There is a key thing that will cause this problem.
It is the old difference between an int16, and an int8 behaviour.
If you use:

set_pwm1_duty(0);

This sets the top 8bits if the 10bit pwm to zero, _but does not update the low two bits_. So if the PWM has already been driven by a 10bit value which sets these to a non zero value, they will stay non zero, and you will get the tiny pulse.

set_pwm1_duty(0L);

will set all ten bits to zero.

Best Wishes
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Sat Jul 07, 2012 9:20 pm     Reply with quote

Ttelmah thanks a lot for your answer! I would never thought about something like that....monday, when I will be back to the lab, I will test it and see if that fixes everything.

But I already had tried (as I posted before)
Code:

#byte CCP1CON = getenv("SFR:CCP1CON")
#byte CCPR1L = getenv("SFR:CCPR1L")
#byte CCP2CON = getenv("SFR:CCP2CON")
#byte CCPR2L = getenv("SFR:CCPR2L")

bit_clear(CCP2CON,5);
bit_clear(CCP2CON,4);
CCPR2L = 0;
bit_clear(CCP1CON,5);
bit_clear(CCP1CON,4);
CCPR1L = 0;   

and it didn't work also...but as far as I can see this code does the same thing that you proposed right? Setting all the bytes from the PWM to 0?

Best Regards!
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Mon Jul 09, 2012 2:46 pm     Reply with quote

Ttelmah, thank you again! It worked! 0% PWM is 0 now :D

But I still dont understand why when I set the registers to 0 it didnt work?

Another quick question:
When I call:
set_pwm1_duty(PWM);
And PWM is an unsigned int 16 variable, it will get all the bytes all the time right? So I dont have to force it with a type cast, right?

Best Regards!
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Jul 10, 2012 1:17 am     Reply with quote

Yes, if the variable being passed, is an int16, full 10bit update is done.

Just FYI, thought setting the bits would appear it should work, I have met this before.
You can do it 'manually', with:
Code:

CCPR1L = 0;
CCP1CON=CCP1CON & 0xCF;

Though the data sheet implies the bits are latched on the next update of the PWM, and makes no mention of requiring them needing writing in a particular order, it only seems to work 'right', if you update the separate bits _after_ updating the register, and, change both in a single instruction. There is nothing in the data to say the other way won't work, but on some chips, it just doesn't.....
The CCS routine I knew 'worked', so easiest to use it. Smile

Best Wishes
mfeinstein



Joined: 05 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Tue Jul 10, 2012 7:09 pm     Reply with quote

Oh, that's tricky!
Anyways, thank you very much for your help, everything seems to be working perfectly now! You are my hero ; )
Best Regards!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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