《电子DIY》之基于STM32驱动K型热电偶模块MAX6675(采集温度)

一,K型热电偶MAX6675简介

热电偶是一种感温元件 , 它把温度信号转换成热电动势信号 , 通过电气仪表转换成被测介质的温度。热电偶测温的基本原理是两种不同成份的均质导体组成闭合回路 , 当两端存在温度梯度时 , 回路中就会有电流通过,此时两端之间就存在 Seebeck 电动势——热电动势,这就是所谓的塞贝克效应。两种不同成份的均质导体为热电极,温度较高的一端为工作端, 温度较低的一端为自由端,自由端通常处于某个恒定的温度下。根据热电动势与温度的函数关系 , 制成热电偶分度表 ; 分度表是自由端温度在 0 ℃ 时 的条件下得到的,不同的热电偶具有不同的分度表。在热电偶回路中接入第三种金属材料时 , 只要该材料两个接点的温度相同 , 热电偶所产生的热电势将保持不变,即不受第三种金属接入回路中的影响。因此 , 在热电偶测温时 , 可接入测量仪表 , 测得热电动势后 , 即可知道被测介质的温度。

热电偶的种类
  K 型(镍铬 - 镍硅) WRN 系列 N 型(镍铬硅 - 镍硅镁) WRM 系列
  E 型(镍铬 - 铜镍) WRE 系列 J 型(铁 - 铜镍) WRF 系列
  T 型(铜 - 铜镍) WRC 系列  S 型(铂铑 10- 铂) WRP 系列
  R 型(铂铑 13- 铂)WRQ系列 B 型(铂铑 30- 铂铑 6 )WRR 系列
  
热电偶作为一种主要的测温元件,具有结构简单、制造容易、使用方便、测温范围宽、测温精度高等特点。但是将热电偶应用在基于单片机的嵌入式系统领域时,却存在着以下几方面的问题。①非线性:热电偶输出热电势与温度之间的关系为非线性关系,因此在应用时必须进行线性化处理。②冷补偿:热电偶输出的热电势为冷端保持为0℃时与测量端的电势差值,而在实际应用中冷端的温度是随着环境温度而变化的,故需进行冷端补偿。③数字化输出:与嵌入式系统接口必然要采用数字化输出及数字化接口,而作为模拟小信号测温元件的热电偶显然法直接满足这个要求。因此,若将热电偶应用于嵌入式系统时,**须进行复杂的信号放大、A/D转换、查表线性线、温度补偿及数字化输出接口(a)**等软硬件设计。如果能将上述的功能集成到一个集成电路芯片中,即采用单芯片来完成信号放大、冷端补偿、线性化及数字化输出功能,则将大大简化热电偶在嵌入式领域的应用设计。

热电偶工作原理:
当有两种不同的导体或半导体A和B组成一个回路,其两端相互连接时,只要两结点处的温度不同,一端温度为T,称为工作端或热端,另一端温度为T0 ,称为自由端(也称参考端)或冷端,回路中将产生一个电动势,该电动势的方向和大小与导体的材料及两接点的温度有关。这种现象称为“热电效应”,两种导体组成的回路称为“热电偶”,这两种导体称为“热电极”,产生的电动势则称为“热电动势”。热电动势由两部分电动势组成,一部分是两种导体的接触电动势,另一部分是单一导体的温差电动势
(摘自《传感器原理》)

MAX6675满足了(a)条件,即集其成了热电偶放大器、冷端补偿、A/D转换器及SPI串口的热电偶放大器与数字转换器。
MAX6675冷端温度补偿、热电偶数字转换器可进行冷端温度补偿,并将K型热电偶信号转换成数字信号。数据以SPI™兼容的12位分辨率只读格式输出。该转换器可将温度解析为0.25°C,允许读数高达+ 1024°C。在0°C至+ 700°C温度范围内具有8LSB的热系数精度。

MAX6675的主要特性如下:
①简单的SPI串行口温度值输出;
②0℃~+1024℃的测温范围;
③12位0.25℃的分辨率;
④片内冷端补偿;
⑤高阻抗差动输入;
⑥热电偶断线检测;
⑦单一+5V的电源电压;
⑧低功耗特性;
⑨工作温度范围-20℃~+85℃;
⑩2000V的ESD信号。
备注:该器件采用8引脚SO帖片封装。

二,MAX6675引脚定义:

在这里插入图片描述

引脚	  名称	 功能
1	     GND	接地端
2	      T-	K型热电偶负极
3		  T+	K型热电偶正极
4		 VCC	正电源端
5	     SCK	串行时钟输入
6	      CS	片选端,CS为低时、启动串行接口
7	      SO	串行数据输出
8	      N.C.	空引脚

三,MAX6675工作原理分析:

MAX6675内部框图
在这里插入图片描述

MAX6675内部具有将热电偶信号转换为与ADC输入通道兼容电压的信号调节放大器,T+和T-输入端连接到低噪声放大器A1,以保证检测输入的高精度,同时使热电偶连接导线与干扰源隔离。热电偶输出的热电势经低噪声放大器A1放大,再经过A2电压跟随器缓冲后,被送至ADC的输入端。在将温度电压值转换为相等价的温度值之前,它需要对热电偶的冷端温度进行补偿,冷端温度即是MAX6675周围温度与0℃实际参考值之间的差值。对于K型热电偶,电压变化率为41μV/℃,电压可由线性公式**Vout=(41μV/℃)×(tR-tAMB)**来近似热电偶的特性。上式中,Vout为热电偶输出电压(mV),tR是测量点温度;tAMB是周围温度。

