View previous topic :: View next topic |
Author |
Message |
brood
Joined: 23 Jan 2007 Posts: 12
|
Software Pwm |
Posted: Tue Mar 13, 2007 9:26 am |
|
|
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
|
PWM |
Posted: Wed May 16, 2007 7:15 pm |
|
|
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
|
Tiny software PWM |
Posted: Fri Feb 15, 2008 1:20 pm |
|
|
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
|
dspic |
Posted: Sat Apr 12, 2008 4:42 am |
|
|
have you worked out using C for dspic if please send the sample progs |
|
|
ricperez
Joined: 25 Apr 2007 Posts: 14
|
Thanks for the push... |
Posted: Sun Jun 01, 2008 8:26 pm |
|
|
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. |
|
|
Simbo
Joined: 02 Mar 2008 Posts: 7 Location: UK
|
|
Posted: Thu Mar 25, 2010 4:18 pm |
|
|
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
|
|
Posted: Sat Apr 28, 2012 2:35 pm |
|
|
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
|
|
Posted: Wed May 09, 2012 3:37 pm |
|
|
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
|
|
Posted: Wed Dec 10, 2014 5:07 am |
|
|
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
|
|
Posted: Wed Dec 10, 2014 1:11 pm |
|
|
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! |
|
|
|