| Pulse / Frequency Outputs: Muti_SPWM (Multiple Slow speed 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
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.
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.
That's all there is to it. Here's the complete example program.
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, |
|   |
| Downloads for Pulse / Frequency Outputs: Muti_SPWM (Multiple Slow speed PWM) | ||
Multi_SPWM.zip | ||
File Description:No description for file. | ||
1427 5.16 KB | Uploaded: 5/16/2004 | |
|
Article Rated: 9.33 (6 votes) Rate this Article |
| Return to Category | Return To Main Index |
| Poster | Thread |
|---|---|
| Anonymous | Posted: 2005/8/17 8:40 Updated: 2005/8/17 8:40 |
|
Very useful program!.... But often we have to produce several channels of pulsed signals with some relative delay. Is this option implemented in the program ? How could we use it?
|
|
| Darrel Taylor | Posted: 2005/8/19 18:01 Updated: 2005/8/19 18:01 |
Webmaster ![]() ![]() Joined: 2004/2/8 From: California Posts: 86 Online! |
Sorry, this program will only produce PWM with all channels having the same phase. I'm sure it can be done, but just not with this program.
|
| Anonymous | Posted: 2006/2/9 3:13 Updated: 2006/2/9 3:13 |
|
I am using Multi_SPWM on a 16F628 running at 20MHz at a PWM freq of 50Hz, and it it works perfectly as expected - great!. But I also need the PIC to process some serial data at 115200bps (eventually I intend have the processor set 8 channels of PWM output based on serial data sent to the device), so I am playing around with the following code segment, to teach myself how to use the USART and have the code respond to recieved serial data:
------------------------------------------------ ' Simple program to handle USART interrupt using PIC16F628A @20MHZ ' =============================================================== ' ' This program allows the user to activate or deactivate ' a LED connected on PORTB.1 pin by sending command from a PC ' terminal software using 9600,n,8,1 setting ' ' User command: ' ============= ' 1. If character "1" is received => enable the LED ' 2. if character "2" is received => disable the LED ' @ DEVICE PIC16F628a, HS_OSC ' System Clock Options @ DEVICE pic16F628a, WDT_ON ' Watchdog Timer @ DEVICE pic16F628a, PWRT_ON ' Power-On Timer @ DEVICE pic16F628a, MCLR_ON ' Master Clear Options @ DEVICE pic16F628a, BOD_ON ' Brown-Out Detect @ DEVICE pic16F628a, LVP_OFF ' Low-Voltage Programming @ DEVICE pic16F628a, CPD_OFF ' Data Memory Code Protect ' Set to CPD_OFF for Development Copy ' Set to CPD_ON for Release Copy @ DEVICE pic16F628a, PROTECT_OFF ' Program Code Protection ' Set to PROTECT_OFF for Development Copy ' Set to PROTECT_ON for Release Copy DEFINE OSC 20 ' running at 20 MHZ CMCON=7 TRISB=%00000010 ' PortB.1 => USART RX pin set to input ' all other pin set to output ' USART setting ' ============= ' Since we will not use HSERIN/HSEROUT, we must ' write directly to internal PIC register TXSTA=$24 ' enable transmit and SPBRGH=1 RCSTA=$90 ' Enable USART and continuous receive SPBRG=10 ' BAUD RATE = 115200 BAUD ' Interrupt definition ' ==================== PIE1.5 =1 ' enable USART receive interrupt INTCON.6 =1 ' enable peripheral interrupt ' Alias definition ' ================ RCIF var PIR1.5 ' receiver interrupt UserLED var PORTB.4 ' the LED that user want to control ' Variable definition ' =================== DataIn var byte ' use to store RCREG content Discard var byte ' use to erase RCREG register ' Hardware/software initialisation ' ================================ PORTB=0 ' clear PORTB on interrupt goto USARTInterrupt Start: 'main program loop goto start disable interrupt USARTInterrupt: ' Here's the interrupt routine to control the status of the user LED ' RCSTA=0 ' Disable serial port AND ' clear possible error (FERR,OERR) datain=RCREG ' Get data while RCif ' wait untill the RCREG is empty discard=RCREG ' by reading it and store result in a wend ' don't care variable select case datain ' What to do with that data??? case "1" ' User selection = 1 userled=1 ' => Enable the LED case "2" ' User selection =2 userled=0 ' => disable the LED end select RCSTA=$90 ' Re-enable the serial PORT AND resume ' get out of here enable interrupt ------------------------------------------------ Now, this code also behaves perfectly - the led responds whenever the correct serial data is recevied. My problem is that I cannot seem to combine this code with Multi_SPWM. I assume this is to be because of some sort of interrupt conflict between the two code segments. Can anyone please help of point me in the right direction? Kind regards, Ralph Parkhurst, Melbourne,Australia. radio_ralph@norwood.org.au |
|
| Darrel Taylor | Posted: 2006/2/9 20:52 Updated: 2006/2/9 20:52 |
Webmaster ![]() ![]() Joined: 2004/2/8 From: California Posts: 86 Online! |
Hi Ralph,
The Multi-SPWM programs interrupts are done in Assembly Language. There's no way to combine Basic Language (A.K.A. ON INTERRUPT GOTO) type interrupts, with ASM interrupts. You could write the USART routines in ASM and be able to add them in to the INT_CODE section. But then, that assumes you are familiar Assembly Language. Sorry, I'm not much help. Darrel Taylor |
| TWISTEDT | Posted: 2008/12/29 4:48 Updated: 2008/12/29 4:48 |
Just popping in ![]() ![]() Joined: 2008/12/29 From: Posts: 1 |
Hello Darrel, this program you have wriiten works great except, I have been working with it for 2 days now and I can not figure out how to change the DutyCycle within the progam as to change the position of the servos. I wanted to do this by way of a serin command but I have had no luck in doing this. Can you help?
Thanks Twisted |
![]() |



File Description:
1427
5.16 KB 



