• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Tiny ASM: PWM LED brightness

Mosaic

Well-Known Member
Thread starter #21
Code:
Brightness; S'ware PWM (uses 3 GPRs) on a 3 bit (8 step)  base, LEDdrive GPR bits 0,2 are the common anodes in this case. At about a 1.37ms prg loop speed (my app. prg)  100% DC period is  11mSec or 90Hz refresh.
    incf LUXCTRL,w; 100% DC timebase. GPR register
    andlw .7; lower 3 bits
    movwf LUXCTRL; range 0-7.
    subwf LUX_setpt,w; Brightness PWM setting, GPR register. Range = 0 (12.5%) thru 7 (100%) for dimmest to brightest.
    movf LEDdrive,w; buffer GPR register for common anodes avoids Read Modify Write issues.
    iorlw b'00000101'; set B0 & B2 as hi by default
    skpc
    andlw  b'11111010'; disable active common anodes if no carry.
    movwf  LEDport; mapped to actual pic PORT, eg #define LEDport    PORTB
    return
So for the first bit of code to stand alone I am adding an instruction to preset the b0 & b2 to high by default...which drives the LED anodes.
 

NorthGuy

Well-Known Member
#22
Only the first 'slow' PWM code changes B0,B2.
It only changes the bits of the actual port, but it doesn't modify LEDdrive. Therefore, bits #0 and #2 in LEDdrive never change. The fast code copies these 2 bits from LEDdrive to LEDport every 10us.

When u say that the first bit of code sets b0,2 high, no it doesn't.
I din't say that. I said it only works if you set them to 1. I see you fixed this with the new code.

However, your new code still doesn't modify LEDdrive, but the fast code overwrites LEDport's bits with the bits from LEDdrive. So the bits set by slow code in LEDport won't stick for longer than 12us.
 

Mosaic

Well-Known Member
Thread starter #23
Yes that's true, for this code to 'stick' there needs to be a 'movwf LEDdrive' to keep the buffer updated. If that is the concern. The write to LEDdrive needs to be included otherwise it won't work with other LEDdrive updates. Like this:
Code:
Brightness; S'ware PWM (uses 3 GPRs) on a 3 bit (8 step)  base, LEDdrive GPR bits 0,2 are the common anodes in this case. At about a 1.37ms prg loop speed (my app. prg)  100% DC period is  11mSec or 90Hz refresh.
    incf LUXCTRL,w; 100% DC timebase. GPR register
    andlw .7; lower 3 bits
    movwf LUXCTRL; range 0-7.
    subwf LUX_setpt,w; Brightness PWM setting, GPR register. Range = 0 (12.5%) thru 7 (100%) for dimmest to brightest.
    movf LEDdrive,w; buffer GPR register for common anodes avoids Read Modify Write issues.
    iorlw b'00000101'; set B0 & B2 as hi by default
    skpc
    andlw  b'11111010'; disable active common anodes if no carry.
    movwf  LEDport; mapped to actual pic PORT, eg #define LEDport    PORTB
    movwf LEDdrive; keep buffer updated.
    return
That is another artifact of the LEDdrive was updated with the anode bits before entering this routine. That is moot now since the anode bits are only changed to low based on the slow PWM.

It seems I left out two instructions that made the difference. So I see the issue now. It wasn't a global issue with the buffer approach it is a local one with the code snippet? Is that right?
 
Last edited:

NorthGuy

Well-Known Member
#24
It seems I left out two instructions that made the difference. So I see the issue now. It wasn't a global issue with the buffer approach it is a local one with the code snippet? Is that right?
I think so.

It also would be nice to safeguard it against interrupts happening in the middle of the operation (somewhere around skpc instruction), but I don't think it's feasible in PIC16.
 

NorthGuy

Well-Known Member
#25
It seems I left out two instructions that made the difference. So I see the issue now. It wasn't a global issue with the buffer approach it is a local one with the code snippet? Is that right?
I think so.

It also would be nice to safeguard it against interrupts happening in the middle of the operation (somewhere around skpc instruction), but I don't think it's feasible in PIC16.
 

Latest threads

EE World Online Articles

Loading

 
Top