查看: 1280|回复: 0

【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(三):PT100温度测量改进--ADC校准

[复制链接]
  • TA的每日心情
    无聊
    2016-10-8 20:34
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2016-9-19 08:44:41 | 显示全部楼层 |阅读模式
    分享到:
    接前面的帖子
    【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(一):开箱+新建工程+测试
    【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(二):ADC功能测试
    【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(三):用PT100电阻实现温度测量
    之前上一贴中已经用本评估板实现了温度测量,但是测试手指的温度竟然达到了36℃!而我竟然没有发烧!
    既然我没有发烧,那么就说明这个温度测得不准,就应该想办法让它测得更准一些;
    想到了两个办法:
    一是提高测量精度,比如将ADC的性能配置得更加优秀,让它测电压测得更准确一些;
    二是重新刻度,比如找个准确的温度计作为参考,按照目前这个板子的实测值刻度一个“准确”的值;
    现在找不到准确的温度计,那么就先把ADC好好配置一下吧,对ADC进行校准就是一条路。
    ①看文档、查资料,了解校准方法;
    ②编写ADC校准程序,并调试;
    ③分析,总结,并发帖。
    详细过程如下:
    ①看文档、查资料,了解校准方法;
    ADC的出厂值或许对这个温度测量来说,不够准确,那么就需要在使用AD转换之前校准一下;

    这款芯片的ADC主要有四种校准模式,主要分失调校准和增益校准;
    跟校准有关的寄存器如下:
    ADC的模式控制寄存器2_downto_0位

    失调校准寄存器

    增益校准寄存器

    ②编写ADC校准程序,并调试;
    直接在上一次的程序基础上增加校准配置,ADC0和ADC1都加上
    /**  * @brief  ADC0_Init  * @param  iStart:ADC状态  *        - 0 or ADCMDE_ADCMD_OFF for power down.  *        - 1 or ADCMDE_ADCMD_CONT for continuous conversion.  *        - 2 or ADCMDE_ADCMD_SINGLE for Single conversion.  *   - 3 or ADCMDE_ADCMD_IDLE for idle mode.  *        - 4 or ADCMDE_ADCMD_INTOCAL for offset calibration.  *        - 5 or ADCMDE_ADCMD_INTGCAL for gain calibration.  *        - 6 or ADCMDE_ADCMD_SYSOCAL for system offset calibration.  *        - 7 or ADCMDE_ADCMD_SYSGCAL for system gain calibration.  * @retval None  * @brief  配置ADC0参数,并使能ADC0中断  */        void ADC0_Init(int iStart){   // Masks in dividual ADC interupt flags 中断控制器   AdcMski(pADI_ADC0,ADCMSKI_RDY,1);              // Enable ADC ready interrupt source                   // Sets filter details 配置滤波器参数   AdcFlt(pADI_ADC0,124,14,FLT_NORMAL|ADCFLT_NOTCH2|ADCFLT_CHOP); // ADC filter set for 3.75Hz update rate with chop on enabled   // Sets ADC measurement range 设置ADC测量范围   // 使用内部参考电压,增益=1,有符号整型输出   AdcRng(pADI_ADC0,ADCCON_ADCREF_INTREF,ADCMDE_PGA_G1,ADCCON_ADCCODE_INT); // Internal reference selected, Gain of 4, Signed integer output   // Configures ADC buffers 配置ADC的BUFFER   // Turn off input buffers to ADC and external reference   // 关闭外部参考缓冲,打开正负缓冲电源,绕过正负缓冲旁路   AdcBuf(pADI_ADC0,ADCCFG_EXTBUF_OFF,ADCCON_BUFBYPN|ADCCON_BUFBYPP|ADCCON_BUFPOWP|ADCCON_BUFPOWN);    // 配置成测电流引脚   AdcPin(pADI_ADC0,ADCCON_ADCCN_AGND,ADCCON_ADCCP_AIN1);      // P->AIN1,N->AGND      printf ("\n\r出厂值:\n\r");   printf ("ADC0_OF:%8x    ADC0INTGN:%8x\n\r",pADI_ADC0->OF,pADI_ADC0->INTGN);   // ADC校准   AdcGo(pADI_ADC0,ADCMDE_ADCMD_IDLE);          // 先进入空闲模式   AdcGo(pADI_ADC0,ADCMDE_ADCMD_INTOCAL);       // 内部零电平校准   while((AdcSta(pADI_ADC0) & BIT5) != BIT5);   // 等待校准完成   AdcGo(pADI_ADC0,ADCMDE_ADCMD_INTGCAL);       // 内部满量程校准   while((AdcSta(pADI_ADC0) & BIT5) != BIT5);   // 等待校准完成    AdcGo(pADI_ADC0,ADCMDE_ADCMD_SYSOCAL);       // 系统零电平校准   while((AdcSta(pADI_ADC0) & BIT5) != BIT5);   // 等待校准完成   AdcGo(pADI_ADC0,ADCMDE_ADCMD_SYSGCAL);       // 内部满量程校准   while((AdcSta(pADI_ADC0) & BIT5) != BIT5);   // 等待校准完成   printf ("\n\r校准值:\n\r");   printf ("ADC0_OF:%8x    ADC0INTGN:%8x\n\r",pADI_ADC0->OF,pADI_ADC0->INTGN);      // ADC初始状态   AdcGo(pADI_ADC0,iStart);   // 中断使能   NVIC_EnableIRQ(ADC0_IRQn);}/**  * @brief  ADC1_Init  * @param  iStart:ADC状态  *        - 0 or ADCMDE_ADCMD_OFF for power down.  *        - 1 or ADCMDE_ADCMD_CONT for continuous conversion.  *        - 2 or ADCMDE_ADCMD_SINGLE for Single conversion.  *   - 3 or ADCMDE_ADCMD_IDLE for idle mode.  *        - 4 or ADCMDE_ADCMD_INTOCAL for offset calibration.  *        - 5 or ADCMDE_ADCMD_INTGCAL for gain calibration.  *        - 6 or ADCMDE_ADCMD_SYSOCAL for system offset calibration.  *        - 7 or ADCMDE_ADCMD_SYSGCAL for system gain calibration.  * @retval None  * @brief  配置ADC1参数,并使能ADC1中断  */        void ADC1_Init(int iStart){   // Masks in dividual ADC interupt flags 中断控制器   AdcMski(pADI_ADC1,ADCMSKI_RDY,1);              // Enable ADC ready interrupt source                   // Sets filter details 配置滤波器参数   AdcFlt(pADI_ADC1,124,14,FLT_NORMAL|ADCFLT_NOTCH2|ADCFLT_CHOP); // ADC filter set for 3.75Hz update rate with chop on enabled   // Sets ADC measurement range 设置ADC测量范围   // 使用内部参考电压,增益=1,有符号整型输出   AdcRng(pADI_ADC1,ADCCON_ADCREF_INTREF,ADCMDE_PGA_G1,ADCCON_ADCCODE_INT); // Internal reference selected, Gain of 4, Signed integer output   // Configures ADC buffers 配置ADC的BUFFER   // Turn off input buffers to ADC and external reference   // 关闭外部参考缓冲,打开正负缓冲电源,绕过正负缓冲旁路   AdcBuf(pADI_ADC1,ADCCFG_EXTBUF_OFF,ADCCON_BUFBYPN|ADCCON_BUFBYPP|ADCCON_BUFPOWP|ADCCON_BUFPOWN);    // 配置成测电流引脚   AdcPin(pADI_ADC1,ADCCON_ADCCN_AIN0,ADCCON_ADCCP_AIN1);      // P->AIN1,N->AIN0      printf ("\n\r出厂值:\n\r");   printf ("ADC1_OF:%8x    ADC1INTGN:%8x\n\r",pADI_ADC1->OF,pADI_ADC1->INTGN);   // ADC校准   AdcGo(pADI_ADC1,ADCMDE_ADCMD_IDLE);          // 先进入空闲模式   AdcGo(pADI_ADC1,ADCMDE_ADCMD_INTOCAL);       // 内部零电平校准   while((AdcSta(pADI_ADC1) & BIT5) != BIT5);   // 等待校准完成   AdcGo(pADI_ADC1,ADCMDE_ADCMD_INTGCAL);       // 内部满量程校准   while((AdcSta(pADI_ADC1) & BIT5) != BIT5);   // 等待校准完成    AdcGo(pADI_ADC1,ADCMDE_ADCMD_SYSOCAL);       // 系统零电平校准   while((AdcSta(pADI_ADC1) & BIT5) != BIT5);   // 等待校准完成   AdcGo(pADI_ADC1,ADCMDE_ADCMD_SYSGCAL);       // 内部满量程校准   while((AdcSta(pADI_ADC1) & BIT5) != BIT5);   // 等待校准完成   printf ("\n\r校准值:\n\r");   printf ("ADC1_OF:%8x    ADC1INTGN:%8x\n\r",pADI_ADC1->OF,pADI_ADC1->INTGN);      // ADC初始状态   AdcGo(pADI_ADC1,iStart);   // 中断使能   NVIC_EnableIRQ(ADC1_IRQn);}先编译再跑一下,校准成功了,相关寄存器的值相比出厂值稍微有些变化:

    用校准后的ADC测电压来计算温度,运行了一段时间之后:

    手放上去一段时间之后:

    温度比没校准的时候让人愿意接受一些了。
    ③分析,总结,并发帖;
    把ADC校准了一下,温度测量的值比没校准要好一些,如果能找个已经校准好的温度计来对比一下就更好了。
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 04:49 , Processed in 0.120408 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.