1 项目介绍
本项目使用温度传感器NST461-DQNR设计外围电路,并使用STM32F103单片机读取本地温度和远程温度。完成串口输出对应温度数据,并在串口软件上完成温度曲线图绘制。并使用12指神探查看I2C的数据波形。
2 项目设计思路
2.1 功能需求
1. 单片机可以读到NST461-DQNR芯片的本地温度和远程温度。
2. 采用STM32F103进行NST461-DQNR芯片的温度数据采集和数据处理,并通过其串口打印温度数据并绘制温度曲线。
3. 使用12指神探查看NST461-DQNR芯片的I2C通讯。
2.2 设计框图

1. NST461-DQNR进行温度采集。
2. STM32F103进行数据采集和处理。
3. 12指神探查看NST461-DQNR与STM32F103的通讯。
4. 上位机VOFA+接收STM32F103处理后的数据进行打印和显示。
2.3 硬件设计
1.NST461-DQNR:小尺寸高精度12C接口远程和本地数字温度传感器
NST461是一款远程温度传感器监视器,内置本地温度传感器。其远程温度传感器连接的晶体管通常是低成本的NPN或PNP类型晶体管或衬底热晶体管及二极管。NST461的工作电压范围为2.1V至3.6 V,温度范围为-40℃至125℃,是通信、计算、仪表和工业等众多应用中多位置、高精度温度测量的理想选择。
其核心原理是利用了半导体PN结的一个周有物理特性:在恒定电流下,PN结的正向压降(Vbe)会随温度升高而几乎线性地下降。
2. STM32F103:ARM 32位的Cortex-M3,最高72MHz工作频率,2.0-3.6V供电和I/O引脚。2个I2C接口,3个USART接口。
2.4 电路板设计
电路板设计使用KiCAD 9.0版本设计绘制了NST461-DQNR及其外围电路,其中NST461-DQNR封装为自己绘制。STM32主控采用最小系统板。

这里A0和A1为地址选择配置引脚,为了灵活配置,采用0欧姆的电阻进行连接。

PCB绘制如下,在接口处最好写上引脚的作用。
2.5 关键代码展示与说明
项目基于CubeMX和Keil5平台进行开发。
CubeMX配置如下:

配置了I2C1和SUART2。因为采用SUART1进行程序烧录。
配置完成后生成代码,在KEIL中添加以下代码。我们可以将芯片手册为给deepseek,让其为我们写代码,但是他写的代码有时候会有点问题,结构体中数组它用指针的方式去访问,直接报错了。报错时需要自己看看。
#include <stdio.h>
#include <string.h>
#define NST461_ADDR_WRITE 0x98 // A1=Float, A0=Float时的写地址
#define NST461_ADDR_READ 0x99 //读地址
#define REG_LOCAL_TEMP_H 0x00
#define REG_REMOTE_TEMP_H 0x01
#define REG_LOCAL_TEMP_L 0x15
#define REG_REMOTE_TEMP_L 0x10
//温度数据结构体
typedef struct {
float local_temp;
float remote_temp;
uint8_t status;
} TempData_t;
//重写_write函数,让printf输出到串口
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
/**
* @brief读取完整的12位本地温度数据
* @retval高精度温度值
*/
float NST461_ReadLocalTemperatureFull(void)
{
uint8_t temp_data[2] = {0};
int16_t raw_temp = 0;
HAL_StatusTypeDef status;
//读取温度高字节(寄存器地址0x00)
status = HAL_I2C_Mem_Read(&hi2c1,
NST461_ADDR_READ,
REG_LOCAL_TEMP_H,
I2C_MEMADD_SIZE_8BIT,
&temp_data[0],
1,
HAL_MAX_DELAY);
//读取温度低字节(寄存器地址0x15)
status = HAL_I2C_Mem_Read(&hi2c1,
NST461_ADDR_READ,
0x15, //本地温度低字节地址
I2C_MEMADD_SIZE_8BIT,
&temp_data[1],
1,
HAL_MAX_DELAY);
if(status == HAL_OK)
{
//组合12位温度数据
raw_temp = (temp_data[0] << 8) | temp_data[1];
//右移4位并乘以分辨率
return (raw_temp >> 4) * 0.0625f;
//打印OK
}
else
{
//打印失败
return -999.0f;
}
}
/**
* @brief读取远程温度
* @retval远程温度值
*/
float NST461_ReadRemoteTemperature(void)
{
uint8_t temp_data[2] = {0};
int16_t raw_temp = 0;
HAL_StatusTypeDef status;
//读取远程温度高字节
status = HAL_I2C_Mem_Read(&hi2c1,
NST461_ADDR_READ,
REG_REMOTE_TEMP_H,
I2C_MEMADD_SIZE_8BIT,
&temp_data[0],
1,
HAL_MAX_DELAY);
//读取远程温度低字节(寄存器地址0x10)
status = HAL_I2C_Mem_Read(&hi2c1,
NST461_ADDR_READ,
0x10, //远程温度低字节地址
I2C_MEMADD_SIZE_8BIT,
&temp_data[1],
1,
HAL_MAX_DELAY);
if(status == HAL_OK)
{
//打印OK
raw_temp = (temp_data[0] << 8) | temp_data[1];
return (raw_temp >> 4) * 0.0625f;
}
else
{
//打印失败
return (int8_t)temp_data[0];
}
}
/**
* @brief简洁版温度打印(仅数值)
* @param data:温度数据结构体指针
*/
void PrintTemperatureSimple(const TempData_t *data)
{
char buffer[128];
//清空缓冲区
memset(buffer, 0, sizeof(buffer));
//格式化温度数据
snprintf(buffer, sizeof(buffer),
"temp:%.3f,%.3f\r\n",
data->local_temp,
data->remote_temp);
HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
}
//MAIN函数中添加:
unsigned char ch[20] = {0};
uint8_t tmp=1;
TempData_t temp_data;
while (1){
//读取本地温度
temp_data.local_temp=NST461_ReadLocalTemperatureFull();
//读取远程温度
temp_data.remote_temp=NST461_ReadRemoteTemperature();
PrintTemperatureSimple(&temp_data);
HAL_Delay(500);
}
3 成果展示
3.1 实物照片
接线如下:
最小系统板-------PCB近端板
3.3V---------------3.3V
GND---------------GND
PB7-----------------SDA
PB6-----------------SCL
最小系统板-------USB-TTL模块
3.3V---------------3.3V
GND------------ -GND
RXD---------------PA2
TXD---------------PA3
PCB近端-------------PCB远端(NPN传感器)
D+---------------------D-
D—---------------------D+
GND-----------------GND
PCB近端-----------------12指神探(这里忘了留接口,就飞线了)
GND-----------------------GND
IO21------------------------SDA
IO20------------------------SCL

