PIC Micro Controller C Routine Math / Functions / Conversions Function

Shifting long strings of bits

By Michael Rigby Jones

if you don't need random access when filling the array, then the following might work. You will have to reset the bitmask and byteptr before shifting in each chunk of bits. 23 words in Hitech.
unsigned char bitmask = 0x01;
unsigned char byteptr = 0x00;

void set_bit(unsigned char new_state)
{

        if(new_state)
                bitarray[byteptr] |= bitmask;
        else
                bitarray[byteptr] &= ~bitmask;

        if(bitmask && 0x80){
                bitmask = 0x01;
                byteptr++;}
        else
                bitmask << 1;
}

Peter L. Perez says:

I think that you could use a vector of shift registers (actually chars). (I assume this is a 8 bit micro). Then you would have code like:
uchar data[NUM_BYTES];

p = data - 1;
for(i=NUM_BITS;i>0;--i) {
  if( !(i%8)) // actually: (i & 0x07) == 0
    ++p;
  *p = (*p * 2) + read_bit();
}

imho for 90 bits you should unroll the outer loop unless there is a code size problem, or write it in assembly. 90 bits ~= 11 bytes of storage.

The loop above can be rewritten in assembly very efficiently (using fsr for p and rotate for *2) and can even be isochronous). Like:

  movlw         (VECTOR_BASE-1)
  movwf         FSR

  movlw         NUM_BITS
  movwf         Fi

loop: ; loop period is 8T+overhead to read input bit
  movlw         H'07'
  andwf         Fi,w
  btfsc         STATUS,Z
  incf          FSR,f

  ; input bit into STATUS.C here

  rlf           INDF,f

  decfsz        Fi,f
  goto          loop

The same method (assembly) can be used on larger processors (i386) and it works to transmit and to receive synchronous data and sound (;-)).

The bit stream must not be tranmitted off chip, it can be fed to another register as required.

To rotate the whole register use something like:

c0 = input_carry;
for(i=LENGTH;i>0;--i) {
  *p++ = ((c1 = (*p & 0x80)) << 1) + c0;
  c0 = c1;
}

Which can be turned into assembly like:

  rlf           Vector_Top,w
  rlf           Fscratch,f

  movlw         VECTOR_SIZE
  movwf         Fi

  movlw         Vector_Base
  movwf         FSR

loop:
  rrf           Fscratch,f
  rlf           INDF,f
  rlf           Fscratch,f

  incf          FSR,f

  decfsz        Fi,f
  goto          loop

Fscratch will have its lowest and highest bits changed at the end.

Michael Rigby-Jones [mrjones@NORTELNETWORKS.COM]

I tried to use Scotts code as inline asm in HiTech, but you need to do some dubious bodging to make it work due to the way to compiler passes single chars. However, this "hybrid" compiles down to 20 words including return.

void set_bit(unsigned char new_state)
{
        bitarray[byteptr] |= bitmask;
        if(new_state)
                bitarray[byteptr] ^= bitmask;

#asm
        clrc
        rlf     _bitmask,w
        rlf     _bitmask,f
        btfsc   _bitmask,0
        incf    _byteptr
#endasm

}