c8051f350 ADC问题,多通道转换时数值差很多,单通道转换时没有问题,

2020-02-05 08:52发布

原理图

(原文件名:350.jpg)

程序
///////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// FILE NAME      : adc.c
// TARGET DEVICE  : c8051f350
// IDE VER              : KEIL C51V900
// CREATED ON     : 10-09-09
// CREATED BY     : BILLTIAN
//
//
///////////////////////////////////////////////////////////////////////////////////////////////////

#define _IN_adc_C_
///////////////////////////////////////////////////////////////////////////////////////////////////
// Includes
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "main.h"
//-----------------------------------------------------------------------------
// ADC0_Init extVREF Bipolar AIN0.1-AIN0.0
//-----------------------------------------------------------------------------
//
// This function initializes the ADC to measure across AIN0.1 and AIN0.0
// on the Target Board (Differential measurements, Bipolar codes)

void ADC0_Init (void)
{
        unsigned ADC0_decimation;
       
        REF0CN &= ~0x01;            // disable internal vref       
        //REF0CN |= 0x01;           // (enable if using internal vref)
               
        ADC0CN = 0x00;              // unipolar output codes, GAIN=1
        //ADC0CN = 0x10;                    // Bipolar output codes, GAIN=1
       
        //ADC0CF = 0x00;                        // interrupts upon SINC3 filter output and uses internal VREF       
        ADC0CF = 0x04;                                // interrupts upon SINC3 filter output and uses external VREF
       
        ADC0CLK = (SYS_CLK_FREQ/MDCLK)-1; // Ideally, MDCLK = 2.4576 MHz Generate MDCLK for modulator.
                                  
        // program decimation rate for desired OWR       
        ADC0_decimation = SYS_CLK_FREQ/OWR/(ADC0CLK+1)/128;       
        ADC0_decimation--;       
        ADC0DEC = ADC0_decimation;               
        ADC0BUF = 0x00;             // ¹Ø±ÕÊäÈ뻺³å               
                              
        ADC0MD = 0x81;                                // ÍêÈ«ÄÚ²¿Ð£×¼       
        while (!AD0CALC);                        // µÈ´ýת»»Íê³É       
        ADC0MD &= ~0x07;

//        ADC0MUX = 0x37;             // ²î·ÖÊäÈë
        ADC0MUX = 0x07;             // ²î·ÖÊäÈë                                        
        //ADC0MD |= 0x80;           // ʹÄÜ(IDLE Mode)
        ADC0MD |= 0x83;             // Æô¶¯Á¬Ðøת»»
        EIE1 |= 0x08;               // ʹÄÜ ADC0 ÖжÏ
        ucADCFlag = 0;
        ucADCStat = 0;
        uiADCResult[0] = 0;
        uiADCResult[1] = 0;
        uiADCResult[2] = 0;
        uiADCResult[3] = 0;
}
void ADC0INT(void) interrupt 10
{
        AD0INT = 0;                                        //Çå AD0 ÖжϱêÖ¾
        uiADCResult[ucADCStat] = (ADC0H<<8) + ADC0M;
        if(MAX_CH == ucADCStat)
        {
                ucADCStat = 0;
                ADC0MUX = 0x07;
                ucADCFlag = 1;                       
        }
        else
        {
                ucADCStat++;
                ADC0MUX = (ucADCStat<<4)|0x07;
        }
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Functions
///////////////////////////////////////////////////////////////////////////////////////////////////
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
billtian
1楼-- · 2020-02-05 12:49
ADC3接的REF/2,只转换这一通道时AD值为0X800x,4通道循环转换时,这通道数值只有0X6xxx
billtian
2楼-- · 2020-02-05 14:28
用ADUC845时也是类似用法,没出现问题
li0713
3楼-- · 2020-02-05 20:28
同样遇到类似问题!!稳定了是否好些呢?
johnwjl
4楼-- · 2020-02-06 00:04
 精彩回答 2  元偷偷看……
li0713
5楼-- · 2020-02-06 03:49
正在研究这个问题,个人愚见!!
测量每个通道的适合需要校准,有偏移校准和增益校准,楼主测量多通道的时候只做了第一个通道的校准,所以偏差比较大。如果做多通道的校准后,每次采集完后自己用校准值再做一次校准,效果可能就不一样了!!
gale
6楼-- · 2020-02-06 08:23
我感觉是:上一通道的残留电压,未能及时释放。我在通道切换后连续抛弃50个转换值,得到的结果就比较靠谱了。但是我觉得这样做不太对劲,恳请高人指点。

一周热门 更多>