MAX30205 是一款接觸式的人體溫度感測器,MAXIM也有在他們的Health Sensor Platform 2.0中提及使用該感測器進行人體溫度的估測,該感測器使用I2C通訊介面進行存取,支持2.7~3.3V的準位通訊,同時為16-Bit的解析度(0.00390625 °C ),在體積也算是相當小。
該實例以STM32L031F6Px進行開發,使用I2C通訊協定,配合STM32CubeMX及Keil 5,使用HAL函式庫。關於感測器更詳細的內容及資料可以參考資料手冊:MAXIM MAX30205
MAX30205 為8Pin的TDFN封裝,主要僅需使用到VDD、GND、SDA、SCL即可,剩餘的腳皆為設定的腳位。在官方的資料手冊Page9有提及I2C Slave Address的設定方式,可以透過A0、A1、A2進行Address的設定。
該感測器的存取也相當容易,內部的暫存器僅有四個。
因此在完成STM32CubeMX的專案建立後,在Keil的部分建立一個Header檔,檔案名稱為max30205.h,用來宣告MAX30205的相關變數。
在上方有提及僅有四個暫存器,分別為Temperature、Configuration、THYST 、TOS,同時該實例將A0、A1、A2都接GND,因此I2C地址為0x90。
#ifndef __MAX_30205_H_
#define __MAX_30205_H_
#include "stm32l0xx_hal.h"
#define MAX30205_ADDR 0x90
#define MAX30205_TEMP 0x00
#define MAX30205_CONFIG 0x01
#define MAX30205_THYST 0x02
#define MAX30205_TOS 0x03
#endif
接著我們建立一個max30205.c檔,用來宣告存取的Function及I2C的通訊Function,以利未來使用其他的晶片仍可以快速地移植使用。
因此在I2C的Function共有三個函式需要定義,未來若使用TI、PIC、Nuvoton等MCU,改變此部分的函式宣告即可。
● max30205_i2c_readBytes
void max30205_i2c_readBytes(uint8_t address, uint8_t reg, uint8_t* data, uint8_t size) {
HAL_I2C_Mem_Read(&hi2c1, MAX30205_ADDR, reg, 1, data, size, 100);
}
● max30205_i2c_readByte
uint8_t max30205_i2c_readByte(uint8_t address, uint8_t reg) {
uint8_t value = 0;
HAL_I2C_Mem_Read(&hi2c1, MAX30205_ADDR, reg, 1, (uint8_t*)&value, 1, 100);
return value;
}
●max30205_i2c_writeByte
uint8_t max30205_i2c_writeByte(uint8_t address, uint8_t reg, uint8_t value) {
uint8_t ret;
ret = HAL_I2C_Mem_Write(&hi2c1, MAX30205_ADDR, reg, 1, (uint8_t*)&value, 1, 100);
return ret;
}
接著要進行 MAX30205 的Inital,在資料手冊的Page12~13可以更清楚Configuration暫存器如何去設定,但該實例僅需存取溫度,沒有需要額外的設定或格式的調整,因此Configuration設定為0x00即可,而 THYST 、TOS 可以在Page8有更多的了解,在此我們一樣設定為0x00。
● max30205_Init
void MAX30205_Init(void){
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_CONFIG, 0x00); //mode setting
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_THYST , 0x00); //threshold
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_TOS, 0x00);
}
完成Inital後,若需要將 MAX30205 關機,以獲得更佳的低功耗可以使用SHUTDOWN的功能,去調用Configuration的暫存器即可。若需要使用ONE-SHOT模式(量測一次即關機),也需要先進行SHUTDOWN的設定。
● MAX30205_Shutdown
void MAX30205_Shutdown(void){
uint8_t config_reg = max30205_i2c_readByte(MAX30205_ADDR, MAX30205_CONFIG); // Get the current register
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_CONFIG, config_reg | 0x01);
}
●MAX30205_OneShotMode
void MAX30205_OneShotMode(void){
MAX30205_Shutdown();
uint8_t config_reg = max30205_i2c_readByte(MAX30205_ADDR, MAX30205_CONFIG); // Get the current register
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_CONFIG, config_reg | 0x80);
}
接著完成了以上的函式宣告,最重要的就是取得溫度數值!溫度暫存器為2個Byte,每階的解析度為 0.00390625 °C ,因此將 Temperature暫存器取值後,乘上 0.00390625即可得到正確的溫度數值。
● MAX30205_GetTemperature
float MAX30205_GetTemperature(void) {
uint8_t buffer[2];
uint8_t config_reg = max30205_i2c_readByte(MAX30205_ADDR, MAX30205_CONFIG); // Get the current register
max30205_i2c_writeByte(MAX30205_ADDR, MAX30205_CONFIG, config_reg | 0x80); // Set one-shot mode
max30205_i2c_readBytes(MAX30205_ADDR, MAX30205_TEMP, buffer, 2);
int16_t raw = ((uint16_t)buffer[0] << 8) | buffer[1];
return ((double)raw * 0.00390625);
}
以上就完成了max30205.c,來看一下整題的截圖為何吧!
接著回到max30205.h將剛剛的函式都宣告在此即可。
完成了 max30205 的library後,回到main.c,在/* USER CODE BEGIN 2 */新增Init及ONE-SHOT的設定,並宣告temp變數以存取溫度即可。
/* USER CODE BEGIN 2 */
MAX30205_Init();
MAX30205_OneShotMode();
float temp = 0;
/* USER CODE END 2 */
在while當中引用 MAX30205_GetTemperature即可取得溫度囉!
temp = MAX30205_GetTemperature();
透過Debug Mode即可查看temp的變化。