Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Reading and setting bits in a register

After this lesson: I can read and set bits in a register.

50 min lesson3 commandsEmbedded systems lab: registers, pins, PWM and interrupts on a simulated chip

A chip is controlled by numbers

A register is a small store of bits inside a chip, and a microcontroller is controlled by reading and writing them. Once you can read a register in binary and change one bit, you can switch one light on without touching the other seven.

A washing machine, a car key and a thermostat all work this way. There is no screen. There are only numbers that mean something.

By the end of this lesson

Note

I can read and set bits in a register.

Key words

WordWhat it meansExample
Microcontrollera tiny computer on one chip, built to control one device
Registera small numbered store inside the chip
Bitone binary digit, a 0 or a 1
Maska number that picks out the bits to change0b00000100
Hexadecimalcounting in sixteens, written with 0x in front0x0A

The cells students fill in are left blank in this preview.

This chip is a simulator

Important

The lab runs a made-up chip written in Python. It is not a real board. Real chips have other register names, more registers and many more rules. What carries over is the idea: a chip is controlled through registers.

A register is one byte of switches

In this lab every register is 8 bits wide. That is one byte, so it holds a whole number from 0 to 255.

Each bit is a switch with a number. Bit 0 is on the right. Bit 7 is on the left. The simulated chip has seven registers. For example PORT holds what the output pins are told to do, and DDR says which pins are outputs.

Worked example: PORT holds 0b00001010

Bit number76543210
Worth1286432168421
Value00001010
Adds up to82

The cells students fill in are left blank in this preview.

List the lab folder

Command
docker exec jupyter ls

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Print every register after a reset

Command
docker exec jupyter python3 steps/registers.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Add the bits that are 1

Bits 3 and 1 are on, so the number is 8 + 2 = 10. Written in hexadecimal it is 0x0A, because 10 is the digit A when you count in sixteens.

Engineers write registers in binary when the bits matter and in hexadecimal when they want something short.

A mask changes only the bits you choose

To switch on one bit you must not write a whole new number. That would switch off every other bit. Use a mask instead: a number with a 1 only in the place you care about.

Bit 3 has the mask 1 << 3, which is 0b00001000. The symbol << moves a 1 to the left, three places.

Worked example: four operations on 0b00001010

JobPythonResultWhat changed
Set bit 0value | (1 << 0)0b00001011Bit 0 became 1
Clear bit 1value & ~(1 << 1)0b00001000Bit 1 became 0
Toggle bit 3value ^ (1 << 3)0b00000010Bit 3 flipped to 0
Read bit 3(value >> 3) & 11Nothing, it only looks

The cells students fill in are left blank in this preview.

OR sets, AND with NOT clears, XOR toggles

The symbol | is OR. A bit that is 1 in either number stays 1, so OR with a mask sets the bit. The symbol & is AND. It keeps a bit only if both numbers have it, so AND with the opposite of a mask clears the bit. The symbol ^ is XOR. It flips a bit, so a second XOR undoes the first.

Watch a mask set, clear and toggle

Command
docker exec jupyter python3 steps/bits.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

What the bits script prints

It starts PORT at 0b00001010. Setting bit 0 gives 0b00001011. Clearing bit 1 gives 0b00001001. Toggling bit 3 gives 0b00000001, and toggling it again brings back 0b00001001.

Each time, only the chosen bit moved. That is the whole point of a mask.

A common mistake

Warning

Many people think that to switch on bit 0 you write the number 1 to the register. That writes 0b00000001 and switches every other bit off. Read the register first, combine it with a mask, then write the result back. Write a whole number only when you mean to change all eight bits.

Try a mask yourself

Code: python
port = 0b00101000          # a register value
port = port | (1 << 1)      # set bit 1
print(format(port, "08b"))
# Change the line above to clear bit 5, then press Run.
port = port & ~(1 << 5)
print(format(port, "08b"), (port >> 3) & 1)

About this lab and its source: Embedded systems lab: registers, pins, PWM and interrupts on a simulated chip

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.