PCB图片


3.2 上位机数据展示
STM32通过I2C读取到NST461-DQNR的数据后,进行处理,并通过串口2进行发送。串口接收数据即可在电脑或其它上位机上展示传感器数据,下图为PC端使用VOFA+展示温度数据曲线图:
可以看到本地温度为18.63°,远程温度为36.25°。温度的变化趋势是正确的,但是远程温度有点不准,可能与三极管的特性有关。

3.3 十二指神探查看I2C数据
采用12指神探我们可以查看STM32和NST461-DQNR通讯时的I2C协议。具体接法如上,但是记得接地,不然一直显示高电平。

4 总结
遇到的问题:
1. NST461-DQNR采用QFN封装比较难焊接,而且不好进行检查。可以现在芯片引脚上上锡然后再焊接到PCB上。
2. NST461-DQNR测量外部温度的三极管可以采用PNP和NPN,但是接法不一样。如果远程温度有问题可以D+和D-反接试试。
3. I2C看波形没有留引脚,只能飞线了,以后测试接口记得留测试点。
4. ST461-DQNR的A1和A0时I2C的地址选择位,为了灵活配置地址,可以采用跳线帽。这里我用的是0欧姆的电阻。
5. 读数据的时候可以用手碰碰芯片,看温度变化不。
6. NST461-DQNR在同一个环境下读取的本地温度和远程温度差别很大,但是温度趋势是正确的,所以真正应用于产品的时候,需要进行温度校准。
7. 12指神探的BOOT模式需要按住按键启动,才能进入U盘模式。
8. 12指神探屏幕不亮可能与Uf2文件有关。
9. 12指神探采集I2C数据时,采样率不能太低,不然采集到的数据不准确。采样数据和采样频率应该同步提高。
10. 当主程序设置有延时,I2C波形不是一直有,所以没数据的时候多采几次,或者加大采样数据。
5 心得体会
通过这个NST461温度采集项目,我深刻体会到硬件设计与调试经验的重要性。焊接QFN封装、预留测试点这些看似简单的细节,实际中却直接影响项目成败。I2C通信的稳定性需要合适的采样率和时序配合,而传感器读数虽然趋势正确但仍需校准才能满足精度要求。
这次项目让我明白,从原理到产品需要跨越的不仅是代码编写,更是对硬件特性的深入理解和实际问题解决能力。工具使用也很关键,无论是12指神探的采样设置还是VOFA+的数据可视化,都需要耐心调试才能发挥最佳效果。
最大的收获是:好的设计需要预留调试空间,可靠的产品离不开细致的校准验证。这为后续项目积累了宝贵的实战经验。
最后,感谢硬禾学堂推出的《WeDesign》活动!此次活动带给我许多宝贵实践经验和机会!
6 参考资料
https://www.eetree.cn/project/detail/748
https://www.eetree.cn/task/908
https://www.eetree.cn/project/detail/3624
https://www.eetree.cn/project/detail/3625

