Grayscale values are 12-bits, and you need to send 16 of those values before latching the data, for a total of 192 bits.

The code in the attachment is sending 1,536 bits (16*12*8).
And the method you showed in post #1 would only send 128 (16*8).

And your variable sizes aren't right. fade is a BYTE array, and can't hold 12-bit values. data1 is also a BYTE array, but you're using it like a WORD variable.

I think something like this will work better ...
Code:
fade   var WORD[16]
TempW  var WORD

setGreys:
    for z = 0 to 15
        TempW = fade(z)
        shiftout ser, sclk, 1, [TempW\12]
    next z
        
    high xlat
    low xlat  
return
Then you could ...
Code:
RampCount  var WORD
ChanCount  var BYTE

RampUP:
    FOR RampCount = 0 to 4088 STEP 8
        FOR ChanCount = 0 to 15
            fade(ChanCount) = RampCount
        NEXT ChanCount
        GOSUB setGreys
        PAUSE 50
    NEXT RampCount
RETURN

RampDN:
    FOR RampCount = 4088 to 0 STEP -8
        FOR ChanCount = 0 to 15
            fade(ChanCount) = RampCount
        NEXT ChanCount
        GOSUB setGreys
        PAUSE 50
    NEXT RampCount
RETURN
Dot correction values are 6-bits. 16 of those would total 96-bits.
<br>