7A. Bitwise Register Simulator
Set, clear, toggle, and check any bit in a 32-bit register.
Hex:
Dec:
Bin:
Before:
After:
REG |= (1U << 5);
Compiled from Lectures 1, 3, 4, 7, 8, & 9. This is your mini-textbook, cheat sheet, and practice quiz rolled into one.
0 of 8 sections complete
Overall Completion
0%
Spaced repetition intervals: 1, 3, and 7 days.
Master these for the quiz.
Flash vs SRAM
what goes where & why.
Memory-mapped I/O
registers live at addresses.
Address Bus
STM32 is 32-bit = 4GB space.
Peripherals
controlled by registers (GPIO).
stdint.h
uint8_t, uint16_t, uint32_t sizes.
Pointers
store addresses, dereference to read/write.
Pointer Size
depends on machine (PC vs STM32).
const vs volatile
especially for hardware registers.
Bitwise Ops
&, |, ^, ~, <<, >> and their uses.
Masks + Shifts
extract fields from 32-bit values.
Structs
. vs -> and why padding happens.
Interrupt Flow
EXTI -> NVIC -> ISR -> HAL -> Callback.
On STM32, GPIO pins aren't magic pins — they're controlled by peripheral registers. Those registers are placed ("mapped") into the same address space as normal memory.
Your STM32 has a 32-bit address bus.
Match the register name to its purpose:
Also worth recognizing: AFRL/AFRH, LCKR, and related GPIO control registers.
A plain int can be 2 bytes on one system and 4 bytes on another. stdint.h eliminates ambiguity and prevents hidden portability bugs.
A pointer stores an address, not a value.
Pointer size depends on the architecture's bus width.
On 64-bit systems, pointers are usually 8 bytes regardless of pointee type. They must be wide enough to hold any valid address.
Quiz trick: "Pointer size depends on architecture."
To treat a raw number as an address, typecast it.
// address of some register
uint32_t *reg = (uint32_t*) 0x40020000;
// write to that register
*reg = 0x1;
"Set/clear/check bits inside registers."
& AND - masking/checking| OR - setting bits^ XOR - toggling bits~ NOT - inverting bits<< >> Shifts - moving bitsMoves the target field to bit 0, then mask isolates it.
Example: Extract Packet field [12:9] (4 bits)
field = (packet >> 9) & 0xF;
This shift-then-mask pattern is reused constantly when decoding packed 32-bit data fields.
Controlling an LED (like PA5) requires writing peripheral registers.
Enable Peripheral Clock: Without it, the peripheral won't accept configurations.
Set Pin Mode: Use the MODER register to set to output.
Write HIGH/LOW: By writing to ODR or BSRR.
In STM32 GPIO, each pin uses two bits in MODER to select its mode (input, output, alternate, analog).
Example: Pin 5 uses bits [11:10]. Code often clears 2 bits then sets them.
. (Dot)
Use when you have a struct variable.
-> (Arrow)
Use when you have a pointer to a struct.
Compilers insert "padding" bytes so data aligns on natural boundaries. This wastes SRAM and creates unused gaps between members.
__attribute__((packed)) removes padding. Saves memory, but may slow down access.
Useful for decoding 32-bit packets, reducing memory usage, and grouping related bits into named fields.
HAL (Hardware Abstraction Layer) lets you write portable code using APIs rather than raw addresses or manual register bit-manipulation.
STM32 header files already define peripheral base addresses and overlay structures used by HAL and low-level code.
HAL_GPIO_Init() to configure registers.For complex peripherals (UART), HAL uses a handle to store:
An interrupt starts when EXTI detects a rising/falling edge.
The CPU then locates the ISR through the vector table and jumps to it.
Practice bit operations, packet field extraction, and interrupt flow with deterministic visuals.
Set, clear, toggle, and check any bit in a 32-bit register.
Hex:
Dec:
Bin:
Before:
After:
REG |= (1U << 5);
Shift then mask a selected bit range from a 32-bit packet.
Shift step:
Mask step:
Extracted (dec):
Extracted (hex):
Width: bits
(packet >> 9) & 0xF
Validate each stage before advancing: EXTI -> NVIC -> ISR -> HAL -> Callback.
Condensed cram sheet for formulas, register meanings, and interrupt flow.
Set bit n: REG |= (1U << n);
Clear bit n: REG &= ~(1U << n);
Toggle bit n: REG ^= (1U << n);
Check bit n: if (REG & (1U << n))
Field [h:l]: (value >> l) & ((1U << (h - l + 1)) - 1)
EXTI -> NVIC -> ISR -> HAL_GPIO_EXTI_IRQHandler -> HAL_GPIO_EXTI_Callback
Timed assessment with per-topic scoring and post-exam recommendations.
1. To prevent the compiler from optimizing out a hardware register variable, use the qualifier.
2. The STM32 address bus is [bits], so its address range is [start] to [end].
3. The register used to read an input pin is .
4. EXTI detects a [edge] or [edge] edge on a GPIO input pin.
5. Use -> when you have a to a structure.
6. Which operator is best for toggling a single bit?
7. Which operator is commonly used for masking?
8. Which register is most directly associated with setting pin mode?
9. NVIC primarily:
10. Why can a struct take more bytes than the sum of its members?
11. Set bit 5 of REG (write the one-liner).
12. Clear bit 12 of REG.
13. Extract bits [12:9] from packet.
14. If REG = 0b10110000, what is REG & 0b00010000 in binary?
If you only have one pass before the quiz: