基于STM32F103驱动AD7793采集K型热电偶温度


前言

  基于AD7793的温度测量系统和ADI CN0206_cn推荐文档。采用PT100作为冷结补偿,4线SPI接口,支持SPI复用。32倍增益时最高热动势为36.5mV,对应K热电偶分度表为850摄氏度。AD7793适合高精度测量应用的低功耗、低噪声的完整模拟前端,内置一个低噪声、带有三个差分模拟输入的24位Σ-Δ型ADC。还集成了片内低噪声仪表放大器,可直接输入小信号。

一、AD7793简介

  AD7793 是一款适合高精度测量应用的低功耗、低噪声、 完整模拟前端, 内置PGA、 基准电压源、时钟和激励电流, 从而大大简化了热电偶系统设计。 系统峰峰值噪声约为0.02°C。AD7793 的最大功耗仅500 μA, 因而适合低功耗应用,例如整个发送器的功耗必须低于4 mA 的智能发送器等。 AD7793还具有关断选项。在这种模式下,整个ADC及其辅助功能均关断,器件的最大功耗降至1 μA。
 主要特性:
   1. 24位Σ-Δ ADC:高分辨率(24位)的ADC适合高精度、低噪声信号测量。
   2. 输入通道:AD7793有3个差分输入通道(或者6个伪差分输入通道),支持多路传感器或信号的采集。
   3. 可编程增益放大器(PGA):AD7793内部带有一个可编程增益放大器,增益可以设置为1、2、4、8、16、32、64、128,便于对不同输入信号幅度进行调节。
   4. 低噪声特性:AD7793专为低噪声应用设计,噪声水平在一定条件下低至50 nV。
   5. 集成滤波器:AD7793内置低通滤波器,可用于抑制50Hz和60Hz工频干扰。
   6. 片内偏置电压和偏移校准功能:消除系统误差,提供高精度输出。
   7. SPI接口:AD7793通过标准的SPI接口与外部微控制器或处理器进行通信,方便数据采集和控制。

二、AD7793应用领域

  • 热电偶测量、热敏电阻测量
  • 仪器仪表信号采集
  • 压力传感器,电子秤测量等

三、系统框图及通讯时序


四、温度换算

   AD7793提供一种集成式热电偶解决方案,可以直接与热电偶接口。冷结补偿由一个热敏电阻和一个精密电阻提供。该电路只需要这些外部元件来执行冷结测量,以及一些简单的R-C滤波器来满足电磁兼容性要求。
   热电偶的传递函数不是线性的。在0°C至+60°C的温度范围,其响应非常接近线性。但是,在更宽的温度范围内,必须使用一个线性化程序处理。AD7793采用单电源供电,热电偶产生的信号必须被偏置到地以上,从而处于该ADC支持的范围。对于128倍的增益,模拟输入端的绝对电压必须在GND + 300 mV至AVDD – 1.1 V范围内。
   热敏电阻在+25°C时的值为1 kΩ,0°C时的典型值为815 Ω,+30°C时的典型值为1040 Ω。假设0°C至30°C的传递函数为线性,则冷结温度与热敏电阻R之间的关系为:
                           冷结温度 = 30 × (R – 815)/(1040 – 815)
   对热敏电阻通道进行采样时,AD7793以1倍的增益工作。对于+30°C的最大冷结温度,热敏电阻上产生的最大电压为1 mA × 1040 Ω = 1.04 V。
   AD7793以16.7 Hz的输出数据速率工作。每读取10个热电偶转换结果,就读取1个热敏电阻转换结果。相应的温度等于:
                           温度 = 热电偶温度 + 冷结温度
   图2显示了T型热电偶上产生的电压与温度的关系。圆圈内的区域是从0°C到+60°C,该区域内的传递函数接近线性。

五、热电偶温度计算

  参照上述图2电压与温度的关系,由分度表近似计算热电动势与温度的斜率方式计算,也可以根据国际温标ITS90多项式拟合计算。
  通过斜率计算:从0°C到+60°C,电压与温度的传递函数接近线性y=Kx。查看分度表上的对应值,计算温度变化对电压的变化率。当然,函数是接近线性,而不是线性,计算得到的是估算值。
斜率 S = E M F 60 ° C − E M F 0 ° C 60 ℃ − 0 ℃ 斜率S=\frac{EMF60°C-EMF0°C}{60℃-0℃} 斜率S=60℃0℃EMF60°CEMFC
由于公式是根据热电偶的电压求解温度,还需求斜率的倒数1/S得到对应的系数。图下所示K型热电偶分度表:

  通过ITS90多项式拟合计算:ITS-90提供了热电偶电压和温度之间的精确近似公式,而ITS90多项式又分为正多项式和逆多项式。正多项式从一个已知温度(˚C)提供热电电压(V),逆多项式从一个已知热电电压(V)提供温度(˚C)。而示例中的系数则根据正多项式计算出:
