一. 簡介
1. MAX31856
用MAX31856配合熱電偶測量溫度,美信官方說總體誤差在1.5 ℃內,0 ~ 85 ℃量程內在0.7 ℃內,我用OMEGA的HH-309A表比較過,誤差還是蠻小的,0 ~ 100 ℃量程內不超過±1 ℃。具體的電路設計可以參考美信公司官網的技術手冊和應用手冊,美信-MAX31856,熱電偶接口的RFI濾波電路最好不要省掉,否則測溫結果容易受干擾。
我直接從某寶買了兩個現成的模塊,一個83大洋,賊貴。
2. STM32
選的STM32F103C8T6最小系統板,也是在某寶買的,大概十幾個大洋一塊。開發的軟件用的CubeMX和Keil 5.26(HAL庫),CubeMX現在已經做得越來越好了,建議沒玩過的朋友嘗試一下。
二. 準備工作
1. 看技術手冊!!!
寫程序之前要仔細閱讀技術手冊,還要看買來模塊的電路圖,準備妥當再發車。電氣特性就不仔細介紹了,給個純淨的3.3 V電源就好。SPI通信時鐘頻率不能超過5 MHz,通信方式:時鐘極性(CPOL)可爲高電平,也可以爲低電平;時鐘相位(CPHA)爲第二個邊沿有效。芯片內部有16個寄存器,沒有什麼特別的要求的話(比如自己做冷端補償),主要關心CR0、CR1、MSAK、LTCBH、LTCBM、LTCBL、SR這幾個就好了,其他保持默認值。
存取寄存器時,使用地址0Xh爲讀操作,地址8Xh爲寫操作。CR0和CR1主要配置芯片工作模式,推薦設置連續採樣模式和採樣點平均,我把CR0設置爲0xA0,CR1設置爲0x33。MASK設置爲0x00,開啓所有的故障檢測,故障檢測週期在CR0寄存器裏配置。LTCBH、LTCBM、LTCBL存放最後的測溫結果,做一些轉換就能計算出來。芯片計算好一次溫度結果後會把DRDY引腳設爲低電平,推薦採用DRDY引腳觸發中斷來測量溫度。SR寄存器放置故障檢測的結果。
基本的流程就是,配置CR0、CR1、MASK三個寄存器,然後讀取LTCBH、LTCBM、LTCBL、SR的值,獲取溫度結果和測溫過程中的故障。
2. SPI配置
CubeMX中配置如下:
引腳如下:
三. 編寫程序
利用CubeMX生成Keil 5的工程後,新建並添加max31856.h和max31856.c文件,存放與其相關的代碼。這裏摘出主要代碼:
1. 列出各寄存器地址(.h文件中)
#define MAX31856_CR0_R_ADDR 0x00 // 配置0寄存器
#define MAX31856_CR0_W_ADDR 0x80
#define MAX31856_CR1_R_ADDR 0x01 // 配置1寄存器
#define MAX31856_CR1_W_ADDR 0x81
#define MAX31856_MASK_R_ADDR 0x02 // 故障屏蔽寄存器
#define MAX31856_MASK_W_ADDR 0x82
#define MAX31856_CJHF_R_ADDR 0x03 // 冷端上限故障
#define MAX31856_CJHF_W_ADDR 0x83
#define MAX31856_CJLF_R_ADDR 0x04 // 冷端下限故障
#define MAX31856_CJLF_W_ADDR 0x84
#define MAX31856_LTHFTH_R_ADDR 0x05 // 線性化溫度上限故障,MSB
#define MAX31856_LTHFTH_W_ADDR 0x85
#define MAX31856_LTHFTL_R_ADDR 0x06 // 線性化溫度上限故障,LSB
#define MAX31856_LTHFTL_W_ADDR 0x86
#define MAX31856_LTLFTH_R_ADDR 0x07 // 線性化溫度下限故障,MSB
#define MAX31856_LTLFTH_W_ADDR 0x87
#define MAX31856_LTLFTL_R_ADDR 0x08 // 線性化溫度下限故障,LSB
#define MAX31856_LTLFTL_W_ADDR 0x88
#define MAX31856_CJTO_R_ADDR 0x09 // 冷端溫度偏移寄存器
#define MAX31856_CJTO_W_ADDR 0x89
#define MAX31856_CJTH_R_ADDR 0x0A // 冷端溫度寄存器,MSB
#define MAX31856_CJTH_W_ADDR 0x8A
#define MAX31856_CJTL_R_ADDR 0x0B // 冷端溫度寄存器,LSB
#define MAX31856_CJTL_W_ADDR 0x8B
#define MAX31856_LTCBH_R_ADDR 0x0C // 線性化TC溫度,字節2
#define MAX31856_LTCBM_R_ADDR 0x0D // 線性化TC溫度,字節1
#define MAX31856_LTCBL_R_ADDR 0x0E // 線性化TC溫度,字節0
#define MAX31856_SR_R_ADDR 0x0F // 狀態故障寄存器
2. 初始化參數宏定義(max31856.h文件中)
這裏將MAX31856設置爲連續採樣模式,8個採樣點取一次平均值,設置爲K型熱電偶(根據熱電偶型號選擇,不過芯片也會自動識別),開啓所有故障檢測,每16個採樣點進行一次開路檢測。SPI_DELAY是SPI通信的超時大小。
#define MAX31856_INIT_CR0 0xA0
#define MAX31856_INIT_CR1 0x33
#define MAX31856_INIT_MASK 0x00
#define SPI_DELAY 0xff
3. 初始化函數(max31856.c文件中)
將初始化數據寫入到芯片的寄存器中去,由於CR0、CR1、MASK三個寄存器地址相連,用連續模式一次發送即可。
static uint8_t rx_buff[4] = {0};
static uint8_t tx_buff[4] = {0};
void max31856_init(void){
tx_buff[0] = MAX31856_CR0_W_ADDR;
tx_buff[1] = MAX31856_INIT_CR0;
tx_buff[2] = MAX31856_INIT_CR1;
tx_buff[3] = MAX31856_INIT_MASK;
HAL_GPIO_WritePin(SPI_CS1_GPIO_Port, SPI_CS1_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi2, tx_buff, 4, SPI_DELAY);
HAL_GPIO_WritePin(SPI_CS1_GPIO_Port, SPI_CS1_Pin, GPIO_PIN_SET);
}
4. 讀取溫度與故障數據(max31856.c文件)
因爲溫度數據和故障數據在連續的四個寄存器裏,所以採用連續方式一次讀取完。
LTCBH寄存器:
LTCBM寄存器:
LTCBL寄存器:
CR故障寄存器:
下面的代碼就是將溫度結果取出來,放在temp_pv變量中,故障寄存器的值放在max31856_error變量中。其中數據轉換部分的代碼參考了github上Adafruit_MAX31856,玩Arduino的可以直接去下載使用。
double temp_pv=0;
uint8_t max31856_error = 0;
void max31856_refresh(void){
tx_buff[0] = MAX31856_LTCBH_R_ADDR;
HAL_GPIO_WritePin(SPI_CS1_GPIO_Port, SPI_CS1_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi2, tx_buff, 1, SPI_DELAY);
HAL_SPI_Receive(&hspi2, rx_buff, 4, SPI_DELAY);
HAL_GPIO_WritePin(SPI_CS1_GPIO_Port, SPI_CS1_Pin, GPIO_PIN_SET);
int32_t temp24 = rx_buff[0];
temp24 <<= 8;
temp24 |= rx_buff[1];
temp24 <<= 8;
temp24 |= rx_buff[2];
if(temp24 & 0x00800000){
temp24 |= 0xFF000000;
}
temp24 >>= 5;
double temp = temp24;
temp *= 0.0078125;
temp_pv = temp;
max31856_error = rx_buff[3]; // 錯誤狀態位
}
四. 總結
以上就是max31856的調試過程,調通過後代碼特別簡潔,我後續把測試結果通過串口發到電腦上,驗證了上述的過程。調試的注意點有:SPI通信模式一定設置正確;發送和讀取寄存器的指令不一樣;max31856工作在連續模式和多點採樣平均效果最佳。