如何使用PIC24读取多个ADC通道;只能得到AN0

问题描述

我使用 PIC24 使用 3 个模拟输入读取数据,但只得到 1 个以显示正确的结果。我在互联网上到处查看,但仍然无法使代码正常工作。

我正在尝试读取 3 个模拟输入信号,但只能读取 AN0。

我目前正在使用加速度计来获取数据并将其显示在 LCD 屏幕上。我能够实现 3 种不同的方式来获取数据并显示它,但只有 an0 有效,而 an1 不是正确的值。

void InitADC(int amask) {
    AD1PCFG = 0xFFF8; // select AN0,AN1,AN2 as analog inputs
    AD1CON1 = 0x00E0; // auto convert @ end of sampling,Integer Data out.
    // see Text pg. 179 & Sec. 17 on AD1CON1.
    //AD1CON2bits.CSCNA = 1;
    AD1CON3 = 0x1F01; // Tad = 2xTcy = 125ns. 31*Tad for conversion time.
    //AD1CSSL = 0xFFF7; // Scan 3 channels
    AD1CON1bits.ADON = 1; // Turn on the ADC
} // InitADC

main() {
   InitADC(0xFFF8); // initialize the ADC and analog inputs 
   char x_string [12];
   char y_string [12];
   char z_string [12];
   //TRISB = 1; // all PORTB pins as outputs
   TRISBbits.TRISB0 = 1;
   TRISBbits.TRISB1 = 1;
   TRISBbits.TRISB2 = 1;
   InitPMP(); // Initialize the Parallel Master Port
   InitLCD(); // Initialize the LCD
   float x_val;
   float y_val;
   float z_val;
   float x_axis,y_axis,z_axis;

   while (1) // main loop
   {  
    x_axis= SelectPort(0);   
    x_val= ((((x_axis * 3.3)/ 1024)-1.58)/0.380);
    
    sprintf(x_string,"X: %0.2f ",x_val);
    ms_delay(2.5);

    y_axis= SelectPort(1);  
    y_val= ((((y_axis * 3.3)/ 1024)-1.58)/0.380);
    
    sprintf(y_string,"Y: %0.2f ",y_val);
    ms_delay(2.5);

    z_axis= SelectPort(2);  
    z_val= ((((z_axis * 3.3)/ 1024)-1.58)/0.380);
    
    sprintf(z_string,"Z: %0.2f ",z_val);
    ms_delay(2.5);
}

这是读取数据的代码

int SelectPort(int ch)
{
//int *result; 
AD1CON1bits.ADON = 0; // Turn off the ADC to reconfigure
//result = &ADC1BUF0;

switch(ch) // set values based on the channel to use
{
    case 0: // select AN0 as analog input
        //AD1CHSbits.CH0SA=0;
        //result = ADC1BUF0;
        AD1PCFG = 0xFFFE;
        break;
    
    case 1:
        //AD1CHSbits.CH0SA=1;
        //result = ADC1BUF1;
        AD1PCFG = 0xFFFD; // select AN1 as analog input
        break;
    
    case 2:
        //AD1CHSbits.CH0SA=2;
        AD1PCFG = 0xFFFB; // select AN2 as analog input
        break;
    
    // there's only so many options here,so there's not really a default case
}

AD1CON1bits.ADON = 1; // Turn on the ADC

AD1CHS = ch; // 1. select analog input channel

AD1CON1bits.SAMP = 1; // 2. Start sampling.
while (!AD1CON1bits.DONE); //5. wait for conversion to complete
AD1CON1bits.DONE = 0; // 6. clear flag. We are responsible see text.
return ADC1BUF0; // 7. read the conversion results
}

我是 PIC24 的新手,需要帮助弄清楚为什么我无法获得多个 ADC 通道来读取数据。

解决方法

在更改其输入端口后,您应该始终留出一些时间让 ADC 输入电压稳定下来。另外,请确保输入信号的阻抗小于 10K。

分离 ADC 通道切换并读取其值会有所帮助,并为您提供添加延迟的机会。

我在 PIC24 数据表中找不到 AD1PCFG。 AD1PCFG 是 PIC32 寄存器... PIC24 使用 ANSx 和 TRSx 将引脚设置为模拟输入。在启动序列期间,模拟输入应设置一次。将模拟信号馈送到数字输入 CMOS 引脚会导致功耗增加,甚至可能导致硬件故障!

//  Set the pins as analog inputs once and for all in your setup code.
void InitADC() 
{
    // select RB0/AN0,RB1/AN1,RB2/AN2 as analog inputs
    TRISB   |= 0x07;
    ANSB    |= 0x07;

    // ...
}

void ADC_SelectInput(int ch)
{
    AD1CHS = ch & 0x0F
}

int ADC_Read()
{
    AD1CON1bits.SAMP = 1;
    while (!AD1CON1bits.DONE)
        ;
    AD1CON1bits.DONE = 0;
    return ADC1BUF0;
}

然后你的循环变成:

// ...


int adc_in;

while (1)
{  
    ADC_SelectInput(0);
    ms_delay(3);         // settling delay,you could also do something
                         // else in the meantime instead of waiting. 
                         // NOTE: the argument to ms_delay() is an integer
                         // so waiting at least 2.5 ms makes it 3. 

    // when computing floats,use float constants,not double.
    x_val  = (((ADC_Read() * 3.3f) / 1024) - 1.58f) / 0.380f;
    sprintf(x_string,"X: %0.2f ",x_val);

    ADC_SelectInput(1);
    ms_delay(3);
    y_val  = (((ADC_Read() * 3.3f) / 1024) - 1.58f) / 0.380f;
    sprintf(y_string,"Y: %0.2f ",y_val);

    ADC_SelectInput(2);
    ms_delay(3);
    z_val  = (((ADC_Read() * 3.3f) / 1024) - 1.58f) / 0.380f;
    sprintf(z_string,"Z: %0.2f ",z_val);
}