JX90614 红外温度传感器 × STM32F103C8T6 HAL库开发
JX90614 非接触式红外温度传感器的工作原理、核心功能与引脚定义
通过检测目标物体发出的红外辐射能量计算温度,无需物理接触,适用于运动部件、带电设备等场景。
集成了低噪声PGA和24位Σ-ΔADC,出厂已完成校准和线性化,分辨率达0.01°C/LSB,全温度范围精度1%,人体测温范围±0.1°C。
支持IIC和PWM两种数字输出方式(出厂设定为IIC),IIC最大频率400KHz,仅需SDA和SCL两根信号线,支持软件模拟驱动。
目标温度测量范围覆盖-70°C至+380°C,工作温度-40~125°C,可用于人体体温筛查、工业设备监控、家用电器温控等多种场景。
| 引脚 | 名称 | 功能 | STM32连接 |
|---|---|---|---|
| 1 | VDD | 电源输入端(底板供电5V,底板自带降压电路) | 5V |
| 2 | GND | 接地端,同时连接金属封装 | GND |
| 3 | SCL | IIC时钟输入端(底板已自带上拉电阻) | PB1(开漏输出) |
| 4 | SDA | IIC数据输入/输出端(底板已自带上拉电阻) | PB0(开漏输出) |
HB-T25 非接触式测温模块各角度实物照片与尺寸图
模块电路原理图与PCB封装设计
基于 STM32F103C8T6 HAL库的 JX90614 驱动程序逐模块解析
使用外部高速晶振(HSE)8MHz,通过PLL倍频9倍获得72MHz系统时钟。APB1总线分频为36MHz,APB2总线保持72MHz。
void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /* HSE 8MHz 外部晶振使能 */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz × 9 = 72MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /* SYSCLK = 72MHz, AHB = 72MHz, APB1 = 36MHz, APB2 = 72MHz */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1 = 36MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2 = 72MHz if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } }
使能GPIOD和GPIOA时钟。GPIOA用于ADC通道(本工程中ADC已配置但未在主程序中使用),JX90614和OLED的引脚在其各自的驱动文件中单独初始化。
void MX_GPIO_Init(void) { __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); }
使用软件模拟IIC通信,SCL接PB1,SDA接PB0,均配置为开漏输出模式(GPIO_MODE_OUTPUT_OD),高速频率。模块底板已自带SDA/SCL上拉电阻和5V降压电路,初始化后将两根线拉高释放总线即可正常通信。
#define JX90614_W_SCL_Port GPIOB #define JX90614_W_SCL_Pin GPIO_PIN_1 // SCL -> PB1 #define JX90614_W_SDA_Port GPIOB #define JX90614_W_SDA_Pin GPIO_PIN_0 // SDA -> PB0 void JX90614_I2C_Init(void) { JX90614_SCL_RCC_ENABLE(); JX90614_SDA_RCC_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; /* SCL: PB1, 开漏输出 */ GPIO_InitStruct.Pin = JX90614_W_SCL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(JX90614_W_SCL_Port, &GPIO_InitStruct); /* SDA: PB0, 开漏输出 */ GPIO_InitStruct.Pin = JX90614_W_SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(JX90614_W_SDA_Port, &GPIO_InitStruct); /* 释放总线 */ JX90614_I2C_W_SCL(1); JX90614_I2C_W_SDA(1); }
器件I2C通配7-bit地址为 0x7F(可通过寄存器0x92的Chip_Address配置)。初始化时先向命令寄存器 CMD(0x30) 写入 0x00 执行软复位,再写入 0x08 启动温度测量状态机。
#define CMD 0x30 // 命令寄存器地址 #define JX90164_ADDRESS 0x7F // 器件地址 void JX90164_Init(void) { JX90614_I2C_Init(); // 初始化软件I2C引脚 JX90164_WriteReg(CMD, 0x00); // 软复位 JX90164_WriteReg(CMD, 0x08); // 启动测量状态机 }
芯片内部DSP通过TaCal(环境温度校准数据)和To1Cal(热电堆校准数据)计算输出最终目标温度值To。程序从 DATA1_MSB(0x10)、DATA1_CSB(0x11)、DATA1_LSB(0x12) 三个寄存器分别读取24位温度数据的高、中、低字节,拼接后除以 214(16384)再乘以10,得到放大10倍的温度值(便于OLED显示小数)。
#define DATA1_MSB 0x10 // 温度数据高字节 #define DATA1_CSB 0x11 // 温度数据中字节 #define DATA1_LSB 0x12 // 温度数据低字节 void JX90164_Get_T_Data(int32_t* Temp) { uint8_t DataH, DataC, DataL; /* 分别读取三个字节 */ DataH = JX90164_ReadReg(DATA1_MSB); DataC = JX90164_ReadReg(DATA1_CSB); DataL = JX90164_ReadReg(DATA1_LSB); /* 拼接为24位原始数据 */ *Temp = (DataH << 16) | (DataC << 8) | DataL; /* 转换: 原始值 / 2^14 × 10 = 温度×10 */ *Temp = *Temp / (pow(2, 14)) * 10; }
例如:读取24位原始值 = 0x012C00(76800),则 T = 76800 ÷ 16384 × 10 = 46.8(×10),实际温度 = 46.8 ÷ 10 = 4.68°C
| 寄存器地址 | 名称 | 说明 |
|---|---|---|
| 0x10 | DATA1_MSB | 温度数据最高字节(Bits 23~16) |
| 0x11 | DATA1_CSB | 温度数据中间字节(Bits 15~8) |
| 0x12 | DATA1_LSB | 温度数据最低字节(Bits 7~0) |
| 0x30 | CMD | 命令寄存器(软复位/启动测量) |
使用0.96寸OLED显示屏(128×64),软件I2C驱动,SCL接PB15,SDA接PB14,I2C地址0x78。OLED_CenterPrintf函数实现字符串居中显示。
#define SCL_Port GPIOB #define SCL_Pin GPIO_PIN_15 // OLED SCL -> PB15 #define SDA_Port GPIOB #define SDA_Pin GPIO_PIN_14 // OLED SDA -> PB14 void OLED_CenterPrintf(int16_t Y, char *format, ...) { char String[256]; va_list arg; va_start(arg, format); vsprintf(String, format, arg); va_end(arg); // 居中显示: X = 64 - 字符串像素宽度/2 OLED_ShowString(64 - strlen(String) * 8 / 2, Y, String, OLED_8X16); }
使用 HAL_GetTick() 获取系统毫秒时间戳,每 500ms 读取一次温度数据,清屏后在OLED中央居中显示温度值(保留1位小数),最后更新时间戳。
uint32_t Time_Now; // 系统时间戳 int32_t temp; // 温度值(×10) int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); OLED_Init(); // OLED初始化 JX90164_Init(); // JX90614初始化 while (1) { if (HAL_GetTick() - Time_Now >= 500) // 500ms更新一次 { JX90164_Get_T_Data(&temp); // 读取温度 OLED_Clear(); // 清屏 OLED_CenterPrintf(24, "%.1f°C", temp / 10.0); // 居中显示 OLED_Update(); // 更新显示 Time_Now = HAL_GetTick(); // 更新时间戳 } } }
主程序执行流程,包含初始化序列与 while(1) 主循环
模拟 JX90614 非接触式测温过程,调节目标温度观察传感器响应与OLED显示