找回密码
 立即注册
楼主: 神***

一次完整的 A/D 时间含【ADC输入通道的切换时间+采样的时间+关闭采样的时间+固定转换

[复制链接]

该用户从未签到

46

主题

2966

回帖

6685

积分

超级版主

积分
6685
发表于 2024-3-5 23:52:16 | 显示全部楼层
分辨率越高的ADC,其对输入信号阻抗就要求越小,比如一些24 bits ADC其手册中的参数是在信号源内阻为10欧姆时得到。
实际使用中,往往希望ADC输入阻抗越高越好(带缓冲输入的ADC就是,但是增加误差,特别是0点误差)。无输入缓冲的ADC则有比较高的线性和精度,但对输入阻抗有要求,越低越好。
实际使用中,有以下情况:
1、信号源有内阻,有的内阻还比较大,比如100K的NTC测温,或者检测外部电压的分压电阻比较大。
2、为了保护ADC输入口,一般要求串联一个1~10K的电阻。
所以,实际信号输入内阻就远大于内部的采样电阻700欧姆,要根据实际的内阻来计算采样时间。
ADC输入端对地接一个1~100nF的低漏电电容,两个作用:
1、抗混叠,或者说抗尖峰干扰。
2、采样时这个电容会提供瞬间的采样电流。
采样电容可以看做一个开关电容,采样频率为f,采样电容为C,则等效电阻为1/fC,当采样速率比较低时,等效电阻很大,可以忽略其影响,但是当采样频率比较高,而输入电阻又比较大时,则影响不可忽略。比如用用10KHz的速度采样,即间隔100us采样一次,其等效电阻 = 1/(10^4 * 16.5*10^-12)=6M,即等效一个对地(或对AVREF)6M的电阻,对于输入信号内阻为1K,内部0.7K,则误差 = 4096*(1+0.7)/(6000+1+0.7)=1.16 LSB,即大约出现1个字的误差。
采样电池电压会用很大的电阻来分压,比如分压后等效内阻为100K,则误差 = 4096*(100+0.7)/(6000+100+0.7)=67.6 LSB,误差很大。但是当采样速度降为100Hz,则等效内阻为600M(理论如此,但是实际IO还会有nA级别的漏电流,温度高时可能会到几十nA至几百nA),则其影响不到1LSB,这个设计就是合理的。

所以常碰到用户类似的应用,没有仔细设计好软硬件,导致ADC结果出现偏差。

我测试过各种MCU自带的ADC,STC的12位ADC的精度可以到12.5位,其余的则很难达到。测试方法是,用一个很高精度的16位DAC(价格很贵的哦)扫描每个点,就可以得到曲线。
回复 支持 反对 送花

