查看: 1473|回复: 0

【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(三):用PT100电阻实现温度测量

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

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2016-9-13 09:03:37 | 显示全部楼层 |阅读模式
    分享到:
    接前面的帖子:
    【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(一):开箱+新建工程+测试
    【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(二):ADC功能测试
    这块板是用铂电阻测温的,铂电阻的阻值会随温度变化,变化很接近线性,适用于高精度测温;
    本板子用的是PT100,这是百度上搜到的描述:“PT后的100即表示它在0℃时阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。它的工作原理:当PT100在0摄氏度的时候他的阻值为100欧姆,它的的阻值会随着温度上升它的阻值是成匀速增涨的。”
    如此看来:测温即测电阻-->测电阻可用测电压和电流再相除的到-->电流实际上也是测电压再用电阻换算而来;
    因此实际实现方法就是使用ADC采集电压,然后换算成电流,再换算成电阻,通过PT100的阻值--温度关系得出温度;
    之前上一贴中已经做好测温设计的准备工作,那么就可以使用ADC和铂电阻进行测温了:
    ①看板子电路图,看芯片手册等文档,看网上前人使用铂电阻测温的分享资料,了解铂电阻特性及其测温方法,理清这块板测温的思路;
    ②编写测温程序,并调试;
    ③分析,总结,并发帖。
    详细过程如下:
    ①看板子电路图,看芯片手册等文档,看网上前人使用铂电阻测温的分享资料,了解铂电阻特性及其测温方法,理清这块板测温的思路;
    这是本板子的测温电路的原理图:

    铂电阻跟5K6的电阻串联,测出5K6电阻的电流即为铂电阻的电流,再测出铂电阻两端电压,就可以计算出电阻值了;
    其中AIN1、AIN0、AIN6、REFIN+可以接到ADC,AIN1的电压除以5K6就得到了电流,AIN1与AIN0的差分电压可以直接测出来;
    AIN6、REFIN+不知道做什么用的……
    但是看了下芯片手册ADC部分,看到了这个:
    这里有个电流源,可以连接到6脚,AIN6就可以用来给这条路提供电流;
    再看到关于这个电流源的说明:

    这里写明了可以用来激励外部的RTD传感器,就是本板子上的PT100RTD;
    那么现在的思路就是:用AIN6提供激励电流,用AIN1测电流,用AIN1和AIN0测电压;
    这个芯片aducm360有两个ADC,可以用其中一个测电流,一个测电压,但是测电流和测电压都用到了AIN1,就是不知道一个引脚可以同时连接
    到两个ADC么;
    在手册里找到这个:

    这里已经找到依据,AIN1可以同时连到两个ADC,那么接下来就可以照着这个思路写程序了:
    用AIN6提供激励电流,用AIN1和AGND连接到ADC0测电流,用AIN1和AIN0连接到ADC1测电压;
    ②编写测温程序,并调试;
    照着思路和电路图、手册写程序,配置好激励电流源,配置好ADC0和ADC1,然后开始测温;
    先写adc.c
    /**  ******************************************************************************  * @file    adc.c  * @author  YangJie  * @version V1.0  * @date    2016-9-9  * @brief   adc function  ******************************************************************************  * @attention  *            ADC0用来测电流  *            ADC1用来测电压  ******************************************************************************  *//* Includes ------------------------------------------------------------------*/#include        "adc.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/int32_t adc0_data = 0;int32_t adc1_data = 0;/* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//**  * @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   // 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       // ADC初始状态   AdcGo(pADI_ADC1,iStart);   // 中断使能   NVIC_EnableIRQ(ADC1_IRQn);}/**  * @brief  IEXCCON_Init  * @param  None  * @retval None  * @brief  配置激励电流  */void IEXCCON_Init(void){   // 配置PIN6上输出电流   IexcCfg(IEXCCON_PD_off,       // IEXCCON_PD_Off to enable Excitation Current source block            IEXCCON_REFSEL_Int,  // IEXCCON_REFSEL_Int to select Internal Current reference resistor            IEXCCON_IPSEL1_AIN6, // IEXCCON_IPSEL1_AIN6 to output IEXC1 to AIN6            IEXCCON_IPSEL0_Off   // IEXCCON_IPSEL0_Off to disable IEXC0           );   // 1.2V/5K6 = 214uA,最大只能设200uA,不然超过ADC上限1.2V   IexcDat(IEXCDAT_IDAT_100uA,IDAT0En);   // IEXCDAT_IDAT_100uA to output 100uA,IDAT0En to enable 10uA source}/**  * @brief  ADC0_Int_Handler  * @param  None  * @retval None  * @brief  ADC0中断服务函数  */        void ADC0_Int_Handler(){   volatile unsigned int adc_status_0 = 0;      adc_status_0 = AdcSta(pADI_ADC0);   // read ADC status register   adc0_data = AdcRd(pADI_ADC0);       // read ADC result register}/**  * @brief  ADC1_Int_Handler  * @param  None  * @retval None  * @brief  ADC1中断服务函数  */        void ADC1_Int_Handler(){   volatile unsigned int adc_status_1 = 0;      adc_status_1 = AdcSta(pADI_ADC1);   // read ADC status register   adc1_data = AdcRd(pADI_ADC1);       // read ADC result register}再为它写一个adc.h/**  ******************************************************************************  * @file    adc.h  * @author  YangJie  * @version V1.0  * @date    2016-9-9  * @brief   adc function  ******************************************************************************  * @attention  ******************************************************************************  *//* Define to prevent recursive inclusion -------------------------------------*/#ifndef __ADC_H#define __ADC_H /* Includes ------------------------------------------------------------------*/#include <ADuCM360.h>#include        "AdcLib.h"#include        "IexcLib.h"/* Exported variables ---------------------------------------------------------*/extern  int32_t adc0_data;extern  int32_t adc1_data;/* Exported functions ------------------------------------------------------- */void ADC0_Init(int iStart);void ADC1_Init(int iStart);void IEXCCON_Init(void);#endif然后在main.c里进行温度换算/**  ******************************************************************************  * @file    main.c  * @author  YangJie  * @version V1.0  * @date    2016-9-9  * @brief   Main program body  ******************************************************************************  * @attention  ******************************************************************************  *//* Includes ------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include <ADuCM360.h>#include        "clock.h"#include "Serial.h"#include        "delay.h"#include        "LED.h"#include        "adc.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//**  * @brief  Main program.  * @param  None  * @retval None  */int main(void){   Clk_Init();    SER_Init();   delay_init();   LED_Init();   ADC0_Init(ADCMDE_ADCMD_CONT);   ADC1_Init(ADCMDE_ADCMD_CONT);   IEXCCON_Init();      printf ("\n\r\n\r初始化成功!\n\r\n\r");      /* Infinite loop */   while (1)   {      float value_i = 0.0,value_v = 0.0,value_r = 0.0,value_t = 0.0;      static uint8_t i = 0;            value_i = (1.2 / 268435456) * adc0_data / 5600;      value_v = (1.2 / 268435456) * (-adc1_data);      value_r = value_v / value_i;      value_t = (value_r - 111.67 ) / 0.387 + 30;   // 30几度处每度0.387欧姆            printf ("\n\r%3d  I: fA   U: fV  R: fΩ  T: f℃\n\r",i++,value_i,value_v,value_r,value_t);            LED_on();      delay_ms(500);      LED_off();      delay_ms(500);   }}编译完成后到板子上跑一下,还可以,ADC没校准,温度也没有校准,大概行;
    跑了一段时间后的温度:

    手放上去后的温度会升高一些:

    感觉手的温度应该不会有这么高,而且还在慢慢上涨,这个东西还需要校准一下才能准;
    ③分析,总结,并发帖;
    至此,已经把温度测量做出来了,就是没有校准过,如果真的要作为一个高精度温度计,还有很多事情要做。
    备注:实际测试过,目前这种情况(ADC0P->AIN1,ADC0N->AGND,ADC1P->AIN1,ADC1N->AIN0),把AIN1连到ADC0的负输入端和ADC1的正输入端,实际上还是能正常工作,而手册上写的是同一引脚可以同时连两个ADC的正输入端。
    回复

    使用道具 举报

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

    本版积分规则

    手机版|小黑屋|与非网

    GMT+8, 2024-4-24 09:08 , Processed in 0.110369 second(s), 16 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.