A microcontroller is controlled by switches. Not the plastic kind: tiny on/off cells inside the chip, grouped into numbered rows called registers. Turning on an output pin, choosing a clock speed, or reading whether a button is pressed all come down to which of those cells hold a 1 and which hold a 0. Datasheets describe them in binary and in a shorthand called hexadecimal. This section teaches both from scratch.
Bits, bytes and place value
A bit is the smallest piece of information there is: a 0 or a 1. In a chip, it is one tiny switch that is either off or on. Eight bits in a row make a byte. Four bits make a nibble, half a byte.
A row of bits can stand for a whole number. This is binary, counting in twos. Each position has a number and a weight. Start at the right. The rightmost bit is bit 0, worth 1. Bit 1 is worth 2. Bit 2 is worth 4. Each step left doubles the weight: 8, 16, 32, 64, 128. To read the number, add up the weights of the bits that are 1.
Try 1010 0101. The 1s sit at bits 7, 5, 2 and 0. Their weights are 128,
32, 4 and 1. Add them: 128 + 32 + 4 + 1 = 165. The space in the middle
is only there to make it easier to read. A number read this way can
never be negative, so tools call it unsigned: it has no minus sign.
Two handy facts come out of this. First, every extra bit doubles how many
patterns you can make. Eight bits make 256 patterns, which stand for the
numbers 0 to 255. Sixteen bits make 65 536. Second, a row with only one
bit switched on is worth exactly that bit's weight. Only bit 5 on is 32.
Datasheets use that trick to point at a single switch. In code, a binary
number starts with 0b, as in 0b10100101.
Hardware values are written in two number systems: binary, base 2, built in this part, and hexadecimal (hex), a base-16 shorthand for binary, built in the next. A bit is a single binary digit: 0 or 1. In hardware it is one on/off cell, or one wire that is either low or high. A byte is 8 bits, and a nibble is 4.
Binary writes a whole number in base 2. Bits are numbered from
bit 0 at the right; bit n has weight 2^n. The value is the sum of
the weights of the bits that are 1. For 1010 0101:
128 + 32 + 4 + 1 = 165. Bit 0 is called the least significant bit, and
the highest-numbered bit the most significant bit. A whole number read
this way, with no minus sign possible, is called unsigned.
Two counts follow. With n bits there are 2^n different patterns, so an 8-bit value has 256 patterns, read as the numbers 0 to 255. Each extra bit doubles the count: 16 bits give 65 536 patterns, 0 to 65 535. And a value with only bit n set equals 2^n: only bit 5 set is 32. That single-bit value is how datasheets and code name one bit.
Spaces between groups of four are for the reader only; 10100101 and
1010 0101 are the same number. In C++ source code a binary value is
written with a 0b prefix, 0b10100101.
Set a byte to 60
Predict first: which bits must be 1 to make 60? Use the weights 32, 16, 8 and 4 as a hint. Then click bits until the byte holds 60, and check.
Loading interactive…
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Correct answer
Also accepted:
Why
Worked example
Binary to decimal (basic)
-
1
What number is
0110 1001? -
2
Number the 1s. Reading from the right, bit 0 is 1, bit 3 is 1, bit 5 is 1, bit 6 is 1.
-
3
Add the weights. 1 + 8 + 32 + 64 = 105.
Worked example
Decimal to binary by subtracting weights (typical)
-
1
Write 200 as an 8-bit binary number.
-
2
Take the largest weight that fits. 128 fits: 200 - 128 = 72. Bit 7 is 1.
-
3
Keep going down the weights. 64 fits into 72: 72 - 64 = 8. Bit 6 is 1. 32 and 16 don't fit into 8: bits 5 and 4 are 0. 8 fits exactly: bit 3 is 1, and nothing is left, so bits 2, 1 and 0 are 0.
-
4
Write it out and check.
1100 1000. Check: 128 + 64 + 8 = 200.
Worked example
How many values fit? (special case)
-
1
A sensor reports a reading as a 10-bit number. What is the largest value it can send?
-
2
Count patterns. 2^{10} = 1024 patterns.
-
3n bits reach 2 to the n minus 1, because one pattern is spent on zero
Start from zero. The patterns are the numbers 0 to 1023, so the largest is 1023, not 1024.
n bits reach 2 to the n minus 1, because one pattern is spent on zero
Check your understanding (counts toward your progress)
What whole number is the binary value 0000 1011?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
8 + 2 + 1 = 11.
Correct answer
Also accepted:
Why
Bits 3, 1 and 0 are 1.
A register value has only bit 6 set. What is its value as a whole number?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
Bit 6 has weight 2⁶ = 64.
Correct answer
Also accepted:
Why
A value with one bit set equals that bit's weight.
Set the bits to 37.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Why
37 − 32 = 5, 5 − 4 = 1, 1 − 1 = 0. Bits 5, 2 and 0 are set: 0010 0101.
Correct answer
Also accepted:
Why
The largest weight that fits in 37 is 32.
An ADC result is a 12-bit number. What is the largest value it can report?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
2¹² = 4096 patterns, 0 to 4095. The largest is 4095.
Correct answer
Also accepted:
Why
Count the patterns first: 2 to the 12.
Practice: Counting in binary (4 problems · doesn’t affect your progress)
Only the top bit and the bottom bit of a byte are 1. What whole number does it hold?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
Bit 7 (128) and bit 0 (1): 129.
Correct answer
Also accepted:
Why
Click bits until the byte holds the decimal value 150.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Why
150 − 128 = 22, 22 − 16 = 6, 6 − 4 = 2, 2 − 2 = 0: bits 7, 4, 2 and 1.
Correct answer
Also accepted:
Why
How many different patterns can 16 bits make?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
2¹⁶ = 65 536 patterns, the numbers 0 to 65 535.
Correct answer
Also accepted:
Why
Each extra bit doubles the number of patterns. Work out 2 to the power of the bit count.
A 10-bit value has every bit set to 1. What whole number is it?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
All ten bits set is the largest 10-bit value: 2¹⁰ − 1 = 1023.
Correct answer
Also accepted:
Why
Every bit set is the largest value those bits can hold.
How many patterns can 10 bits make, and where does counting start?
Hexadecimal: four bits per digit
Long rows of 1s and 0s are hard to read and easy to copy wrong. So programmers use hexadecimal, or hex. Hex counts in sixteens. Its big trick is simple: one hex digit stands for exactly four bits, one nibble.
Counting in sixteens needs sixteen digits. Hex uses 0 to 9, then letters:
A means 10, B means 11, C means 12, D means 13, E means 14, and F means
15. A hex number starts with 0x, so you can tell it apart from an
ordinary number. 0xA5 is hex.
To turn binary into hex, chop the bits into groups of four, starting
from the right. Swap each group for its hex digit. 1010 is 8 + 2 = 10,
which is A. 0101 is 4 + 1 = 5. So 1010 0101 is 0xA5. To go back,
write each hex digit as four bits. 0x3C becomes 0011 (3) and 1100
(12, or C): 0011 1100. You never have to do sums on the whole number.
Two hex digits make one byte, so a byte runs from 0x00 to 0xFF, which
is 0 to 255. Both boards in this course have 32-bit processors. Many of
their registers hold 32 bits, which is eight hex digits, like 0x40000000.
You can still turn hex into an ordinary number. Each place is worth 16
times the place to its right. So 0xA5 is 10 sixteens plus 5, which is
165. Most of the time, though, you want the bits, not the decimal.
Long binary numbers are hard to read and easy to miscopy. Hexadecimal
(hex) is base 16, and its point is that one hex digit stands for exactly
one nibble. It needs sixteen digit symbols: 0–9, then A = 10,
B = 11, C = 12, D = 13, E = 14, F = 15. A hex value is written
with a 0x prefix, in code and in datasheets: 0xA5.
Binary to hex: split the bits into groups of four from bit 0, and
replace each group with its digit. 1010 0101 → A 5 → 0xA5.
Hex to binary: expand each digit to four bits. 0x3C → 0011 1100.
No arithmetic on the whole number is needed, which is why hex is used
for bit patterns rather than decimal.
Two hex digits are one byte, so 0x00 to 0xFF covers 0 to 255. Both
of this course's boards are built on 32-bit processors, and many of their registers
are 32 bits wide: eight hex digits, such as 0x4000_0000 (the
underscore, like the space in binary, is only for reading; C++ code
writes it 0x40000000).
To get a decimal value from hex, multiply each digit by its place value, which goes up by 16 each step left: \texttt{0xA5} = 10 \times 16 + 5 = 165. In practice, convert the bits, not the decimal, because registers are read bit by bit.
Rule
One hexadecimal digit is exactly four bits
also known as: hex-to-binary by nibbles
Recalled from Assembly and Computer Architecture · Hexadecimal as four-bit shorthand — first taught there.
Formal. Because 16 = 2^4, each base-16 digit corresponds to exactly one 4-bit group (a nibble). A binary number converts to hexadecimal by grouping its bits in fours from bit 0 and replacing each group by its hex digit, and back by expanding each hex digit to four bits.
In plain English. Hex is shorthand for binary. Split the bits into groups of four starting from the right, and write one hex digit per group; no arithmetic on the whole number is needed.
Example. 1011 0110 → B 6 → 0xB6. 0x3F → 0011 1111.
Why this rule exists. It is why debuggers, compilers and memory dumps print values in hex: two hex digits are one byte, and every bit is still visible at a glance.
Bits and hex side by side
The byte starts at 0xA5. Predict the hex value before each click: turn bit 7 off, then turn bit 3 on. Watch which hex digit changes each time, and why only one does.
Loading interactive…
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Correct answer
Also accepted:
Why
Worked example
Hex to binary (basic)
-
1
Write
0x7Ein binary. -
2
One digit at a time.
7is 4 + 2 + 1:0111.Eis 14, which is 8 + 4 + 2:1110. -
3
Join them.
0111 1110.
Worked example
Binary to hex with a short number (common trap)
-
1
Write
101101in hex. -
2
Group from the right, not the left.
10 1101. Pad the short group with zeros on the left:0010 1101. -
3
Swap each group.
0010→2,1101→D. The answer is0x2D. -
4
Check the trap. Grouping from the left gives
1011 01??, which has no clean answer. Bit 0 is always in the rightmost group.
Check your understanding (counts toward your progress)
A 32-bit register value is written in hex. How many hex digits does it need?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Four hex digits cover only 16 bits.
One hex digit covers four bits, so you need far fewer than 32.
16 hex digits would be 64 bits.
Why
32 bits ÷ 4 bits per digit = 8 hex digits, such as 0x40000000.
Divide the bits by four.
How many bits does one hex digit stand for?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
8 bits is a byte, which takes two hex digits.
16 is how many values one hex digit can stand for, not how many bits.
Two bits make only 4 patterns; a hex digit has 16.
Why
16 = 2⁴, so one hex digit is exactly four bits, one nibble.
One hex digit has 16 possible values.
Set the bits to 0xC3.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Why
0xC3 is 1100 0011: bits 7, 6, 1 and 0.
Correct answer
Also accepted:
Why
Do one nibble at a time: C is 12, which is 8 + 4.
Write 1101 0110 in hex, with the 0x prefix.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
1101 = 13 = D, 0110 = 6: 0xD6.
Correct answer
Also accepted:
Why
1101 is 8 + 4 + 1. 0110 is 4 + 2.
Practice: Bits and hex digits (5 problems · doesn’t affect your progress)
Which hex digit stands for 12?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
B is 11.
D is 13.
Each hex digit is one symbol; 12 needs the letter C.
Why
A = 10, B = 11, C = 12.
C
A datasheet table gives a field's bits as 0011 1111. What is that in hex? Include 0x.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
0011 = 3, 1111 = F: 0x3F.
Correct answer
Also accepted:
Why
Split the bits into two nibbles and turn each nibble into one hex digit.
Write 0xB4 in binary, as 8 bits.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
B → 1011, 4 → 0100.
Correct answer
Also accepted:
Why
Turn each hex digit into its own group of four bits.
Write the 6-bit value 11 1010 in hex, with the 0x prefix.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
From the right: 1010 = A, then 11 padded to 0011 = 3: 0x3A.
Correct answer
Also accepted:
Why
Group from the right and pad the short group.
What whole number is 0xFF?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
15 × 16 + 15 = 255, the largest byte.
Correct answer
Also accepted:
Why
Each F is a full nibble, 15.
The left digit counts sixteens; the right digit counts ones.
Registers: bits with jobs
A register is a tiny row of switches inside the microcontroller, usually 8, 16 or 32 bits long. Each one has an address, a number the chip uses to find it, like a house number. And every bit in it has a job written down in the datasheet.
Some registers hold data. Many are control registers. Writing a pattern of 1s and 0s into one turns a piece of hardware on, picks a mode, or sets a speed. Others are status registers. Reading one tells you what the hardware is doing, one bit per fact.
The datasheet splits each register into fields. A field is one bit,
or a few bits side by side, with a name. Look at the invented register in
the picture. Bit 7 is called ENABLE. Bits 6, 5 and 4 together are MODE.
Bits 1 and 0 are SPEED. Write 0xB2 into it, which is 1011 0010. That
one number sets ENABLE to 1, MODE to 011, and SPEED to 10, all at
once. The datasheet then tells you what each pattern means.
Some bits are marked "reserved" or unused. The chip may need them left
as they are. So good code changes only the field it wants and leaves the
rest alone. Arduino's ready-made commands, such as digitalWrite(), do
that for you behind the scenes. Chapter 13 shows you how to do it by hand.
A register is a small, fixed-width storage location inside the microcontroller, usually 8, 16 or 32 bits wide, with an address (a number that identifies it) and a documented meaning for every bit. Some registers hold data. Many are control registers: writing a pattern into one switches hardware on, picks a mode, or sets a speed. Others are status registers: reading one tells you, bit by bit, what the hardware is doing.
A datasheet describes each register as a table of fields: a single
bit, or a run of neighbouring bits, with a name. In the invented register
in the figure, ENABLE is bit 7, MODE is bits 6 to 4, and SPEED is
bits 1 and 0. Writing 0xB2 (1011 0010) sets ENABLE to 1, MODE to
011 and SPEED to 10. The datasheet then says what MODE 011 means.
Bits a datasheet marks reserved or unused may have to keep a set
value, so code changes only the field it means to change and leaves the
others alone. Arduino functions such as digitalWrite() do exactly
that on your behalf; Chapter 13 writes to the registers directly.
Fields in a register
This is the invented register from the figure, starting at 0xB2. Predict the new hex value, then change SPEED to 11 and MODE to 000, leaving ENABLE at 1. Check your prediction against the readout.
Loading interactive…
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Correct answer
Also accepted:
Why
Worked example
Reading fields out of a hex value (typical)
-
1
The invented register reads
0x51. What are ENABLE, MODE and SPEED? -
2
Expand to bits.
5→0101,1→0001:0101 0001. -
3
Cut along the fields. Bit 7 is 0, so ENABLE = 0. Bits 6 to 4 are
101, so MODE =101. Bits 1 and 0 are01, so SPEED =01.
Worked example
Building a value from fields (variation)
-
1
Set ENABLE = 1, MODE =
010and SPEED =11in the invented register, with the unused bits at 0. What hex value do you write? -
2
Place each field. Bit 7:
1. Bits 6 to 4:010. Bits 3 and 2:00. Bits 1 and 0:11. -
3
Read in nibbles.
1010 0011→A3→0xA3.
Where this goes next
Hex and bit numbers come back often. In Chapter 9, a compiled program is a list of bytes written to flash. In Chapter 11, type sizes on the two boards are counted in bytes. Chapter 13 blinks an LED by writing a control register directly. Chapter 14 sets and clears single bits. Chapter 19 reads messages between chips as hex bytes. Chapter 20 maps each register to its address in the chip's memory.
Check your understanding (counts toward your progress)
In the chapter's invented register (ENABLE = bit 7, MODE = bits 6 to 4, SPEED = bits 1 to 0), the value is 0xC1. What is MODE?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
That takes bits 7 to 5. MODE starts at bit 6.
001 is the low nibble's end. MODE sits in the top nibble.
Expand 0xC first: 1100. Bits 6, 5, 4 are 1, 0, 0.
Why
0xC1 = 1100 0001. Bit 7 is 1 (ENABLE), bits 6 to 4 are 100 (MODE), bits 1 to 0 are 01 (SPEED).
Expand to bits: C is 1100, 1 is 0001.
A datasheet marks bits 3 and 2 of a register as reserved. What should code that changes the SPEED field do with them?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
A reserved bit may need a particular value. Guessing 1 can change the hardware's behaviour.
Reserved bits belong to the chip, not to your program.
Clearing the whole register also wipes ENABLE and MODE.
Why
Good code changes only the field it means to change and leaves reserved bits alone.
Change only the field you mean to change.
In the invented register, set ENABLE = 1, MODE = 111 and SPEED = 01, with the unused bits at 0.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
What this task checks
Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.
The compiler says
A model answer
Why
ENABLE 1, MODE 111, unused 00, SPEED 01: 1111 0001, which is 0xF1.
Correct answer
Also accepted:
Why
Fill the fields from the left: ENABLE, then MODE.
Practice: Fields in a register (4 problems · doesn’t affect your progress)
What does a status register tell you?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
The program decides that; a status register reports hardware state.
Memory size is in the datasheet, not a status register.
Status registers report live hardware state.
Why
Reading a status register tells you, bit by bit, what a peripheral is doing.
What the hardware is doing, one fact per field
In the invented register, the value is 0x7F. Is ENABLE (bit 7) on?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
F covers only the low nibble. The 7 puts a 0 in bit 7.
Only bit 7 decides ENABLE.
The fields are independent.
Why
0x7F = 0111 1111. Bit 7 is 0, so ENABLE is off.
Write 0x7F as 8 bits, then look only at bit 7.
No; 0x7F is 0111 1111, so bit 7 is 0
In the invented register, set ENABLE = 0, MODE = 110 and SPEED = 01, unused bits 0. Write the value in hex with the 0x prefix.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Why
0 110 00 01 = 0110 0001 = 0x61.
Correct answer
Also accepted:
Why
Lay out the fields from bit 7 down: ENABLE, MODE, two unused bits, SPEED.
Group the 8 bits into two nibbles and convert each to hex.
The register holds 0xB2. You want SPEED = 11 and everything else unchanged. What is the new value?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
That wipes ENABLE and MODE.
That sets every bit, including MODE and the unused bits.
That clears SPEED instead of setting it.
Why
0xB2 = 1011 0010. Setting bits 1 and 0 gives 1011 0011 = 0xB3.
Write 0xB2 in binary and find the SPEED bits.
Change only those two bits, then convert back to hex.
0xB3