Soft' PWM for that many outputs is difficult but you might be able to reduce 'overhead' using one of the following assembler methods;
Good luck on your project Sir. Regards, Mike
Code:
;
; 6 bit (single port), 256 step, 20 cycles (isochronous) for 16F
;
movf led+5,W ; led[5] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[5] >= dcy |B0
rlf shadow,F ; |B0
movf led+4,W ; led[4] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[4] >= dcy |B0
rlf shadow,F ; |B0
movf led+3,W ; led[3] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[3] >= dcy |B0
rlf shadow,F ; |B0
movf led+2,W ; led[2] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[2] >= dcy |B0
rrf shadow,F ; |B0
movf led+1,W ; led[1] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[1] >= dcy |B0
rlf shadow,F ; |B0
movf led+0,W ; led[0] duty cycle, 0..255 |B0
subwf dcy,W ; C = led[0] >= dcy |B0
rlf shadow,F ; |B0
xorlw 0xFF ; for active hi outputs |B0
movwf PORTB ; update LEDs |B0
;
; bump duty cycle counter
;
movlw b'00111111' ; just in case |B0
incf dcy,F ; bump duty cycle counter |B0
skpnz ; end-of-period? no, skip, else |B0
movwf shadow ; reset shadow |B0
Code:
;
; 6 bit (single port), 256 step, 15 cycles (isochronous) for 18F
;
movf dcy,W ; duty cycle counter, 0..255
cpfsgt Led+0 ; if(Led[0] >= dcy)
bcf Shadow,0 ; Shadow.0 = 0
cpfsgt Led+1 ; if(Led[1] >= dcy)
bcf Shadow,1 ; Shadow.1 = 0
cpfsgt Led+2 ;
bcf Shadow,2 ;
cpfsgt Led+3 ;
bcf Shadow,3 ;
cpfsgt Led+4 ;
bcf Shadow,4 ;
cpfsgt Led+5 ;
bcf Shadow,5 ;
movff Shadow,LATB ;
;
; bump duty cycle counter
;
movlw b'00111111' ; just in case
infsnz dcy,F ; if end-of-period
movwf Shadow ; reset shadow
Bookmarks