使用道具 举报

  • TA的每日心情
    奋斗
    5 小时前
  • 签到天数: 127 天

    [LV.7]常住居民III

    12

    主题

    315

    回帖

    894

    积分

    高级会员

    积分
    894
    发表于 2024-3-22 14:35:00 | 显示全部楼层
    梁工 发表于 2024-3-5 23:52
    分辨率越高的ADC,其对输入信号阻抗就要求越小,比如一些24 bits ADC其手册中的参数是在信号源内阻为10欧姆 ...

    学习到了,能否详细讲解下:如何用16位DAC扫描得到曲线的?

    点评

    16位DAC,从0开始输出,做ADC,之后每次都加1再输出做ADC,一共扫描65535个点,绘成曲线,做数据分析。  详情 回复 发表于 2024-3-22 15:36
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    46

    主题

    2966

    回帖

    6685

    积分

    超级版主

    积分
    6685
    发表于 2024-3-22 15:36:33 | 显示全部楼层
    jwg 发表于 2024-3-22 14:35
    学习到了,能否详细讲解下:如何用16位DAC扫描得到曲线的?

    16位DAC,从0开始输出,做ADC,之后每次都加1再输出做ADC,一共扫描65535个点,绘成曲线,做数据分析。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    5 小时前
  • 签到天数: 127 天

    [LV.7]常住居民III

    12

    主题

    315

    回帖

    894

    积分

    高级会员

    积分
    894
    发表于 2024-3-22 16:39:05 | 显示全部楼层
    梁工 发表于 2024-3-22 15:36
    16位DAC,从0开始输出,做ADC,之后每次都加1再输出做ADC,一共扫描65535个点,绘成曲线,做数据分析。 ...

    谢谢!清楚了
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    14 小时前
  • 签到天数: 63 天

    [LV.6]常住居民II

    0

    主题

    186

    回帖

    386

    积分

    中级会员

    积分
    386
    发表于 2024-3-26 19:29:38 | 显示全部楼层
    不错,学习了
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 50 天

    [LV.5]常住居民I

    3

    主题

    57

    回帖

    371

    积分

    中级会员

    积分
    371
    发表于 2024-4-1 11:38:17 | 显示全部楼层

    截图202404011124092578.jpg

    人家这个电阻,是指信号源内阻,用来评估ADC对高阻信号源采样的能力,并非要自己焊个电阻上去,
    ADC采样速度受限于电路的RC时间常数,这个RC包括芯片内部的等效电阻杂散电容和取样保持电容,以及用户外接电路的信号源内阻和分布电容,
    总的时间常越小,取样保持电路建立时间越短,保证精测前提下,ADC速度才更快.
    但是,高速的采样保持时间也不见得就是好事,很可能把高频噪声也采样到.ADC外部串联电阻,可以跟分布电容形成低通滤波器,对高频噪声有一定抑制作用,
    所以串不串电阻,串多大电阻,加不加电容,加多大电容,要不要做抗混叠滤波,需要实际电路应根据实际情况来定,不能生搬硬套.



    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9345

    回帖

    1万

    积分

    管理员

    积分
    13918
     楼主| 发表于 2024-4-8 16:23:05 | 显示全部楼层
    一用户,信号是 0V ~ 40V 变化,速度要求不高,用的 90K/10K 分压
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    难过
    4 小时前
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    1

    主题

    12

    回帖

    59

    积分

    注册会员

    积分
    59
    发表于 3 小时前 | 显示全部楼层
    单片机型号,STC32G8K64,用的是3.3V供电,内部晶振选24MHz,输入串了个1K欧的电阻,尝试了官网例程DMA方式,ADC中断方式,ADC查询方式,均不成功。
    以下代码是比较接近的,但是也有问题。
    现象1:采用通道2的值会受通道3影响,P1.2脚接入3.3V,采集不到ADC值,通道2和通道3都没有变化。
    现象2:P1.3脚接入3.3V,通道3ADC能捕捉到3.3V,但是通道2的值也会跟着变化,电压值有1.8V。
    尝试,1秒采集轮巡两个通道各采集一次,均无法成功。
    尝试,单独采集通道2,通道2的值无法采集,烦请梁工看看。

    IO配置:
    P1_MODE_IN_HIZ(GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_6|GPIO_Pin_7);


    //ADC 配置
    void        ADC_config(void)
    {
            ADC_InitTypeDef                ADC_InitStructure;                //结构定义
           
            ADC_InitStructure.ADC_SMPduty   = 31;                //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
            ADC_InitStructure.ADC_CsSetup   = 0;                //ADC 通道选择时间控制 0(默认),1
            ADC_InitStructure.ADC_CsHold    = 1;                //ADC 通道选择保持时间控制 0,1(默认),2,3
            ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X1T;                //设置 ADC 工作时钟频率        ADC_SPEED_2X1T~ADC_SPEED_2X16T
            ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;        //ADC结果调整,        ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
            ADC_Inilize(&ADC_InitStructure);                //初始化
           
            ADC_PowerControl(ENABLE);                                                        //ADC电源开关, ENABLE或DISABLE
            NVIC_ADC_Init(DISABLE,Priority_3);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    }

    u16        Get_ADCResult(u8 channel)        //channel = 0~15
    {
            if(channel > ADC_CH15)        return        4096;        //错误,返回4096,调用的程序判断       
            ADC_RES = 0;
            ADC_RESL = 0;
           
            ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道
            ADC_START = 1;//启动ADC转换
            NOP(4);                        //对ADC_CONTR操作后要4T之后才能访问

            while(ADC_FLAG == 0);
            ADC_FLAG = 0;//清除ADC结束标志
      return (((u16)ADC_RES << 8) | ADC_RESL);
    }
    //采集ADC部分
    ADC_VAL = Get_ADCResult(2);
    ADCSUM1 += Get_ADCResult(2);
    ADC_VAL = Get_ADCResult(3);
    ADCSUM2 += Get_ADCResult(3);
    if(++SumCount>=10)
    {
      SumCount=0;
      //求平均值
      INVALUE1=ADCSUM1/10;
      INVALUE2=ADCSUM2/10;
      //把累加值清零
      ADCSUM1=0;
      ADCSUM2=0;
      //计算电压,这里*33而不是乘以3.3,相当于把电压值乘以10倍。
      BatV1=((INVALUE1*33)/4096);
      BatV2=((INVALUE2*33)/4096);
    }
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-8 14:21 , Processed in 0.066171 second(s), 59 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表