From Regulus Berdin
Given a number in bin, from 1 to 30, this code will drive that number of LED's on.
; 1-30 to 30 leds
;input: bin
;output: led1,led2,led3,led4
convert:
clrf led1
clrf led2
clrf led3
clrf led4
incf bin,f
loop:
decfsz bin,f ;do not include 0
goto $+2
return
decf bin,f
setc ;turn on led
rlf led4,f
rlf led3,f
rlf led2,f
rlf led1,f
goto loop
;--------------------
I have another solution, using the fact that 1-30 bar is equal to 2^y -
1. This routine is isochronous and faster on some values than the
above.
Here goes:
convert:
clrf a1
clrf a2
clrf a3
clrf a4
movlw a4 ;2^bin
btfsc bin,3
movlw a3
btfsc bin,4
addlw -2 ;corrected from 'movlw a1'
movwf FSR
movlw B'00000001'
btfsc bin,1
movlw B'00000100'
movwf INDF
btfsc bin,0
addwf INDF,f
btfsc bin,2
swapf INDF,f
movlw 1 ;subtract by 1
subwf a4,f
skpc
subwf a3,f
skpc
subwf a2,f
skpc
subwf a1,f
You don't need a 30bit number just because you want to drive a 30led bar :) All you need is a number from 0 to 30, which boils down to a simple division, if your representation is linear. 0->0%->no led, 65535->100%->all (30) leds. that's 30 intervals for 65535, hence each interval (corresponding to one led more) is 65535/30... you divide your load by this number, and get the number of leds to switch on.