典型应用电路显示了MAX6675与微控制器接口。 MAX6675处理来自热电偶的读数,并通过串行接口传输数据。强制CS为电平并在SCK处施加时钟信号以读取SO的结果。 强制CS低立即停止任何转换过程。 发起新的转化通过迫使CS来进行处理。强制CS为低电平以输出SO引脚上的第一位。 一个完整的串行接口读取需要16个时钟周期。在时钟的下降沿读取16个输出位。第一位D15是伪符号位,始终为零。 D14–D3位包含转换后的温度从MSB到LSB的顺序。 D2位通常为低电平且当热电偶输入打开时变为高电平。 D1是低电平,为MAX6675和D0位提供器件ID是三态。数据格式如下图:
在这里插入图片描述
(以上介绍官方芯片手册翻译过来,若有错误欢迎评论指出)

与MCU电路连接图:
在这里插入图片描述

四,MAX6675时序:

采集数据时序:
在这里插入图片描述
在这里插入图片描述

五,MAX6675模块实物图:

在这里插入图片描述
(只拍了背面)

六,MAX6675驱动源程序:

max6675 头文件

#ifndef __max6675_H
#define __max6675_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
typedef struct __MAX6675
{
	u16 temperatureBasic; 
    long temp; 	
	float temperatureHandle;     
	u8  checkFlag;              
}MAX6675;
extern MAX6675 max6675;
#define MAX6675PORT      GPIOA
#define MAX6675PIN_CLK   GPIO_Pin_11
#define MAX6675PIN_SO    GPIO_Pin_12
#define MAX6675PIN_CS    GPIO_Pin_6
#define MAX6675CLK       RCC_APB2Periph_GPIOA
//IO operation function	
#define	MAX6675_CS     PAout(6)  
#define	MAX6675_CLK    PAout(11) 
#define	MAX6675_SO     PAin(12)  
//Function declaration
void max6675_Init(void);
u16  max6675_ReadData(void);    
void max6675_HandleData(void);
void max6675_ReadDataCnt(u16 count);
void max6675_ExcuteTest(void);
void max6675_TimeBase_Init(u16 arr,u16 pre);
#endif

max6675 C文件

#include "max6675.h"
#include "usart.h"
MAX6675 max6675={0,0,0.0,0};
/*
*	Function name: initialize MAX6675
*	author: liuxianfei0810
*	Parameter: None
*	Return value: None
*/
void max6675_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(MAX6675CLK,ENABLE);//Turn on the clock
	//Initialization pin
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=MAX6675PIN_CLK|MAX6675PIN_CS;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(MAX6675PORT,&GPIO_InitStruct);
 	GPIO_SetBits(MAX6675PORT,MAX6675PIN_CLK|MAX6675PIN_CS);	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=MAX6675PIN_SO;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(MAX6675PORT,&GPIO_InitStruct);
	MAX6675_CLK=MAX6675_CS=1;	
}
u16 max6675_ReadData(void)
{
	u16 dat=0;
	u16 i=0;
//时序中各时间延时如下:(根据官方手册)
/*
	fSCL <= 4.3MHz
	tCH  >= 100ns
	tCL  >= 100ns
	tCSS >= 100ns
	tDV  <= 100ns
	tTR  <= 100ns
	tDO  <= 100ns 
*/
	MAX6675_CLK=0;
	MAX6675_CS=0;
	for(i=0;i<16;i++)
	{
		MAX6675_CLK=1;
		delay_us(1);
		dat<<=1;
		if(MAX6675_SO)
			dat|=0x01;
		MAX6675_CLK=0;
		delay_us(1);
	}
	MAX6675_CS=1;
	max6675.temperatureBasic=dat;
	return dat;
}
void max6675_HandleData(void)
{
	max6675.temperatureBasic>>=3;
	max6675.temperatureBasic&=~(0xf<<12);
	max6675.temperatureHandle=(float)max6675.temperatureBasic*0.25;
	
}
void max6675_ReadDataCnt(u16 count)
{
	u16 i=0;
	max6675.temp=0;
	max6675.temperatureBasic=0;
	max6675.temperatureHandle=0.0;
	for(i=0;i<count;i++)
	{
		max6675.temp+= max6675_ReadData();
		delay_ms(1);
	}
	max6675.temperatureBasic=(u16)(max6675.temp/count);
}

void max6675_ExcuteTest(void)
{
	if(max6675.checkFlag)
	{
		max6675.checkFlag=0;
		//close timer
		max6675_ReadDataCnt(20);
	//	    max6675_ReadData();
		max6675_HandleData();	
		printf("\r\nMAX6675采集的原始数据为: %d \r\n\r\n",max6675.temperatureBasic);
		printf("\r\nMAX6675处理后的数据为: %f 度\r\n\r\n",max6675.temperatureHandle);
		TIM_Cmd(TIM2,ENABLE);
	}
	else;
}
void max6675_TimeBase_Init(u16 arr,u16 pre)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//Turn on the clock
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=arr;
	TIM_TimeBaseInitStruct.TIM_Prescaler=pre;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn; 
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; 
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStruct);
	TIM_Cmd(TIM2,ENABLE);
	
}
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
	{
		max6675.checkFlag=1;
	}
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	TIM_Cmd(TIM2,DISABLE);
}

备注:通过定时器延时,具体延时时间自己按要求设定

七,效果图:

使用串口助手打印采集的数据:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/liuxianfei0810/article/details/105903354