heres a way to add PWM's to a PIC even if there is no PWM support on the chip. However note that this requires full access to the chip, running other code can hinder the PWM output, it works great if you only need PWM's with or without ADC. you can add some other code in but it will affect frequency and or the PWM slightly. Now this has been tested, and this is what I was using with the 12F675 chip, before i found out what a 12f683 chip can do. it works, its harder to set your frequency and all the PWM's use the same frequency, but it may be helpfull to someone or it might spark an idea for someone. Feel free to modify anything. what I used this circuit for was light dimmers, speed controls, and thermostats. but no other processes were running so it worked great, I did wish for better frequencys but even a 40hz is fast enough for leds to light and you wont see them blinking.
Code:
'****************************************************************
'* Name : SOFTPWM.BAS *
'* Author : XXXX*
'* Notice : Copyright (c) 2011 XXXX*
'* : All Rights Reserved *
'* Date : 10/23/2011 *
'* Version : 1.0 *
'* Notes : Software PWM for adding extra PWM's to PIC or *
'* : adding PWM's to a non PWM Chip (TEST-PIC 12F675) *
'****************************************************************
DEFINE ADC_BITS 10 ' A/D number of bits
DEFINE ADC_CLOCK 1 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us
POT1 Var Word ' A/D converter result
POT2 Var Word ' A/D converter result
POT3 Var Word ' A/D converter result
PWMR VAR WORD ' PWM Pulse Width Monitor/Counter
RESO Var byte ' POT Resolution ("256" = 256, "512" = 128, "1024" = 64)
FREQ_Set VAR byte ' OSC Frequency PAUSE limitation in "ms" or higher
' Frequency = (1/FREQ_Set)/ RESO
TRISIO = %000111 ' AN0-AN2 is input , IO3-IO5 is Output
PWMR = 0
GPIO = 0
RESO = 256 ' Default 256 POT Resolution (Must be multiple of 64)
FREQ_Set = 100 ' Default 100us = (10KHz / RESO) = Output 39Hz
' The 12F675 with 4mhz XT the Pause Limitation is 24us
' This gives a maximum Frequency of 162Hz with 256 RESO
' See PAUSEUS chart in PBP manual for ms Limitations
SAMPLEPOT:
ADCIN 0, POT1 ' Read Channel 0 data (Omit Line for 12F675)
ADCIN 1, POT2 ' Read Channel 1 data
ADCIN 2, POT3 ' Read Channel 2 data
GPIO = 0 'Resets outputs
POT1 = POT1 / RESO ' Omit Line for 12F675
POT2 = POT2 / RESO
POT3 = POT3 / RESO
if POT1 < (RESO / 50) then POT1 = 0 'Optional Cutoff @ 5% or less POT Value
if POT2 < (RESO / 50) then POT2 = 0 'Optional Cutoff @ 5% or less POT Value
if POT3 < (RESO / 50) then POT3 = 0 'Optional Cutoff @ 5% or less POT Value
RUNPWM:
if PWMR > (POT1 - 1) then GPIO.3 = 0 ' Omit Line for 12F675
if PWMR > (POT2 - 1) then GPIO.4 = 0 'these 3 lines used to be GPIO.x = 0
if PWMR > (POT3 - 1) then GPIO.5 = 0
if PWMR < POT1 then GPIO.3 = 1 ' Omit Line for 12F675
if PWMR < POT2 then GPIO.4 = 1
if PWMR < POT3 then GPIO.5 = 1
PWMR = PWMR + 1
if PWMR > (RESO - 1) then PWMR = 0
PauseUS Freq_set ' Omit Line to Run at Highest Possible Frequency
if PWMR = 0 then goto SAMPLEPOT ' Samples taken between output Hz
GOTO RUNPWM
end
the cool thing is, say your using a 18f4550, its got 35 I/O so if you used a serial in, you could possibly make 30 PWM's?
Im not sure how it will affect the frequency with the ADC read times, NOTE on PAUSEUS line, I usually omit this line so it will will run as fast as possible.
Bookmarks