Gains:
- Ability to define register, interrupt and timing requirements for the microcontroller with a clear prompt
- Ability to check the C/Arduino code produced by AI in terms of register settings, buffer overflow and real time constraints
- Ability to apply the habit of verifying the generated code by measuring it on hardware (oscilloscope, serial port)
Embedded system development is where software and hardware intersect: setting a register bit incorrectly, holding an interrupt too long, or overflowing a buffer will cause strange, hard-to-reproduce failures in the field, even though the code "compiles" and runs. AI is truly an accelerator in this area; It can produce initial skeletons, hardware abstraction functions, state machines and communication routines. But AI does not see your card's datasheet, does not know your clock frequency, and does not sense your real time constraints. In this unit, we will cover how to clearly define microcontroller work to AI, how to check the generated C/Arduino code, and why you should measure everything in hardware.
Defining the Requirement Clearly: Register, Cutting, Timing
Telling AI to "light up an LED" won't work; Which card, which pin, which clock frequency, which timing? When assigning an embedded task to AI, use this framework: hardware (MCU family, clock, pin), function (what will happen), constraint (timing, power, memory), and interface (register, HAL, Arduino library).
Weak Prompt / Strong Prompt
WEAK: "Produce PWM with STM32." (Result: which timer, which frequency, which pin is unclear; general, probably wrong register named code.) STRONG: "Produce 20 kHz, 0-100% adjustable duty PWM on TIM3 CH1 (PA6) for STM32F103 (72 MHz system clock). Write at register level (not HAL). - Prescaler and ARR values for 20 kHz CALCULATE and show the calculation in the comment line. - Set the duty with a function parameter between 0-100. - Comment each register bit you use. Note that the values will change if your clock assumption is wrong."
The difference is that the powerful prompt makes the model show the calculation and reveal the clock assumption. So you can check the prescaler/ARR values independently:
For 20 kHz PWM (72 MHz clock):Timer_clock = 72 MHzIf we want prescaler = 72-1 → counter clock = 1 MHzARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Verification: 1e6 / (49+1) = 20 000 Hz ✓
Auditing AI Code: What to Look for?
Just because the generated code compiles does not mean it works correctly. Follow this checklist:
control area
What to look for
Register/bit settings
Exactly compatible with datasheet, correct bit mask
Interrupt (ISR)
Is it short? No blocker delay? Is volatile used?
buffer/array
Is there border control? Risk of overflow?
timing
With delay or timer? Are the actual time constraint met?
Type and width
8/16/32-bit overflow, signed/unsigned confusion
power/watchdog
Infinite loop feeding watchdog?
Interrupt service routines (ISR) are the most common source of errors. AI sometimes puts delay() or long loop inside the ISR. This leads to other interrupts being missed and watchdog resets. Rule: ISR should be as short as possible; The main job should be to set up a flag and move it to the main loop.
// WEAK (AI sometimes produces this): Blocker function in ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; read_sensor(); // may take a long time - BAD CASE_Delay(10); // delay in ISR - VERY BAD }}// STRONG: ISR short; job moves to main loopvolatile uint8_t tick_flag = 0; // volatile CONDITIONvoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1; //just set flag }}// in main loop:if (tick_flag) { tick_flag = 0; read_sensor(); }
Caution: Any variable shared between the interrupt and the main loop must be volatile. Otherwise, the compiler may cache the variable in the register and miss the update. AI often forgets this keyword; Look for it specifically when reading the code.
Buffer Overflow and Type Errors
AI can copy data from the serial port into a fixed-size array without bounds checking. In an embedded system, this means crushing contiguous memory and unexplained crashes. Make sure the limit is checked at each strcpy, array index and DMA buffer. Similarly, an 8-bit counter resets after 255; AI can ignore this and rely on an overflowing account.
Verification in Hardware: "Working" is Measured, Not Assumed
In an embedded system, the most reliable evidence is the meter, not the compiler. Verify the generated code in these three ways:
- Oscilloscope/logic analyzer: Measure PWM frequency, signal timing and communication waveform. If you wanted 20 kHz, see 20 kHz on the screen.
- Serial port (UART) log: Print out variable values, state transitions, and error counters and compare with expected behavior.
- Bound and stress testing: Test whether the system holds up under the highest load, fastest data and worst timing.
If the measured value does not agree with the calculation, the clock assumption, prescaler value or register setting is incorrect; chase.
Mini Case
A team of students has the AI print a distance measurement code with an HC-SR04 ultrasonic sensor. The code compiles but the distance always gives ridiculous values. When they connect it to the oscilloscope, they see that the echo leg calculates its timing in milliseconds instead of microseconds; AI used millis() instead of micros(). This one-word error confounded the entire measurement by a factor of 1000. When they print the raw echo time into the serial log and compare it with a real ruler, they find the error and fix it. Lesson: compiled code is not correct code; Measurement in hardware reveals the error immediately.
Common Mistakes
- Accepting register names and bit masks without comparing them with the datasheet.
- Allowing blocking delay or long processing within the ISR.
- Forgetting volatile on shared variables.
- Bypass buffer and array bounds checking; not seeing the overflow.
- Relying on clock frequency and timing assumptions without verifying them.
- Considering the code "working" without measuring it with an oscilloscope/serial log.
In summary
- Clearly define the embedded task in terms of hardware, function, constraints and interface.
- Have the AI calculate timing values such as prescaler/ARR and verify them independently.
- Keep ISRs short, use volatile on shared variables.
- Specifically look for register, buffer limit and type width errors.
- "It works" is proven with an oscilloscope, logic analyzer, and serial log, not with the compiler.
- If the measured value does not agree with the calculation, chase the assumptions.
Application task
With a microcontroller you have (Arduino, STM32, ESP32), ask the AI for PWM or a periodic task at a certain frequency. Before loading the code: (1) verify the frequency/timing values independently of the account in the comment line, (2) check for volatile and blocking in the ISR and shared variables. After uploading, measure the actual frequency with an oscilloscope or logic analyzer and compare it with the target. If there is a deviation, find the source and correct it, and note what was assumed wrong.