Microcontroller Program Malfunction? 5 Common Causes and Troubleshooting Methods (with Practical Cases)

Microcontroller Program Malfunction? 5 Common Causes and Troubleshooting Methods (with Practical Cases)

Hello everyone, today we will discuss a classic problem that causes countless engineers to lose their hair—microcontroller program malfunction. Just like a novice driver suddenly losing control of a car, when a program malfunctions, the microcontroller may suddenly freeze, restart, or execute strange actions. Last week, I encountered a funny case: the customer’s production line equipment would start dancing mechanically every afternoon at three o’clock, and it turned out that a relay was interfering with the power supply (details at the end)!

unsetunset1. Stack Overflow: The Most Insidious “Memory Killer”unsetunset

1.1 Everyday Understanding

Imagine your home storage warehouse (memory), where each function call is like throwing a cardboard box (local variable) into the warehouse. When the nested calls go too deep (for example, recursion without a termination condition), and the warehouse piles up to the ceiling… “Boom!” The entire warehouse collapses, and the program crashes.

1.2 Classic Case

void recursive_demo(){
    int buffer[50]; // Each recursion consumes 200 bytes
    recursive_demo(); // Infinite recursion
}

Phenomenon: Crashes after running for 2 minutes, repeats after restartTroubleshooting Tool: IDE’s built-in stack analysis tool (Check Stack Usage in Keil’s .map file)

1.3 Practical Tips

  • Increase the stack size by 20% in the startup file (for example, change from 0x400 to 0x500)
  • Avoid declaring large arrays in interrupt service functions
  • Important: When using FreeRTOS, be sure to use<span>uxTaskGetStackHighWaterMark()</span> to check task stack
Stack Overflow Illustration

unsetunset2. Interrupt Conflicts: The Invisible “Road Rage”unsetunset

2.1 Real Crash Scene

Last year, while working on a temperature controller, the ADC sampling interrupt and PWM interrupt had the same priority. As a result, when the motor speed suddenly changed, the ADC data mixed into the PWM waveform! Later, I solved it usinginterrupt nesting:

NVIC_SetPriority(ADC_IRQn, 0); // Highest priority
NVIC_SetPriority(TIM1_IRQn, 1); // Second priority

2.2 Pitfall Guide

  • Set critical interrupts (like watchdog) to the highest priority
  • Disable global interrupts before clearing interrupt flags
  • Hard Lesson: Do not perform complex calculations in I2C communication interrupts (which once caused I2C to lock up)

unsetunset3. Power Interference: The Most Easily Overlooked Culpritunsetunset

3.1 Classic Fault Phenomena

  • Screen glitches when the motor starts
  • Microcontroller restarts when the relay engages
  • ADC sampling values show regular fluctuations

3.2 Hardware Improvement Solutions

Power Filtering Circuit

Measured Data:

Filtering Solution Ripple Peak-to-Peak Value
No Filtering 300mV
Add Capacitor 50mV
LC Filtering 10mV

3.3 On-Site Diagnostic Techniques

Use an oscilloscope probe to connect to the power pin, set the trigger to falling edge. When the device exhibits abnormal behavior, if a voltage drop is captured, immediately check:

  1. Whether the power line is too long (add a ferrite bead if over 15cm)
  2. Whether the digital ground and analog ground are connected at a single point
  3. Whether high-power devices share ground with the MCU

unsetunset4. Infinite Loops: A Pitfall for Beginnersunsetunset

4.1 Typical Error Code

while(UART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); // Waiting indefinitely for serial data

4.2 Optimization Solutions

Solution 1: Add a timeout check

uint32_t timeout = 100000;
while(timeout--){
    if(UART_GetFlagStatus(...)) break;
}
if(timeout == 0) Error_Handler();

Solution 2: Use DMA + Interrupt

HAL_UART_Receive_DMA(&amp;huart1, rx_buf, 256);

4.3 Debugging Black Technology

Use the Live Watch feature in STM32CubeIDE to monitor the loop variable values in real-time

unsetunset5. Watchdog: A Lifesaver Turned Killerunsetunset

5.1 Real Case

A fire-fighting device restarted in a fire scene due to:

void main(){
    IWDG_Init(); // Initialize watchdog
    while(1){
        do_something(); // May take 2 seconds
        // Forgot to feed the dog!
    }
}

5.2 Correct Watchdog Feeding Method

  • Feed the watchdog in the timer interrupt (with a period shorter than the watchdog timeout)
  • Segment complex tasks, feeding the watchdog at the end of each segment
  • Key: Disable the watchdog during debugging!

unsetunset6. Comprehensive Troubleshooting Flowchartunsetunset

Program Malfunction -> Check Reset Flags -> 
If it is a watchdog reset: Check watchdog feeding logic  
If it is a hard error: Connect debugger to locate crash address  
If there is no abnormal reset: Check power/clock/stack

unsetunset7. Essential Tool List for the Laboratoryunsetunset

  1. Oscilloscope (must have single-shot trigger function)
  2. Logic Analyzer (to check timing conflicts)
  3. Thermal Imaging Camera (for quickly locating short circuit hotspots)
  4. Homemade debugging tool: Use LED + resistor to create a “program heartbeat light”

unsetunsetPractical Suggestionsunsetunset

  1. Intentionally write an infinite loop program and observe the PC pointer changes with the debugger
  2. Connect a 10Ω resistor in series on the power line and measure the voltage drop with an oscilloscope
  3. Modify the stack settings in the startup file and observe changes in program stability
  4. Use GPIO toggling method to measure interrupt response time

Finally, let me share that mechanical dance case: The factory’s packaging machine would twitch every afternoon, and it was eventually found that workers were simultaneously turning on multiple high-power fans, causing a sudden drop in grid voltage. The solution was to install a voltage regulator at the 380V incoming line and add a voltage anomaly holding mechanism in the PLC program. So friends, never underestimate the impact of environmental factors on microcontrollers!

Leave a Comment