
Muti_SPWM (Multiple Slow speed PWM)
Multiple Slow speed Software PWM
Multiple Slow speed Software PWM
(for PicBasic Pro)
OK, I finally got it working, Yahoo.
After writing the SSPWM
program. The first thing that everyone said was... "How can I use
more than one SSPWM on the same chip?" Of course the answer was..
"You can't". SSPWM was written as a minimum impact Background
process. This means that it uses Timer1 to determine when the output needs
to change states, and uses very little processing time to accomplish it.
That way the main program can continue on without much disruption.
Therefore, to have more than 1 SSPWM output on the same chip would require 2
16-bit timers, one for each output. Since there aren't any 16F chips with
2 16-bit timers, this became a problem for everyone. So, back to the
proto-board I went
The result, is now called Multi_SPWM.pbp
and has the following features
- up to 8 Slow Speed PWM outputs simultaneously on 1 chip
- Works on just about any chip. 12F, 16F, 18F
- Each SPWM output can be assigned to ANY General I/O pin on any Port
- PWM is 8-bit (0-255) 0=Always Low, 255=Always High
- Can be compiled with either MPASM or PM
- It's an Include file, for easy implementation in your program.
- Error checking is built in, and supplies Messages detailing the problems.
The downside to this version is that it uses a lot of processor time.
This leaves very little for the rest of the program. Depending on how it
is configured, it may use 75% or more of the available processing time.
The reason it uses so much is due to the large number of interrupts
required. Instead of only 2 interrupts per cycle like SSPWM, Multi_SPWM
needs 256 interrupts per cycle to be able to handle multiple outputs at various
DutyCycles. So if the PWM frequency is say 100Hz, it takes 25,600 interrupts per
second. With each output using around 20 instructions per interrupt, it
adds up to about 512,000 instructions per second, per output. Yowsa.
Needless to say, you probably won't want to run this on a 4Mhz processor.
Here's what it takes to use the program.
define SPWMFREQ 100 ' PWM frequency in Hz
|
|
|
- For each output that you will be using, create a BYTE sized variable to hold
the Dutycycle value. They can be named anything you wish, but for the
example I'll just stick with the obvious.
DutyCycle1 VAR byte ' 0-255 0=Idle Low 255=Idle High
DutyCycle2 VAR byte
DutyCycle3 VAR byte
|
|
|
- Designate the Output Pin for each PWM channel, and tell Multi_SPWM what
veriable holds the Dutycycle for that channel by using a define.
SPWM1PIN VAR PORTB.0 ' SPWM channel 1
define SPWM1VAR _DutyCycle1
SPWM2PIN VAR PORTB.1 ' SPWM channel 2
define SPWM2VAR _DutyCycle2
SPWM3PIN VAR PORTB.2 ' SPWM channel 3
define SPWM3VAR _DutyCycle3
|
|
|
- And finally, include the Multi_SPWM.PBP file
Congratulations, you now have 3 PWM channels running at 100hz, ready and
waiting for you to set the dutycycle. All PWM channels automatically
configure the pin as an output, and set the output to the LOW state. It
will IDLE there until the Dutycycle is changed.
- The Dutycycle can be changed at any time by simply changing the
variable. The PWM output will be automatically updated (if nescessary)
on the next interrupt. There are no subroutines to call. It all
"Just Happens".
DutyCycle1 = 0
DutyCycle2 = 50
DutyCycle3 = 255
|
|
|
That's all there is to it.
Here's the complete example program.
define OSC 20
define SPWMFREQ 100 ' PWM frequency in Hz
DutyCycle1 VAR byte ' 0-255 0=Idle Low 255=Idle High
DutyCycle2 VAR byte
DutyCycle3 VAR byte
SPWM1PIN VAR PORTB.0 ' SPWM channel 1
define SPWM1VAR _DutyCycle1
SPWM2PIN VAR PORTB.1 ' SPWM channel 2
define SPWM2VAR _DutyCycle2
SPWM3PIN VAR PORTB.2 ' SPWM channel 3
define SPWM3VAR _DutyCycle3
Include "Multi_SPWM.pbp"
DutyCycle1 = 0
DutyCycle2 = 127
DutyCycle3 = 255
Loop:
Pause 100
Goto Loop
|
|
|
This is a new program as of 5/16/2004 so I wouldn't be surprised if there's a
problem somewhere. So, if you have any problem, please let me know, as it
will help everyone involved. Please feel free to post a comment if you'd
like at the bottom of this page.
Best regards,
Darrel Taylor
|