Bird
Raised Fist0
Embedded Cprogramming~10 mins

ADC interrupt-driven reading in Embedded C - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - ADC interrupt-driven reading
Start ADC Conversion
↓
ADC Conversion Complete?
No→Wait
Yes↓
ADC Interrupt Triggered
↓
Interrupt Service Routine (ISR)
↓
Read ADC Result
↓
Process or Store Result
↓
Restart ADC Conversion
↩Back to Start
The ADC starts conversion, waits until done, triggers an interrupt, ISR reads and processes the result, then restarts conversion.
Execution Sample
Embedded C
void ADC_ISR(void) {
  int adc_value = ADC_Read();
  process(adc_value);
  ADC_StartConversion();
}
This ISR reads the ADC value when conversion completes, processes it, and starts a new conversion.
Execution Table
StepEventADC Conversion StatusISR CalledADC Value ReadAction Taken
1ADC conversion startedIn ProgressNoN/AWaiting for conversion
2ADC conversion completeCompleteYesValue read from ADCProcess value and restart conversion
3New ADC conversion startedIn ProgressNoN/AWaiting for next conversion
4ADC conversion completeCompleteYesNew value readProcess value and restart conversion
ExitStop or power downN/ANoN/AADC conversions stopped
💡 ADC conversions stop when device powers down or ADC is disabled
Variable Tracker
VariableStartAfter Step 2After Step 4Final
adc_valueundefinedValue from first conversionValue from second conversionLast read value
ADC Conversion StatusIdleCompleteCompleteStopped or Idle
Key Moments - 3 Insights
Why does the ADC conversion start again inside the ISR?
Because after reading the ADC value in the ISR (see Step 2 in execution_table), we need to start a new conversion to keep reading fresh data continuously.
What triggers the ADC ISR to run?
The ADC hardware triggers the ISR automatically when the conversion completes (Step 2 and 4 in execution_table), so the CPU can read the result immediately.
Why don't we read the ADC value outside the ISR?
Reading inside the ISR ensures we get the value right after conversion finishes, avoiding delays or missed data, as shown in the execution_table steps.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the ADC Conversion Status at Step 1?
AComplete
BIdle
CIn Progress
DStopped
💡 Hint
Check the 'ADC Conversion Status' column at Step 1 in the execution_table.
At which step does the ISR read the ADC value?
AStep 2
BStep 1
CStep 3
DStep 4
💡 Hint
Look for 'ISR Called' and 'ADC Value Read' columns in execution_table.
If the ADC conversion never completes, what happens to the ISR calls?
AISR is called repeatedly
BISR is never called
CISR is called once
DISR calls happen randomly
💡 Hint
Refer to the 'ADC Conversion Complete?' decision in concept_flow and ISR trigger in execution_table.
Concept Snapshot
ADC interrupt-driven reading:
- Start ADC conversion
- Wait for conversion complete interrupt
- ISR reads ADC value
- Process value inside ISR
- Restart conversion for continuous reading
Full Transcript
This visual execution trace shows how ADC interrupt-driven reading works. The ADC starts conversion and waits until it finishes. When done, it triggers an interrupt. The interrupt service routine (ISR) runs, reads the ADC value, processes it, and starts a new conversion. Variables like adc_value update after each ISR call. This cycle repeats until ADC is stopped or powered down. Key points include starting conversion inside ISR and ISR triggering only after conversion completes.

Practice

(1/5)
1. What is the main advantage of using ADC interrupt-driven reading in embedded C?
easy
A. The CPU can perform other tasks while ADC conversion happens
B. It makes the ADC conversion faster
C. It disables other interrupts during ADC conversion
D. It reduces the ADC resolution automatically

Solution

  1. Step 1: Understand ADC interrupt-driven reading

    ADC interrupt-driven reading allows the CPU to continue other work while waiting for ADC conversion to complete.
  2. Step 2: Identify the main benefit

    This method improves efficiency by not blocking the CPU during ADC conversion.
  3. Final Answer:

    The CPU can perform other tasks while ADC conversion happens -> Option A
  4. Quick Check:

    Interrupt-driven ADC = CPU multitasking [OK]
Hint: Interrupts let CPU work during ADC conversion [OK]
Common Mistakes:
  • Thinking ADC conversion speed increases
  • Assuming interrupts disable other interrupts
  • Believing ADC resolution changes automatically
2. Which of the following is the correct way to declare a variable shared between main code and ADC interrupt handler?
easy
A. const int adc_value;
B. int adc_value;
C. static int adc_value;
D. volatile int adc_value;

