View previous topic :: View next topic |
Author |
Message |
MrXploder
Joined: 14 Mar 2013 Posts: 6
|
Software PWM for General Purpose |
Posted: Thu Mar 14, 2013 8:53 pm |
|
|
I always use rgb led just for fun. Even I made a nice lamp for my girlfriend.
Here is a tiny library to use any io pin as a pwm and as many you want...
its uses the timer 2 and unfortunately you will have to configure the Timer2 manually (you can help me to do this automatically).
I use the picwizard to get the code for the timer. Just make sure that the interrupt period is greater than 120uS.
Code: | #define numpwmouts 4
static int8 pwmvalues[numpwmouts];
static int8 auxvalues[numpwmouts];
int8 pwmpins[numpwmouts]={pin_b0,pin_b1,pin_b2,pin_b3};
int8 i=0;
#INT_TIMER2
void timer2_isr(){
int8 z;
for(z=0;z<numpwmouts;z++){
if(i==auxvalues[z] && auxvalues<255) output_low(pwmpins[z]);
}
++i;
if(i==255){
for(z=0;z<numpwmouts;z++){
if(auxvalues[z]!=0) output_high(pwmpins[z]);
auxvalues[z]=pwmvalues[z];
}
i=0;
}
}
void sw_pwm_init(){
setup_timer_2(T2_DIV_BY_1,6,16);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
}
|
variables:
numpwmouts 4 // is the total software pwm outs
static int8 pwmvalues[numpwmouts]; // this is used to set the duty value for each pin
static int8 auxvalues[numpwmouts]; //aux variable used to set the duty at the start of the timer 2 interrupt and not in any moment
int8 pwmpins[numpwmouts]={pin_b0,pin_b1,pin_b2,pin_b3}; // set here the pins that will be used as a sotware pwm
int8 i=0; timer 2 counter... |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Mar 15, 2013 4:12 pm |
|
|
am i reading this right ?
i assume 120 usecs is the worst case execution time of the interrupt
and that therefore:
If we are interrupting at the maximum frequency which produces a 120 usec #int cycle , we are only talking a master "#int call" rate of 8333hz. (1/8333=120usec)
in the interrupt handler, we have to call it 256 times to accurately generate all possible phases for one complete PWM cycle, right ?
And as there are 256 possible phase transition times, to complete a decoded master at 8 bit resolution , that implies a PWM baseline repetition frequency of no more than 32.5hz
and that would be with the timer2 interrupt saturated.
what on earth is a 32 hz PWM( or less) of any use for, that eats up all the CPU capacity in the process ?? |
|
|
MrXploder
Joined: 14 Mar 2013 Posts: 6
|
|
Posted: Fri Mar 15, 2013 4:59 pm |
|
|
sorry but I didnt understand something.. do you mean that 32hz pwm is too low?.. but this is only for leds.. due to the POV is more than enough.. when do you generate more frecuency the main program executes more slow so thats why I use that frecuency... |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Mar 15, 2013 5:43 pm |
|
|
GOT it -
YES - flickering LEDS for sure -
BUT
driving a motor - or controlling a filament lamp
by using a mosfet + an L, C +catch diode DC demodulator -
would require VERY large values of L to and C to work with anything that low in frequency.
I did not understand that this is a very special purpose PWM |
|
|
MrXploder
Joined: 14 Mar 2013 Posts: 6
|
|
Posted: Fri Mar 15, 2013 6:11 pm |
|
|
this is not true.. I extensively test this code and its working just perfect.. I just post this code to help other newbies like me.. and to improve the code.. I understand that always a software pwm written in other interpreter than ASM is always inefficient.. but for leds and other stuff... it always works..
here is a video working with rgb leds made by me...
http://www.youtube.com/watch?v=0LUshw0tn6o |
|
|
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Sat Sep 19, 2015 7:55 pm |
|
|
asmboy wrote: |
what on earth is a 32 hz PWM( or less) of any use for, that eats up all the CPU capacity in the process ?? |
No offense, i see some of your great piece of code and answer, but right now i need just 1Hz pwm, with no more than 0-100 duty, to be set on each second. My controller is 18F4550 on 8MHz, i always use my all codes with interrupts functions, i like the main to remain cleared.
The I2C native & other one software, all 3 INT, other SPI software, 2 analog pins, rs232, and LCD is used in my code. Single free remain timer 2 and 3, and i try so many codes to generate pwm (1Hz), but for some reasons, the pwm pin change state randomly, some time remain high, some time low and that break my code. I try to make priority on each function, but that has more random pin state change. Someone have any idea ? Is true if i stop all interrupts and i keep just the timer for pwm code, all my codes works. |
|
|
|