《電子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);
}

備註:通過定時器延時,具體延時時間自己按要求設定

七,效果圖:

使用串口助手打印採集的數據:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章