microcontrollerpic24

PIC24F - Set LATx specific pins without effecting the other pins


Is there a way to set specific port pins without effecting other pins at the same port?

For example:

I used LATB[13:6] for 7-segment LCD, the rest LATB bits are used for other purposes.

Now I need to set LATB = 0x003F for display '0', if i do this the rest of the bits are changed.

Someone can help me?


Solution

  • You'll have to split the operation, since you can't address specifically bits 6 to 13 in a 16 bit register. For instance, assuming LATB is a 16 bit register on which bits 6 to 13 (a range of 8 bits) map to a 7-segment display with period (making 8 segments), and we want to set those pins in particular to 0x3f = 0b00111111, we can do:

    LATB = (LATB & ~(0xff<<6)) | (0x3f<<6);
    

    0xff is a bit mask of which bits we want to affect, representing 8 bits, which we shift into position 6-13 using <<6.

    However, this is not atomic; we are reading, masking out the bits we want to adjust, setting them to new values, and writing back the entire register including the preserved other bits. Thus we may need for instance to disable interrupts around such a line.

    For many MCUs there are particular code paths supporting modification of single bits, or dedicated logic for clear/set. Those might mean that you could perform the adjustment without risking trampling another change if you stick to plainer operations, such as:

    val = 0x3f;
    LATB |= (val<<6);  // set bits which should be set
    LATB &= (val<<6) | ~(0xff<<6);  // clear bits that should be clear
    

    In this example, we're not doing the display update in one step, but each update we are making is left in a form the compiler might be able to optimize to a single instruction (IOR and AND, respectively).

    Some processors also have instructions to access sections of a word like this, frequently named bitfield operations. I don't think PIC24 is among those. It does have single-bit access instructions, but they seem to either operate on the working file or require fixed bit positions, which means setting bit by bit would have to be unrolled.

    C also does have a concept of bit fields, which means is is possible to define a struct interpretation of the latch register that does have a name for the bits you want to affect, but it's a fairly fragile method. You're writing architecture specific code anyway when relying on the particular register names. It is likely best to inspect documentation for your compiler and platform libraries.