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 start and stop

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



Joined: 12 Nov 2007
Posts: 37

View user's profile Send private message

PWM start and stop
PostPosted: Fri Jan 29, 2010 5:51 am     Reply with quote

How I can start and stop PWM? When stop PWM_OUT_PIN is low (0).
When start duty is 50%. My device is PIC16F616.
Code:

#include "C:\Project\PWM.h"
void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_wdt(WDT_2304MS);
   setup_timer_1(T1_DISABLED);

   setup_timer_2(T2_DIV_BY_1,99,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(150);

   setup_comparator(CP1_A1_VREF);

   while(1)
   {
     
   }
}
mbradley



Joined: 11 Jul 2009
Posts: 118
Location: California, USA

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

PostPosted: Fri Jan 29, 2010 10:01 am     Reply with quote

Here is a tiny snippet from a project I did, to stop the motors from moving. (This was part of a touchpad lens controller)

ZOOM_A is a pwm output pin, _B is just a GPIO
FOCUS_A is a pwm output pin, _B is just a GPIO
STOP is 0, so both motor pins get a logic low

A&B pins went to mosfets, depending on the state of _B I can controll motor direction

Code:

void stopMotors(void)
{
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
   output_bit(ZOOM_A,STOP);
   output_bit(ZOOM_B,STOP);
   output_bit(FOCUS_A,STOP);
   output_bit(FOCUS_B,STOP);
   flagIsOnZoom = false;
   flagIsOnFocus = false;
}


_________________
Michael Bradley
www.mculabs.com
Open Drivers and Projects
Ttelmah
Guest







PostPosted: Fri Jan 29, 2010 10:15 am     Reply with quote

As a further comment, on the original posted code, do a search on the forum about the numbers used to control the PWM duty cycle.
For 50% duty cycle, you need to use 200L. Notice the 'L'.
The search will reveal 'why'.

Best Wishes
jjude



Joined: 12 Nov 2007
Posts: 37

View user's profile Send private message

PostPosted: Fri Jan 29, 2010 2:27 pm     Reply with quote

Ttelmah wrote:

For 50% duty cycle, you need to use 200L. Notice the 'L'.


set_pwm1_duty(0L); is 0% PWM "stop" and output is LOW ?
set_pwm1_duty(200L); is 50% ?
What is 100%?
Why L ?
Ttelmah
Guest







PostPosted: Fri Jan 29, 2010 3:43 pm     Reply with quote

The PWM, counts from '0', to your (Timer2 reset value+1)*4 and resets.
In your case, 0 to 399, and resets on the 400th count.
Any value greater than this, up to 1023 (the maximum that can be loaded into the registers), will leave the output high.

Best Wishes
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Fri Jan 29, 2010 3:50 pm     Reply with quote

Depending on your oscillator frequency and the PWM frequency, the number inside the pwm function will change (set_pwm1_duty(XX)).

What Ttelmah is referring to is that the PWM register is 10-bits; so the set_pwm1_duty function can use either a 8-bit byte or 16-bit long. So set_pwm1_duty(150L) is not the same as set_pwm1_duty(150). The former is casted to a long value and the later is a byte value (so they give different duty cycles).

After you determine your PWM frequency, and TMR2 div-ratio, you can tell what number you need to pre-load the PWM register for 100% (and anything below). If the calculations you used for the PWM register were based on 10-bits (this would be normally the case) then you need the "L" suffix after the number so the set_pwm1_duty works as you expect.

As for the set_pwm1_duty(0L) giving you 0% or setting the output LOW; you can try it yourself. set_pwm1_duty(0L) still keeps the PWM operational. In theory, you are still pulsing the output; but nothing should ever come out. I have seen instances where there is some leakage and very narrow spikes are present. If you require the output to go low and stay low, without worries; I would follow something like what mbradley suggested.
Ttelmah
Guest







PostPosted: Fri Jan 29, 2010 3:58 pm     Reply with quote

The reason for leakage, is that people use:

set_pwm1_duty(0);

Rather than '0L'.

If you use a 'short' value, as opposed to a long, the low two bits of the 10bit register don't get updated. So, if there is anything other than '00' in these two bits, when you try to set '0', a small pulse will be generated. The same happens with the 'full on' value, where if there is anything other than '11' already loaded in these two bits, again a small pulse will be seen.....
Using the long value throughout, avoids the problem.

Best Wishes
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Fri Jan 29, 2010 4:01 pm     Reply with quote

Learned something new. That makes perfect sense. Since I learned about the "L", I have never seen any glitches happen; still I figured why take a chance. However, what you say fully explains it.

Thanks for the piece of info...
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