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

Software Pwm

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
brood



Joined: 23 Jan 2007
Posts: 12

View user's profile Send private message

Software Pwm
PostPosted: Tue Mar 13, 2007 9:26 am     Reply with quote

Hello all,

Here is an example program I wrote for a PIC16F917 to create a 100Hz pwm signal with 256 duty cycle steps. it utilizes a interrupt that occurs every 25.8kHz to check for the duty cycle steps. Its possible to add extra pwm outputs with that has the same frequency but with different duty cycles.

Code:

//**************************************************************************************************
// Andre Broodryk
// Led fader
// 2006/07
//**************************************************************************************************

#include <16F917>
#fuses INTRC_IO,NOPROTECT,NOWDT,PUT
#use delay(clock=8000000)
#use standard_io(d)
#define preload 65458
#define red pin_d0
#define green pin_d1
#define blue pin_d2

//**************************************************************************************************
//Global variables
//**************************************************************************************************

int red_duty;
int green_duty;
int blue_duty;
int Intcount;

//**************************************************************************************************
//100Hz pwm (interrupt at 25.8kHz
//**************************************************************************************************

#INT_TIMER1
void timer_irq()
{
    set_timer1(preload);
   
   if (Intcount < 255)
    {
      if (Intcount == red_duty)
       {
         output_low(red);
       }   
      if (Intcount == green_duty)
       {
         output_low(green);
       }   
      if (Intcount == blue_duty)
       {
         output_low(blue);
       }   
    }
   
   else if(Intcount == 255)
    {
      Intcount = 0;
      output_high(red);
      output_high(green);
      output_high(blue);   
    }   
    Intcount++;
}


//**************************************************************************************************
// Main Program
//**************************************************************************************************

void main()
{
   setup_oscillator(OSC_8MHZ);
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
   red_duty = 63;
   green_duty = 1;
   blue_duty = 250;
   Intcount = 0;

   for (;;)
   {

      
   }
}



Hope some one will find it useful

CCS Compiler version used: 3.228
horizontech



Joined: 09 Nov 2003
Posts: 13

View user's profile Send private message Send e-mail

PWM
PostPosted: Wed May 16, 2007 7:15 pm     Reply with quote

Hi !

I have made a test with 3 channels !

When i try 4 or 6 channel i got some glitch when I perfrom a cross fade.
Which parameter I need to change for 6 channel ?

Here is my code for fade in/ fade out:
Code:

ala:
Intcount = 0;
a=1;
while(a<254>1){
   red_duty =a;

   delay_ms(2);
   a--;}

a=1;
while(a<254>1){
   cha =a;

   delay_ms(2);
   a--;}


goto ala;
Greg Richter



Joined: 15 Feb 2008
Posts: 18
Location: Atlanta, Tulsa, Asheville

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

Tiny software PWM
PostPosted: Fri Feb 15, 2008 1:20 pm     Reply with quote

OK, this is TINY, but it works a treat. Set an interrupt to call this at whatever freq you like best, and off you go.
Code:

// The ISR is called at about 9.8 kHz, forming a square wave with 255
// counts per period, 128 counts high and 128 low for a 74 Hz signal at 50%
// duty cycle.  The high counts vary with global variables AileronPWM
// and ElevatorPWM. 
//
#int_timer2       
void PWMisr()     
{
 static int8 pwm=0;
 
 pwm <= AileronPWM  ? output_high(AILERON_MOTOR)  : output_low(AILERON_MOTOR); 
 pwm <= ElevatorPWM ? output_high(ELEVATOR_MOTOR) : output_low(ELEVATOR_MOTOR);
 pwm ++;
}

This is dirt simple, but I find myself using it quite a lot ...
_________________
Madness takes it toll; please have exact change.
kash



Joined: 12 Apr 2008
Posts: 1

View user's profile Send private message

dspic
PostPosted: Sat Apr 12, 2008 4:42 am     Reply with quote

have you worked out using C for dspic if please send the sample progs
ricperez



Joined: 25 Apr 2007
Posts: 14

View user's profile Send private message

Thanks for the push...
PostPosted: Sun Jun 01, 2008 8:26 pm     Reply with quote

Very Happy Thanks for sharing this program Brood. It helped me to step into PCM programming! I had purchased my compiler more than a year ago before I started using it. Since then I´ve done lots of variations and have even gone into PWM built into PICs. Very Happy
Simbo



Joined: 02 Mar 2008
Posts: 7
Location: UK

View user's profile Send private message MSN Messenger

PostPosted: Thu Mar 25, 2010 4:18 pm     Reply with quote

How would I go about changing the duty cycle from a standard serial terminal using the pic uart?

I have tried and failed and could really use a hint or example!

Thanks for any help

Simbo
_________________
<~Simbo~>
salanki



Joined: 28 Apr 2012
Posts: 2
Location: New York, NY

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

PostPosted: Sat Apr 28, 2012 2:35 pm     Reply with quote

Could anyone help me figure out the math here for a PIC12F1822.

With the preload set at 65458, and the timer overflowing at 65535 this would give us 77 timer increments until overflow. Now running at 8Mhz this would overflow 103,896 times a second (8M/77). Now the 12F1822 documentation states that "When the FOSC internal clock source is selected, the
Timer1 register value will increment by four counts every
instruction clock cycle.". This makes me belive that the 77 number should be divided by four: (8M/(77/4)) which would give us 415,584 overflows per second (415Khz).

What am I doing wrong?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed May 09, 2012 3:37 pm     Reply with quote

Simbo wrote:-
Quote:

How would I go about changing the duty cycle from a standard serial terminal using the pic uart?

I have tried and failed and could really use a hint or example!

Thanks for any help.

I don't understand the question.

What are you trying to achieve?

Mike

salanki wrote:-
Quote:
Could anyone help me figure out the math here for a PIC12F1822.

With the preload set at 65458, and the timer overflowing at 65535 this would give us 77 timer increments until overflow. Now running at 8Mhz this would overflow 103,896 times a second (8M/77). Now the 12F1822 documentation states that "When the FOSC internal clock source is selected, the
Timer1 register value will increment by four counts every
instruction clock cycle.". This makes me belive that the 77 number should be divided by four: (8M/(77/4)) which would give us 415,584 overflows per second (415Khz).

What am I doing wrong?

Do you mean 8Mhz Fosc or 8MHz instruction cycles?

How are you proposing to preload Timer1 after each overflow on a 12F1822?

You've got me confused.

Mike
40inD



Joined: 30 Jul 2007
Posts: 112
Location: Moscow, Russia

View user's profile Send private message

PostPosted: Wed Dec 10, 2014 5:07 am     Reply with quote

When I use the example from the first post with 4-channel PWM, at 0% duty LEDs still poorly lit.
Where is the problem?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Dec 10, 2014 1:11 pm     Reply with quote

40inD wrote:
When I use the example from the first post with 4-channel PWM, at 0% duty LEDs still poorly lit.
Where is the problem?


When interrupt counter is reset you always get one cycle of LEDs on.
The software is not designed to give 0% output.

Problem is with this bit of code
Code:
   else if(Intcount == 255)
    {
      Intcount = 0;
      output_high(red);
      output_high(green);
      output_high(blue);   
    }   
    Intcount++;


It needs modifying to give zero output when asking for 0% PWM.

Mike

EDIT I suspect PWM duties of 0 and 1 give the same output!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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