
Originally Posted by
Joe S.
I'm : having : a : stack : overflow :

Me too :::::::::::::::::::
)))))))))))))))))))))
At any rate, just to prove I'm not an _ _ _ (insert word here)...here's some cut down 3 channel code I use on a 16F628A running at 20Mhz.
Interrupt driven 8 bit, 76Hz software PWM for RGB.
You got a timer (Timer 0) running as fast as it can, interrupting at 19,531.25 Hz. That increments a byte counter, pwmcount.
You got 3 duty cycle registers (reddcr, greendcr, bluedcr). If the individual duty cycle register is less than the pwmcounter, the LED stays on, if not the LED goes out.
Change the DCRs in the mainloop and it should work.
Like I said, this is cut down code. The full code works just fine for me, but I took out all of the serial interface code, the 5 button interface code and the serial LCD code. Might work, might not. Pay attention to how the hardware hooks up (3 LEDs on PortA, that's it).
The code should fade the 3 LEDs each in turn in about one second from off to full brightness, over and over again, 3 seconds for all 3 LEDs, wash lather rinse repeat.
But if you can't make an LED blink in the first place, DO THAT BEFORE YOU TRY THIS!
Code:
'PWM loop is @ 19,531.25 hz, w/ 256 cnt res, Freq of PWM is 76.2939hz
@ DEVICE PIC16F628A , HS_OSC , WDT_OFF , PWRT_ON , MCLR_ON , BOD_ON , LVP_OFF , PROTECT_OFF 'HS 20mhz osc, watchdog off, powerup timer on, mclr external, brown out detect on, low volt program off , code protect off for now
resetplaceholder:
DEFINE OSC 20 '20mhz
DEFINE NO_CLRWDT 1 'don't clear the watchdog timer, I'm not using it anyways
DISABLE 'disable software interrupt checks
CLEAR 'clear out the ram and do a software 'reset'
redled var porta.0:greenled var porta.1:blueled var porta.2:chx var porta:reddcr var byte:greendcr var byte:bluedcr var byte:ledtemp var byte:pwmcount var byte
temp var byte : temp2 var word
startupholder: goto skipsubs 'skip over all the commonly used subroutines
ON INTERRUPT GOTO INTHANDLER
DISABLE INTERRUPT
INTHANDLER: if intcon.2 = 1 then 'if tmr0 rolled over
intcon.2 = 0 'reset timer 0 overflow flag
if pwmcount = 0 then 'if pwmcounter has rolled over
if reddcr <> 0 then ledtemp.0 = 1 'turn off red leds if dcr is 0 (dcr = duty cycle register for LED), otherwise turn it on
if greendcr <> 0 then ledtemp.1 = 1 'turn off green leds if dcr is 0
if bluedcr <> 0 then ledtemp.2 = 1 'turn off blue leds if dcr is 0
chx = ledtemp 'update port pins of led status (on or off), can do this because all the LEDs are on the same port
endif
endif
if reddcr < pwmcount then ledtemp.0 = 0 'if the channel's dcr (duty cycle register) is less than the pwmcounter, turn that channel off, otherwise, leave it on ( < rather than <=, fixes problem with pulsing at high rates)
if greendcr < pwmcount then ledtemp.1 = 0
if bluedcr < pwmcount then ledtemp.2 = 0
chx = ledtemp : pwmcount = pwmcount + 1 'update the port pins and increment the pwmcount
endif
intfinish: RESUME
'commonly used subroutines start here
alloff: reddcr = 0 : greendcr = 0 : bluedcr = 0 : return 'turn off all leds thru dcr's
allon: reddcr = 255 : greendcr = 255 : bluedcr = 255 : return 'turn on all leds
skipsubs: option_reg=8:pie1=$20:trisa=0:porta=0:trisb=$ef:portb=$10:t1con=0:t2con=0:cmcon=7:ccp1con=0:vrcon=0:pir1.5=0:ledtemp=0:redled=0:blueled=0
greenled = 0 : intcon = $e0
ENABLE INTERRUPT
mainloop:
for temp=0 to 255:reddcr=temp:for temp2=0 to 2603:pauseus 1:next temp2:next temp:for temp=0 to 255:greendcr=temp:for temp2=0 to 2603:pauseus 1:next temp2
next temp:for temp=0 to 255:bluedcr=temp:for temp2=0 to 2603:pauseus 1:next temp2:next temp:goto mainloop 'do it over again
END
And for those that don't like colons...
Code:
'PWM loop is @ 19,531.25 hz, w/ 256 cnt res, Freq of PWM is 76.2939hz
@ DEVICE PIC16F628A , HS_OSC , WDT_OFF , PWRT_ON , MCLR_ON , BOD_ON , LVP_OFF , PROTECT_OFF 'HS 20mhz osc, watchdog off, powerup timer on, mclr external, brown out detect on, low volt program off , code protect off for now
resetplaceholder:
DEFINE OSC 20 '20mhz
DEFINE NO_CLRWDT 1 'don't clear the watchdog timer, I'm not using it anyways
DISABLE 'disable software interrupt checks
CLEAR 'clear out the ram and do a software 'reset'
redled var porta.0
greenled var porta.1
blueled var porta.2
chx var porta
reddcr var byte
greendcr var byte
bluedcr var byte
ledtemp var byte
pwmcount var byte
temp var byte
temp2 var word
startupholder:
goto skipsubs 'skip over all the commonly used subroutines
ON INTERRUPT GOTO INTHANDLER
DISABLE INTERRUPT
INTHANDLER:
if intcon.2 = 1 then 'if tmr0 rolled over
intcon.2 = 0 'reset timer 0 overflow flag
if pwmcount = 0 then 'if pwmcounter has rolled over
if reddcr <> 0 then
ledtemp.0 = 1 'turn off red leds if dcr is 0 (dcr = duty cycle register for LED), otherwise turn it on
endif
if greendcr <> 0 then
ledtemp.1 = 1 'turn off green leds if dcr is 0
endif
if bluedcr <> 0 then
ledtemp.2 = 1 'turn off blue leds if dcr is 0
endif
chx = ledtemp 'update port pins of led status (on or off), can do this because all the LEDs are on the same port
endif
endif
if reddcr < pwmcount then
ledtemp.0 = 0
endif
'if the channel's dcr (duty cycle register) is less than the pwmcounter, turn that channel off, otherwise, leave it on ( < rather than <=, fixes problem with pulsing at high rates)
if greendcr < pwmcount then
ledtemp.1 = 0
endif
if bluedcr < pwmcount then
ledtemp.2 = 0
endif
chx = ledtemp
pwmcount = pwmcount + 1 'update the port pins and increment the pwmcount
endif
intfinish:
RESUME
'commonly used subroutines start here
alloff:
reddcr = 0
greendcr = 0
bluedcr = 0
return 'turn off all leds thru dcr's
allon:
reddcr = 255
greendcr = 255
bluedcr = 255
return 'turn on all leds
skipsubs:
option_reg = 8
pie1 = $20
trisa = 0
porta = 0
trisb = $ef
portb = $10
t1con = 0
t2con = 0
cmcon = 7
ccp1con = 0
vrcon = 0
pir1.5 = 0
ledtemp = 0
redled = 0
blueled = 0
greenled = 0
intcon = $e0
ENABLE INTERRUPT
mainloop:
for temp = 0 to 255
reddcr = temp
for temp2 = 0 to 2603
pauseus 1
next temp2
next temp
for temp = 0 to 255
greendcr = temp
for temp2 = 0 to 2603
pauseus 1
next temp2
next temp
for temp = 0 to 255
bluedcr = temp
for temp2 = 0 to 2603
pauseus 1
next temp2
next temp
goto mainloop 'do it all over again
END
Bookmarks