E ( T ) = a 0 + a 1 T + a 2 T 2 + . . . + a n T n E(T)=a_0+a_1T+a_2T^2+...+a_nT^n E(T)=a0+a1T+a2T2+...+anTn
其中,E(T)是热电偶在温度T时产生的热电动势(以mV为单位),a0,a1,a2,…,an是热电偶的常数系数。
  在0°C到60°C的温度范围内,热电偶电压与温度关系可以被近似为线性。ITS-90标准多项式可以查到,近似在该温度范围内的关系为线性,可以通过正、逆多项式的一阶系数(即线性部分)来计算线性系数。
E ( T ) ≈ a 0 + a 1 T E(T)≈a_0+a_1T E(T)a0+a1T
  对于K型热电偶,一次项系数a1对应的正多项式系数为 38.9212 mV/°C。这个系数可以理解为每升高1°C,热电偶产生的电压大约增加 38.9212 μV。为了将热电偶的电压换算成温度,需要求解出从电压 𝐸(𝑇) 到温度 𝑇的转换系数。基于一次项的近似公式:
T ≈ E ( T ) a 1 ≈ 25692.9385 ℃ / V T≈\frac{E(T)}{a_1}≈25692.9385℃/V Ta1E(T)25692.9385℃/V

五、AD7793采集示例

1.准备工作

   STM32F103ZET6开发板、AD7793温度采集模块、K型热电偶。

2.引脚接线

AD7793STM32F103
3.3V3V3
GNDGND
DRDYPD0
SDIPD2
SCLKPD3
nCSPD4

3.示例代码

AD7793.c

#include "ad7793.h"

void RCC_Configurations(void) 
{    
  ErrorStatus HSEStartUpStatus;
  RCC_DeInit(); 
  RCC_HSEConfig(RCC_HSE_ON); 
  HSEStartUpStatus = RCC_WaitForHSEStartUp(); 
  if(HSEStartUpStatus == SUCCESS) 
  { 
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 
    FLASH_SetLatency(FLASH_Latency_2); 
    RCC_HCLKConfig(RCC_SYSCLK_Div1);  
    RCC_PCLK2Config(RCC_HCLK_Div1);  
    RCC_PCLK1Config(RCC_HCLK_Div2); 
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); 
    RCC_PLLCmd(ENABLE); 
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 
    while(RCC_GetSYSCLKSource() != 0x08) { } 
  } 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC| RCC_APB2Periph_GPIOD, ENABLE); 
} 

void GPIO_Configurations(void) 
{ 
  GPIO_InitTypeDef GPIO_InitStructure; 
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_4; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
  GPIO_Init(GPIOD, &GPIO_InitStructure); 
} 

void NVIC_Configurations(void) 
{ 
#ifdef  VECT_TAB_RAM   
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);  
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);    
#endif 
} 

void Delay(vu32 nCount) 
{ 
  for(; nCount != 0; nCount--); 
} 

void AD7793Reset(void)
{
  uint8_t ResetTime;
  ResetTime=50;
  AD7793_SCLK_H;
  AD7793_CS_L;
  AD7793_SDI_H;
  while(ResetTime--)
  {
    AD7793_SCLK_L;
    Delay(200);
    AD7793_SCLK_H;
    Delay(200);
  }
}

void AD7793Write(uint8_t Data)
{
  uint8_t data;
  data=Data;
  AD7793_SCLK_H;
  AD7793_CS_L;
  AD7793_SDI_L;
  for(uint8_t i=0;i<8;i++)
  {
    AD7793_SCLK_L;
    if(data&0x80)
    AD7793_SDI_H;
    else
    AD7793_SDI_L;
    Delay(100);
    AD7793_SCLK_H;
    Delay(100);
    data=data<<1;
  }
  //AD7793_CS_H;
}

uint32_t AD7793Read(void)
{
  uint32_t DATA;
  AD7793_SDI_L;
  AD7793_CS_L;
  AD7793_SCLK_H;
  DATA=0;
  for(uint8_t i=0;i<24;i++)
  {
    DATA<<=1;
    AD7793_SCLK_L;
    Delay(100);
    if(AD7793_DOUT)
    DATA|=0x01;
    AD7793_SCLK_H;
    Delay(100);
  }
  //AD7793_CS_H;
  return DATA;
}

uint8_t AD7793Read_Byte(void)
{
  uint8_t DATA;
  AD7793_SDI_L;
  AD7793_CS_L;
  AD7793_SCLK_H;
  DATA=0;
  for(uint8_t i=0;i<8;i++)
  {
    DATA<<=1;
    AD7793_SCLK_L;
    Delay(100);
    if(AD7793_DOUT)
    DATA|=0x01;
    AD7793_SCLK_H;
    Delay(100);
  }
  //AD7793_CS_H;
  return DATA;
}

