You can address individual bits with Bit Set/Bit Clear and Bit Test instructions on most MCUs (
BSF, BCF, BTFSC on PIC16), (
bis, bic, test on MSP430) and some CPUs such as the Z80 (
SET, RES, BIT) while RISC CPUs may not have that functionality at the instruction set level.
These instructions require both an address, and a bit number within that address.
But the C language doesn't allow easy means to access that functionality, and languages following in its footsteps usually don't either. So C type languages use the smallest type the language can address for their
char in pure C) which is usually a byte.
There are other languages where you can treat a byte as a register of 8 booleans, and address an individual bit within that array, for example (Ada, for the MSP430)
package MSP is
type Byte is Array(0 .. 7) of Boolean;
For Byte'Size use 8;
and some (ugly, because it's auto-generated from TI's C headers) code mapping a specific register as either an integer or an array of booleans
package MSP.port1 is
p1in : constant unsigned_8; -- Port 1 Input
Pragma Import(Ada, p1in); -- see ARM C.6 (13)
For p1in'Address use 16#20#;
p1in_bits : constant Byte; -- Port 1 Input Bits
Pragma Import(Ada, p1in_bits);
For p1in_bits'Address use 16#20#;
allowing me to test bit 7 of port P1 as
if p1in_bits(7) then
bool is typically 1 byte long because some languages don't make it easy to access individual bits.