You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PIC32MX795F512L ADC读取异常排查:缓冲区始终返回0

Troubleshooting ADC Returning 0 on PIC32MX795F512L

Let's break down your code and hardware setup to figure out why your ADC buffers are always returning 0. I've identified several critical issues that are almost certainly causing this problem:

1. Channel Assignment Bug in Main Loop

First, there's a straightforward variable assignment mistake that might be misleading you in the main loop:

channel0=ReadADC(0);
delay_ms(0.5);
channel0=ReadADC(1); // Overwriting channel0 with channel1's result
delay_ms(0.5);
channel0=ReadADC(2); // Overwriting channel0 with channel2's result
delay_ms(0.5);
channel0=ReadADC(3); // Overwriting channel0 with channel3's result

You're assigning all four channel results to channel0, while channel1, channel2, and channel3 never get updated. If you were debugging these unused variables, they'd show 0 (their default initialized value) even if channel0 had valid data. Fix this by assigning each result to its corresponding variable.

2. Incorrect Delay Usage

Your delay_ms function takes a WORD (unsigned integer) parameter, but you're passing 0.5. This value gets truncated to 0 by the compiler, so you're not actually adding any delay. Worse, software delays aren't needed for ADC sampling/conversion—your hardware is already configured to handle timing via SAMC and ADCS settings.

3. Flawed ADC Sampling/Conversion Flow

In your ReadADC function, you start sampling and immediately wait for the DONE bit. When using SSRC=0b111 (auto-convert mode), the hardware handles sampling timing automatically:

  • Setting SAMP=1 starts sampling
  • After SAMC TAD cycles, the hardware clears SAMP and starts conversion
  • Once conversion finishes, DONE is set

Your current code doesn't wait for the sampling phase to complete before checking for conversion finish, which can lead to incomplete sampling and invalid results. Here's the corrected flow:

int ReadADC(int ch)
{
    AD1CHSbits.CH0SA = ch; // Select the desired input channel
    AD1CON1bits.SAMP = 1;  // Start sampling
    while(AD1CON1bits.SAMP); // Wait for hardware to end sampling and start conversion
    while(!AD1CON1bits.DONE); // Wait for conversion to complete
    return ADC1BUF0; // Return the conversion result
}

4. Pin Configuration Mismatch (Likely Root Cause)

Looking at your initADC function, you've configured AD1PCFGbits.PCFG0-3 = 0 (sets AN0-AN3 to analog mode) but then set TRISB6 and TRISB7 to input. These pins don't map to AN0-AN3:

  • AN0 = RB0, AN1 = RB1, AN2 = RB2, AN3 = RB3
  • RB6 = AN8, RB7 = AN9

If your sensors are connected to RB6/RB7 (AN8/AN9), you're configuring the wrong analog pins! Adjust your AD1PCFG and TRISB settings to match your hardware wiring:

void initADC(void)
{
    // Adjust these based on your actual sensor connections
    // Example: If using AN0, AN1, AN8, AN9
    AD1PCFGbits.PCFG0 = 0; // AN0 (RB0) as analog
    AD1PCFGbits.PCFG1 = 0; // AN1 (RB1) as analog
    AD1PCFGbits.PCFG8 = 0; // AN8 (RB6) as analog
    AD1PCFGbits.PCFG9 = 0; // AN9 (RB7) as analog

    // Set corresponding pins as inputs
    TRISBbits.TRISB0 = 1;
    TRISBbits.TRISB1 = 1;
    TRISBbits.TRISB6 = 1;
    TRISBbits.TRISB7 = 1;

    // Rest of your ADC configuration (mostly correct)
    AD1CHSbits.CH0NA = 0;
    AD1CHSbits.CH0SA = 0;
    AD1CON1bits.FORM = 0;
    AD1CON1bits.SSRC = 0b111;
    AD1CSSL = 0;
    AD1CON2bits.VCFG = 0;
    AD1CON2bits.CSCNA = 0;
    AD1CON2bits.BUFM = 0;
    AD1CON2bits.ALTS = 0;
    AD1CON3bits.ADRC = 0;
    AD1CON3bits.ADCS = 0b00000011; // TAD = 4*TPB (adjust based on your PB clock)
    AD1CON3bits.SAMC = 0b00011; // 3 TAD sample time (sufficient for most sensors)
    AD1CON1bits.ON = 1;
    delay_ms(1); // Short delay to let ADC module stabilize
}

5. Additional Checks to Rule Out Hardware Issues

Even with fixed code, double-check these hardware points:

  • Ensure your sensors are outputting a voltage between 0V and VDD (the ADC's input range)
  • Verify that sensor outputs are connected to the correct AN pins on the PIC32
  • Confirm VDD is stable (the ADC uses VDD as its positive reference)

Corrected Main Loop

Here's the fixed main loop to properly capture all four channel results:

int main() {
    initADC();
    unsigned int channel0, channel1, channel2, channel3;

    while(1)
    {
        channel0 = ReadADC(0);
        channel1 = ReadADC(1);
        channel2 = ReadADC(8); // Use ReadADC(2) if connected to AN2
        channel3 = ReadADC(9); // Use ReadADC(3) if connected to AN3
        // Add code here to log/use these values (e.g., UART print)
        delay_ms(10); // Optional delay for readability in debugging
    }
}

内容的提问来源于stack exchange,提问作者faraz ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:27:52