Solution

  1. Step 1: Identify variable sharing between ISR and main code

    Variables shared between interrupt handlers and main code must be declared volatile to prevent compiler optimization issues.
  2. Step 2: Choose the correct declaration

    Using 'volatile int adc_value;' ensures the variable is read fresh each time and not cached.
  3. Final Answer:

    volatile int adc_value; -> Option D
  4. Quick Check:

    Shared variable = volatile [OK]
Hint: Use volatile for variables shared with interrupts [OK]
Common Mistakes:
  • Omitting volatile causing stale reads
  • Using const which prevents modification
  • Using static which limits scope but not volatility
3. Given this ADC interrupt handler code snippet, what will be the value of adc_result after the interrupt?
volatile int adc_result = 0;
void ADC_ISR(void) {
    adc_result = ADC_Read();
    ADC_ClearInterruptFlag();
}
medium
A. The previous ADC conversion value
B. Zero, because adc_result is volatile
C. The latest ADC conversion value
D. An undefined value due to missing initialization

Solution

  1. Step 1: Analyze the interrupt handler code

    The handler reads the ADC value using ADC_Read() and stores it in adc_result, then clears the interrupt flag.
  2. Step 2: Understand the effect on adc_result

    After the interrupt, adc_result holds the latest ADC conversion value read by ADC_Read().
  3. Final Answer:

    The latest ADC conversion value -> Option C
  4. Quick Check:

    ISR updates adc_result with new ADC value [OK]
Hint: ISR updates adc_result with fresh ADC reading [OK]
Common Mistakes:
  • Confusing volatile with zero initialization
  • Assuming adc_result remains unchanged
  • Ignoring ADC_ClearInterruptFlag() role
4. Identify the error in this ADC interrupt-driven code snippet:
volatile int adc_val;
void ADC_ISR(void) {
    adc_val = ADC_Read();
    // Missing ADC_ClearInterruptFlag();
}
medium
A. adc_val should not be volatile
B. ADC_ClearInterruptFlag() is missing, causing repeated interrupts
C. ADC_Read() should not be called inside ISR
D. ISR function must return a value

Solution

  1. Step 1: Review the ISR code

    The ISR reads ADC value but does not clear the interrupt flag.
  2. Step 2: Understand interrupt flag importance

    Not clearing the interrupt flag causes the interrupt to trigger repeatedly, leading to an infinite loop of interrupts.
  3. Final Answer:

    ADC_ClearInterruptFlag() is missing, causing repeated interrupts -> Option B
  4. Quick Check:

    Clear interrupt flag to stop repeated ISR calls [OK]
Hint: Always clear interrupt flag inside ISR [OK]
Common Mistakes:
  • Forgetting to clear interrupt flag
  • Thinking volatile is incorrect here
  • Expecting ISR to return a value
5. You want to implement ADC interrupt-driven reading that updates a global variable only when the ADC value exceeds 500. Which code snippet correctly implements this logic inside the ISR?
hard
A.
void ADC_ISR(void) {
    int val = ADC_Read();
    if (val > 500) {
        adc_value = val;
    }
    ADC_ClearInterruptFlag();
}
B.
void ADC_ISR(void) {
    if (adc_value > 500) {
        adc_value = ADC_Read();
    }
    ADC_ClearInterruptFlag();
}
C.
void ADC_ISR(void) {
    adc_value = ADC_Read();
    if (adc_value > 500) {
        ADC_ClearInterruptFlag();
    }
}
D.
void ADC_ISR(void) {
    ADC_ClearInterruptFlag();
    int val = ADC_Read();
    if (val > 500) {
        adc_value = val;
    }
}

Solution

  1. Step 1: Check ADC reading and condition

    void ADC_ISR(void) {
        int val = ADC_Read();
        if (val > 500) {
            adc_value = val;
        }
        ADC_ClearInterruptFlag();
    }
    reads ADC value into a local variable, then updates global adc_value only if val > 500.
  2. Step 2: Verify interrupt flag clearing

    void ADC_ISR(void) {
        int val = ADC_Read();
        if (val > 500) {
            adc_value = val;
        }
        ADC_ClearInterruptFlag();
    }
    clears the interrupt flag after processing, which is correct to prevent repeated interrupts.
  3. Final Answer:

    Updates adc_value only if ADC reading exceeds 500 and clears interrupt flag -> Option A
  4. Quick Check:

    Read ADC, check >500, update, clear flag [OK]
Hint: Read ADC first, then check condition, clear flag last [OK]
Common Mistakes:
  • Clearing interrupt flag before reading ADC
  • Checking old adc_value instead of new ADC reading
  • Not clearing interrupt flag causing repeated interrupts
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard