70 likes | 211 Views
Bit-Masking Demystified. Twiddle Dem Bits!. Why?. The ports are 16-bits and most (all?) of our I/O devices use only a single bit or a subset. The LAT and PORT registers provide a method for writing or reading all bits of the port.
E N D
Bit-Masking Demystified Twiddle Dem Bits!
Why? • The ports are 16-bits and most (all?) of our I/O devices use only a single bit or a subset. • The LAT and PORT registers provide a method for writing or reading all bits of the port. • LATSET and LATCLR allow writing a 1 or 0 to a subset of the port, but notsimultaneously. • There is a PORTReadBits, but no write bits. • Thus, the PIC has no way of writing a mix of ones and zeroes to a subset of the port simultaneously.
How? (Read-Modify-Write) • Individual bits of an integer can not be treated as elements of an array (as in VHDL/Verilog!). • The C bit operators allow bit-wise manipulation of bits. • The solution is to • Read the port data into a variable • Modify selected bits of the variable • Write the variable to the port
Example #1 #define LSB_MASK 0x01 // Define mask for lsb (bit 0) [...] unsigned short tmp_var; // local 16-bit variable tmp_var|= LSB_MASK; // set lsb to 1 tmp_var&= (~LSB_MASK); // set lsb to 0 tmp_var^= LSB_MASK; // toggle lsb if (tmp_var& LSB_MASK)… // test if lsb = 1 if (!(tmp_var& LSB_MASK))… // test if lsb = 0
Example #2 #define BIT_MASK (BIT_3 | BIT_6) [...] // Modifying selected port bits with new data tmp_var= PORTA; // read port data tmp_var = tmp_var & (~BIT_MASK); // clear port bits new_data = new_data & BIT_MASK; // clear other bits tmp_var = tmp_var | new_data; // combine with new LATA = tmp_var; // write all data
Shifting • The read button routine should return data that is “board-independent”. • If you return the PORTReadBits data unmodified, then the “mapping” function needs to know which bit positions “might” be a one, i.e., (0, 64, 128, 192) • Better to shift data and return (0, 1, 2, 3) return (button_data >> 6);