-- file : jpwm3.jal -- author : Toon Beerten -- date : 21-August-2005 -- purpose : PWM-Output on 3 pins of a PIC for RGB LED -- credits : based upon the one-pin PWM output library of -- Branko Karaklajic -- Copyright (C) 2005 Toon Beerten -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Library General Public License for more details. -- -- You should have received a copy of the GNU Library General Public -- License along with this library; if not, write to the -- Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA. -- defining which pins are activated for PWM var volatile bit PWM_outR1_pin is pin_b6 -- Red var volatile bit PWM_out_pinR1_direction is pin_b6_direction var volatile bit PWM_outG1_pin is pin_b5 -- Green var volatile bit PWM_out_pinG1_direction is pin_b5_direction var volatile bit PWM_outB1_pin is pin_b4 -- Blue var volatile bit PWM_out_pinB1_direction is pin_b4_direction -- end defining pins -- PWM procedure for 3 RGB pins. First three bytes must be within 1 - 255. Not 0 procedure PWM_OUT(byte in PWMR1, byte in PWMG1,byte in PWMB1,byte in TRA) is var byte LoPWM1 -- LoPWM : time color is high var byte LoPWM2 var byte LoPWM3 var byte LoPWM4 var byte HiPWM1 var byte HiPWM2 var byte HiPWM3 var bit firstR1 = low -- bits to see which colors need to be var bit firstG1 = low -- turned off first and second var bit firstB1 = low var bit secondR1 = low var bit secondG1 = low var bit secondB1 = low -- "dirty" fix if some values are equal, what whould -- cause problems in algorithm if PWMR1 == PWMG1 & PWMR1 == PWMB1 then if PWMB1 > 2 then PWMB1 = PWMB1 - 2 PWMG1 = PWMG1 - 1 elsif PWMB1 <= 2 then PWMG1 = PWMB1 + 1 PWMR1 = PWMR1 + 2 end if elsif PWMR1 == PWMG1 then if PWMR1 > 2 then PWMG1 = PWMG1 - 1 elsif PWMR1 <= 2 then PWMR1 = PWMR1 + 1 end if elsif PWMR1 == PWMB1 then if PWMR1 > 2 then PWMB1 = PWMB1 - 1 elsif PWMR1 <= 2 then PWMR1 = PWMR1 + 1 end if elsif PWMB1 == PWMG1 then if PWMB1 > 2 then PWMG1 = PWMG1 - 1 elsif PWMB1 <= 2 then PWMG1 = PWMG1 + 1 end if end if -- determine order when colors should be turned off if PWMR1 > PWMG1 then if PWMG1 > PWMB1 then LoPWM1 = PWMB1 LoPWM2 = PWMG1 LoPWM3 = PWMR1 firstB1 = high secondG1 = high elsif PWMG1 < PWMB1 & PWMR1 < PWMB1 then LoPWM1 = PWMG1 LoPWM2 = PWMR1 LoPWM3 = PWMB1 firstG1 = high secondR1 = high elsif PWMG1 < PWMB1 & PWMR1 > PWMB1 then LoPWM1 = PWMG1 LoPWM2 = PWMB1 LoPWM3 = PWMR1 firstG1 = high secondB1 = high end if elsif PWMR1 < PWMG1 then if PWMG1 < PWMB1 then LoPWM1 = PWMR1 LoPWM2 = PWMG1 LoPWM3 = PWMB1 firstR1 = high secondG1 = high elsif PWMG1 > PWMB1 & PWMR1 < PWMB1 then LoPWM1 = PWMR1 LoPWM2 = PWMB1 LoPWM3 = PWMG1 firstR1 = high secondB1 = high elsif PWMG1 > PWMB1 & PWMB1 < PWMR1 then LoPWM1 = PWMB1 LoPWM2 = PWMR1 LoPWM3 = PWMG1 firstB1 = high secondR1 = high end if end if LoPWM4 = LoPWM3 -- make wait times relative to each other LoPWM3 = LoPWM3 - LoPWM2 LoPWM2 = LoPWM2 - LoPWM1 -- PWM_out_pinR1_direction = output --use if not already in main program -- PWM_out_pinG1_direction = output -- PWM_out_pinB1_direction = output assembler local PWMa local PWMb local PWMtra local PWMend bsf status, status_rp0 movlw 0b_1000_0011 OPTION bcf status, status_rp0 movf LoPWM1,W sublw 0xFF movwf HiPWM1 movf LoPWM2,W sublw 0xFF movwf HiPWM2 movf LoPWM3,W sublw 0xFF movwf HiPWM3 PWMa: bcf INTCON, intcon_t0if movf HiPWM1, W movwf TMR0 PWMb: -- turn all colors on bsf PWM_outR1_pin bsf PWM_outG1_pin bsf PWM_outB1_pin call PWMtra -- turn first color off btfsc firstR1 -- if firstR1 = 0 skip next line bcf PWM_outR1_pin btfsc firstG1 bcf PWM_outG1_pin btfsc firstB1 bcf PWM_outB1_pin -- second wait time movf HiPWM2, W movwf TMR0 call PWMtra -- turn second color off btfsc secondR1 -- if secondR1 = 0 skip next line bcf PWM_outR1_pin btfsc secondG1 bcf PWM_outG1_pin btfsc secondB1 bcf PWM_outB1_pin -- third wait time movf HiPWM3, W movwf TMR0 call PWMtra -- turn third color off = turn all off bcf PWM_outR1_pin bcf PWM_outG1_pin bcf PWM_outB1_pin -- fourth wait time when all colors are 0 movf LoPWM4, W movwf TMR0 call PWMtra -- repeat all until TRA 0 is decfsz TRA,f goto PWMa goto PWMend PWMtra: btfss INTCON, intcon_t0if -- wait until overflow happens goto PWMtra bcf INTCON, intcon_t0if -- set overflow bit back to 0 return PWMend: end assembler -- PWM_out_pinR1_direction = input --use if not already in main program -- PWM_out_pinG1_direction = input -- PWM_out_pinB1_direction = input end procedure