Send a link to your students to track their progress
74 Terms
1
New cards
Pull-down resistor
Holds an input at logic 0 when nothing else drives it
2
New cards
Why does the User Button have a pull-down resistor?
So the signal doesn't float; it reads 0 when not pressed and goes high when the button is pressed
3
New cards
MODER value that makes all 16 pins of a port general-purpose outputs
0x55555555 (01 repeated for every pin)
4
New cards
GPIOB->MODER |= 0x____ sets PB0 and PB7 to output
0x00004001 (PB0: 01 in bits 1:0 = 0x1; PB7: 01 in bits 15:14 = 0x4000)
5
New cards
Set all of port C to analog: GPIOC->MODER = 0x____
0xFFFFFFFF (11 for every pin)
6
New cards
Clear the mode bits for PB14: GPIOB->MODER &= ~(0x____)
0x30000000 (PB14 uses bits 29:28, so 11 << 28)
7
New cards
Set PC6 to alternate function: GPIOC->MODER |= 0x____
0x00002000 (PC6 uses bits 13:12; 10 << 12)
8
New cards
Code: RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
Turns on the clock for GPIO port B so its registers can be used
9
New cards
Code: GPIOB->BSRR = (1 << 7);
Atomically sets PB7 high (turns on the blue LED LD2)
10
New cards
Code: TIM2->CR1 |= TIM_CR1_CEN;
Enables (starts) the TIM2 counter
11
New cards
Code: GPIOB->ODR ^= (1 << 0);
Toggles PB0 (flips its output from high to low or low to high)
12
New cards
Code: if (GPIOC->IDR & (1 << 13)) { ... }
Polls the user button: checks if PC13 reads high (button pressed) and runs the block if so
13
New cards
Timer: 16 MHz clock, TIM4 (16-bit), 2 ms update. PSC for 1 us ticks?
PSC = 15 (16 MHz / (15+1) = 1 MHz = 1 us per tick)
14
New cards
Timer: using PSC = 15, ARR for a 2 ms period?
ARR = 1999 (2000 ticks of 1 us, minus 1)
15
New cards
Timer: can 32-bit TIM2 make a 500 ms update event at 16 MHz with PSC = 0? Explain.
Yes. 500 ms x 16 MHz = 8,000,000 ticks, which fits in a 32-bit counter (a 16-bit counter maxes at 65,535)
16
New cards
Timer: ARR for a 500 ms period on TIM2 with PSC = 0?
ARR = 7,999,999 (8,000,000 ticks minus 1)
17
New cards
PSC value for 1 us ticks from a 16 MHz timer clock
15
18
New cards
PSC value for 1 ms ticks from a 16 MHz timer clock
15999
19
New cards
Timer formula
Update frequency = timer clock / ((PSC + 1) x (ARR + 1))
20
New cards
SysTick->LOAD for an interrupt every 1 ms at 16 MHz?
15999 (16,000 ticks minus 1)
21
New cards
Longest interrupt period SysTick can produce from a single reload at 16 MHz?
About 1.05 s (2^24 = 16,777,216 ticks / 16 MHz = 1.048576 s)
22
New cards
Why can't SysTick toggle an LED every 2 s with one reload, and what do you do instead?
2 s exceeds the 24-bit max (about 1.05 s). Use a 1 ms SysTick interrupt and count interrupts in a volatile counter; toggle the LED when the count reaches 2000, then reset the count
23
New cards
Instead of using an interrupt, if (GPIOC->IDR & (1 << 13)) checks this
Whether the user button is pressed (polling)
24
New cards
Polling vs interrupts
Polling: the CPU repeatedly checks a pin/flag. Interrupts: hardware signals the CPU, which runs an ISR; more efficient and more responsive
25
New cards
Function that runs when an interrupt fires
ISR (Interrupt Service Routine)
26
New cards
Cortex-M controller that enables and prioritizes interrupts
NVIC (Nested Vectored Interrupt Controller)
27
New cards
Keyword that forces the compiler to re-read a variable from memory on every access
volatile
28
New cards
Why must a variable written in an ISR and read in main() be volatile?
Without volatile the compiler may cache the value in a register/optimize the read away, so main() never sees the ISR's change
29
New cards
The internal 16 MHz oscillator the F446 runs on out of reset
HSI (High-Speed Internal)
30
New cards
Maximum system clock frequency of the STM32F446
180 MHz
31
New cards
Arm core inside the STM32F446
Cortex-M4
32
New cards
Number of package pins on the MCU (Nucleo-144 F446ZE)
144
33
New cards
Final Jeopardy: Arm-defined header layer that lets you write GPIOB->MODER instead of a raw address
P1: What does RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN do and why do we need it?
Enables the clocks to GPIOB and GPIOC; clocks are off by default to save power
37
New cards
P1: What mode did you set the User Button (PC13) to?
Input
38
New cards
P1: Why not set the debounce delay very high?
If it is too long, the program could ignore legitimate subsequent button presses
39
New cards
P1: Walk through your debounce logic
Code-dependent. Brute force: blocking delay after detecting the press, then act. buttonLock: act on the first press, then ignore further presses for a set time
40
New cards
P1: How does your code track which LED is on next?
An LED state variable that is incremented every button press
41
New cards
P1: What does %3 do in the LED state code?
Wraps the state back to 0 after it reaches 3 so it cycles 0, 1, 2, 0, 1, 2...
42
New cards
P1: Why shift by *2 when setting LED pins in MODER?
MODER needs 2 bits per pin, so each pin's shift jumps 2 places (pin*2)
43
New cards
P1: BSRR - why shift by pin number sometimes and pin+16 other times?
Lower 16 bits SET the pin (turn on), upper 16 bits RESET the pin (turn off)
44
New cards
P1: Advantage of BSRR over ODR?
It is atomic: happens in one write/clock cycle, so nothing can interrupt between read-modify-write steps like with ODR
45
New cards
P1: What if we added a 4th LED?
Change %3 to %4 and add an else if (led_state == 3) case
46
New cards
P2: Why enable the GPIOA/B/C clock before using switches, buttons, and LEDs?
Peripheral clocks are off by default to save power; the registers don't work until the clock is enabled
47
New cards
P2: What mode are the D1-D8 LED pins configured to and why?
General-purpose output, because the MCU needs to drive the LEDs high/low
48
New cards
P2: What mode are LEFT/CENTER/RIGHT pushbuttons and why EXTI?
Input mode. EXTI lets a button press trigger an interrupt instead of constantly polling
49
New cards
P2: Why does reading V_POT need the ADC?
The potentiometer outputs an analog voltage (continuous), not a digital 0/1; the ADC converts it to a number
50
New cards
P2: How does the program decide between the 3 states (shift left, pause, shift right)?
A state variable (set in the button ISRs) is checked in main; a button press changes the variable and so the behavior
51
New cards
P2: How is wraparound implemented when shifting?
When the pattern shifts past D8 (or D1) it is set back to D1 (or D8), e.g. with a check or rotate (code-dependent)
52
New cards
P2: How do you convert the 12-bit ADC reading into a ms delay?
ADC range is 0-4095; scale it (e.g. map 0-4095 to the delay range such as 0-4000 ms)
53
New cards
P2: ODR or BSRR to shift the LED pattern, and why?
BSRR: atomic, changes only the targeted pins in one write without read-modify-write
54
New cards
P2: How can a blocking software delay hurt responsiveness?
The CPU is stuck in the loop and can't do anything else (read the ADC, check buttons) until the delay ends
55
New cards
P2: Why is a 4 s SysTick delay awkward with a single interrupt?
SysTick is 24-bit and maxes out around 1.05 s at 16 MHz. Use a 1 ms tick and count interrupts until the target is reached
56
New cards
P2: Why must state/led_state be volatile?
It is changed in an ISR and read in main(); without volatile the compiler may cache it, so main() would never see the change and the program could ignore button presses
57
New cards
P3: Why can only one digit of the 4-digit 7-segment display be on at a time?
The digits share the same segment lines, so only one digit is enabled at a time; we cycle through them quickly (multiplexing) and persistence of vision makes them all look on
58
New cards
P3: Why clear the update flag (UIF) in the TIM5 interrupt? What if you don't?
The flag stays set, so the interrupt immediately fires again and again, the CPU gets stuck in the ISR
59
New cards
P3: What is the purpose of a helper file and why use one?
Holds reusable code (e.g. display functions) separate from main: keeps main clean, organized, and reusable across projects
60
New cards
P3: What number did you give SysTick and how often does it interrupt?
Code-dependent. Formula: LOAD = (16 MHz x period) - 1, e.g. 15999 for 1 ms
61
New cards
P3: How often does TIM5 interrupt? How did you pick PSC and ARR?
Code-dependent. Update rate = 16 MHz / ((PSC+1)(ARR+1)); e.g. 2.5 ms per digit. Pick PSC for convenient tick size then ARR for the period
62
New cards
P3: Walk through your TIM5 interrupt handler. Why in that order?
Code-dependent. Typical: clear UIF, turn off the current digit, move to the next digit, output its segments, turn it on (avoids ghosting)
63
New cards
P3: All buttons share EXTI9_5_IRQHandler. How does the code know which button was pressed?
Check the EXTI pending register (EXTI->PR) bits for each line, act on the one that is set, then clear it by writing 1
64
New cards
P3: Count is changed in an interrupt and used elsewhere. Does it need to be volatile?
Yes. A variable shared between an ISR and other code must be volatile so the compiler always re-reads it from memory
65
New cards
P3: What if TIM5 interrupted every 10 ms instead of 2.5 ms?
Each digit refreshes every 40 ms (25 Hz), which is slow enough to see flicker; 2.5 ms gives a 100 Hz refresh
66
New cards
P3: How does the code split the count into 4 digits?
Using / and %: thousands = count/1000, hundreds = (count/100)%10, tens = (count/10)%10, ones = count%10
67
New cards
P4: Explain what your program does to a non-engineer (key ideas)
It plays a sound tone: a table of 100 numbers describing one sine wave cycle is fed to the DAC one at a time by a timer and DMA; the DAC turns the numbers into a voltage; a faster/slower timer changes the pitch
68
New cards
P4: Why use a lookup table (LUT) instead of computing sine every time?
Computing sine is slow and CPU-heavy; a precomputed table just needs a fast memory read, so it is quick and predictable
69
New cards
P4: What is DMA and what job is it doing here?
Direct Memory Access: hardware that moves data without the CPU. It copies each LUT value to the DAC each timer tick
70
New cards
P4: Why is the LUT centered at 2048 with no negative values, and why 1048 to 3048 instead of 0 to 4095?
The DAC can only output 0 to Vref (0-4095), no negatives, so the zero line is the midpoint 2048. 2048 +/- 1000 gives 1048 to 3048: a smaller amplitude that stays safely within range (avoids clipping/distortion) and keeps volume moderate
71
New cards
P4: With TIM6 at PSC = 0 (16 MHz), how do you compute ARR for a given frequency? Show for 440 Hz
ARR = 16,000,000 / (f x samples) - 1. For 440 Hz with 100 samples: 16,000,000 / 44,000 - 1 = about 363
72
New cards
P4: Why use DMA instead of an interrupt to send each LUT value to the DAC?
An interrupt every sample (e.g. 44,000 times/sec) would use lots of CPU time for ISR overhead; DMA does the transfer in hardware, leaving the CPU free
73
New cards
P4: How does one 100-value LUT create every frequency from 100 Hz to 2 kHz?
The table stays the same; the timer rate (ARR) changes how fast the samples are played. Faster sample rate = higher pitch
74
New cards
P4: Why is the DMA stream in circular mode? What would you hear without it?
Circular mode wraps back to the start of the table automatically so the wave repeats forever. Without it, you'd get only one cycle (a click) and then silence