uint8_t Get_AD7793_ID(void)
{
  uint8_t ID;
  AD7793Write(0x60);//读满刻度校准寄存器的值
  ID=AD7793Read_Byte();
  return ID;
}

void AD7793_thermocouple_init(void)
{	
  AD7793Reset();
  Delay(20000);
  AD7793Write(0x28);//IO register
  AD7793Write(0x0A);//Set 420uA Current Source for PT100
  
  AD7793Write(0x10);//configuration register
  AD7793Write(0x45);//Gain =32
  AD7793Write(0x90);//00010000//10010000

  AD7793Write(0x08);//Mode Register
  AD7793Write(0x00);//00000000
  AD7793Write(0x0B);//00001011  12.5Hz DATA OUT
}

void AD7793_GetPT100_init(void)
{	
  AD7793Reset();
  Delay(20000);
  AD7793Write(0x28);//IO register
  AD7793Write(0x0A);//Set 420uA Current Source for PT100

  AD7793Write(0x10);//configuration register
  AD7793Write(0x40);//Gain =1   01000101
  AD7793Write(0x11);//10010000//100100001

  AD7793Write(0x08);//Mode Register
  AD7793Write(0x00);//00000000
  AD7793Write(0x0B);//00001011 12.5Hz DATA OUT
}

float Get_PT100(void)//Return the temp of PT100;
{
  float PT100_TEMP;
  float PT100_R_Value;
  uint32_t DATA_T;
  while(AD7793_DOUT);
  AD7793Write(0x58);
  DATA_T=AD7793Read()-0x800000;
  PT100_TEMP=DATA_T;
  PT100_TEMP/=0x7fffff;
  PT100_R_Value=PT100_TEMP*402;
  PT100_TEMP=(PT100_R_Value-100)/0.385055;//A gruad
  return PT100_TEMP;
}

float Get_thermocouple_Value(void)//Return the Voltage of TC;
{
  float Voltage;
  uint32_t DATA_T;
  int32_t DATA_T1;
  while(AD7793_DOUT);
  AD7793Write(0x58);
  DATA_T=AD7793Read();
  DATA_T^=0xFFFFFF;
  DATA_T&=0xffffff;
  DATA_T1=0x7FFFFF-DATA_T;
  Voltage=DATA_T1*1.17; //Vref=1.17V
  Voltage/=0x7fffff;
  Voltage/=32;//gain = 32
  return Voltage;
}

void AD7793init(void)
{	
  AD7793Reset();
  Delay(200);
  AD7793Write(0x28);//IO register
  AD7793Write(0x06);//AD7793Write(0x02),
  AD7793Write(0x10);//configuration register
  AD7793Write(0x10);//Gain 1
  AD7793Write(0x10);//external Reference
  
  AD7793Write(0x08);//Mode Register
  AD7793Write(0x80);//内部零刻度校准
  AD7793Write(0x4F);
  Delay(800);
  while(AD7793_DOUT);
  AD7793Write(0x08);//Mode Register
  AD7793Write(0xA0);//内部满量程校准
  AD7793Write(0x4F);//
  Delay(800);
  while(AD7793_DOUT);
}

#ifdef  DEBUG 
void assert_failed(u8* file, u32 line) 
{  
  while (1) { } 
} 
#endif 

main.c

#include "stm32f10x.h"
#include "systemconfig.h" 
#include "common.h"
#include "stdio.h"	
#include "ad7793.h"

int main(void)
{	
	float TC_voltage;
    float PT100_temp;
	float tempsssssssss;
	uint32_t TESTSSS;
	uint8_t AD7793_ID;
	
	RCC_Configurations();
    GPIO_Configurations();
    NVIC_Configurations();
    AD7793init();
    AD7793_ID=Get_AD7793_ID();//Read AD7793 ID(0xXB)

	SystemConfiguration();		    //系统初始化
	USART_Config(USART1,115200);    //串口1初始化,波特率 115200

	while(1)
	{	
		AD7793_CS_L;
		AD7793_thermocouple_init();
		Delay_ms(2000);
		TC_voltage = Get_thermocouple_Value();
			
		tempsssssssss=TC_voltage*25692.9385+PT100_temp;  //读取PT100温度
		Delay_ms(2000);
		AD7793_GetPT100_init();
		Delay_ms(2000);
		PT100_temp = Get_PT100();
		Delay_ms(2000);
		
		printf(" %.2f℃  ",tempsssssssss);
		printf("\r\n"); 
	}
}

4.示例演示

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值