用NST461-DQNR基于纳芯微评估版设计的温度传感器
一、项目介绍
本项目是使用NST461-DQNR 芯片与纳芯微NS800RT5039评估版搭配十二指针神探设计的一个温度传感器,原理图与PCB绘制均采用KiCad绘制。本项目主要功能包括:读取本地温度和远程温度,串口输出数据,并在串口软件完成温度曲线图绘制.
(二)项目目标
完成基于纳芯微评估版与 NST461-DQNR 模块的硬件系统设计,包括原理图绘制、PCB 布局与制版。
实现目标模拟信号温度的高精度采集,采集精度高。
完成信号的调理、滤波及数字化处理,通过纳芯微芯片的功能实现信号的放大、降噪与传输。
搭建系统测试平台,验证硬件系统的稳定性、可靠性及功能完整性,确保系统在不同工作环境下正常运行。
二、芯片选型
(一)核心芯片选型:纳芯微 NS800RT5095
选型依据:
高频控制性能匹配:项目需生成 2MHz 互补 PWM 波形,NS800RT5095 作为纳芯微实时控制 MCU 系列核心型号,具备皮秒级 PWM 控制精度,其集成的 16 对互补 PWM 外设支持高频信号生成,且硬件死区控制单元可直接解决高频切换时的导通重叠问题,完美适配项目对 PWM 频率与可靠性的需求。
高精度采集能力适配:针对 RC 滤波后电压的精准采集需求,芯片配备 3 个 12 位 5MSPS ADC 模块(INL/DNL±1.5LSB),支持 1.6V 高精度参考电压配置,可实现低电压信号的高分辨率采集,与项目中 “万用表 + ADC 双验证” 的设计思路高度契合。
DSP 算力支撑:音频频谱分析需高效 FFT 运算,芯片内置 eMath 硬件数学加速核,可大幅提升数字信号处理效率,为麦克风采集信号的实时频谱转换提供算力保障,避免因软件运算延迟导致的律动显示卡顿。
硬件设计适配性:芯片采用工业级封装,支持 3.3V 宽压供电,外设接口布局合理,便于自主 PCB 设计时的模拟 / 数字模块分区布线,且兼容 Keil MDK 开发环境,降低软件开发门槛。
(二)NST461-DQNR 模块适配性分析
NST461-DQNR 模块支持数字信号输出(I2C),其工作电压为 3.3V,与纳芯微 NS800RT5095的工作电压范围完全匹配。模块的信号输入接口可直接与 NS800RT5095的输入端连接,数字信号输出接口可通过I2C 总线与微控制器(选用 NS800RT5095)通信,实现数据的实时传输与处理,二者在硬件接口、通信协议等方面具有良好的适配性。
三、原理图绘制
(一)绘制工具
采用 kicad作为原理图绘制工具,该软件功能强大,支持复杂电路设计、器件库管理、等功能,能够有效提高原理图设计效率与准确性。
(二)原理图整体架构
微控制模块:以 NS800RT5095为核心,通过 iic接口接收 NST461-DQNR 模块传输的数据,进行数据解析、校准与存储。
通信模块:NS800RT5095通过 USART 接口传输至上位机,实现数据的实时显示与分析。

(三)关键设计要点
我们根据温度传感器的核心原理:半导体 PN 结在恒定电流下,正向压降(Vbe)会随温度升高线性下降。传感器向 PN 结通精确恒定小电流,测量对应 Vbe 电压,再通过 Vbe 与温度的已知线性关系,精准反推目标温度。
四、PCB 与制版
(一)PCB 设计参数
板层设置:采用双层 PCB 设计,顶层(Top Layer)用于放置元器件、信号走线,底层(Bottom Layer)用于电源走线、接地平面,提高散热性能与抗干扰能力。
板材选择:厚度 1.6mm,具有良好的机械性能、电气性能与成本优势,适用于常规电子设备。
铜箔厚度:采用 1oz 铜箔,满足系统电流传输需求,降低线路损耗。
设计规则:线宽最小设置为 0.8mm(电源线路)、0.4mm(信号线路);线间距最小设置为 0.4mm;过孔直径设置为 1.0mm(孔径 0.6mm),便于插件焊接。
(二)PCB 布局与布线
布局原则:遵循 “就近布局、功能分区” 原则,将电源模块、信号采集模块、核心模块、通信模块分别集中布局,缩短信号传输路径,减少干扰。
(三)PCB板


(四)板子实物图


(五)设计框图

五、开发中遇到的问题
(一)信号采集精度不足
问题现象:通过上位机读取的远程数据与本地温度数据差距较大。
原因分析:远程温度检测是使用8050三极管,本身温漂较大,阻值不匹配
解决方案:更换线性较好的三极管或者使用稳定的PN节,搭配反馈电路
(二)NST461-DQNR 模块与微控制器通信失败
问题现象:STM32F103C8T6 微控制器通过 iic无法读取 NST461-DQNR 模块的数字信号,iic通信中断。
原因分析:iic地址不对
解决方案:仔细阅读数据手册,查找正确的iic设备地址
(三)PCB 板焊接后短路
问题现象:PCB 板焊接完成后,通电测试发现电源模块短路,保险丝熔断。
原因分析:通过万用表测量排查,输出端与地之间短路,经检查是焊接过程中焊锡过多,导致芯片引脚与接地焊盘短路。
解决方案:使用吸锡器清除芯片引脚多余的焊锡,并用酒精清洗焊接区域;在焊接芯片时,控制电烙铁温度与焊接时间,避免焊锡流淌造成短路;焊接完成后,用万用表逐一测量电源线路与地之间的电阻,排查短路问题。
六、实现结果展示
(一)硬件实物展示

(二)功能测试结果


(三)项目达成目标
本项目基于纳芯微评估版与 NST461-DQNR 模块,成功设计并实现了一套高精度信号采集与处理系统。硬件系统满足设计要求,信号采集精度、稳定性、通信性能均达到预期目标,可广泛应用于工业控制、智能监测等场景,为后续相关产品的研发提供了可靠的硬件平台与技术参考。
七、关键代码及说明// NST461 初始化函数
uint8_t NST461_Init(I2C_TypeDef *i2c, uint8_t devAddr)
{
uint8_t config_data[2];
uint8_t status;
// 1. 配置转换速率(可选,默认是16次/秒)
config_data[0] = 0x0A; // 转换速率寄存器地址
config_data[1] = 0x08; // 默认值,16次/秒
status = I2C_WriteDataRaw(i2c, devAddr, config_data, 2);
if (status != 0) return status;
// 2. 配置通道使能寄存器(确保本地温度测量使能)
config_data[0] = 0x16; // 通道使能寄存器地址
config_data[1] = 0x03; // 默认值,本地和远程通道都使能 (bit0=LEN, bit1=REN)
status = I2C_WriteDataRaw(i2c, devAddr, config_data, 2);
if (status != 0) return status;
// 3. 配置工作模式(确保在连续转换模式)
config_data[0] = 0x09; // 配置寄存器地址
config_data[1] = 0x00; // 默认值,连续转换模式,ALERT功能
status = I2C_WriteDataRaw(i2c, devAddr, config_data, 2);
if (status != 0) return status;
return 0; // 初始化成功
}
/**
* @brief Main function
* @return int Force return 0
*/
// 完整的本地温度读取函数
float read_local_temperature_complete(I2C_TypeDef *i2c, uint8_t devAddr)
{
uint8_t temp_high, temp_low;
//uint8_t config_reg;
float temperature;
// // 首先检查配置寄存器,确保设备在正确模式
// if (I2C_ReadData(i2c, devAddr|0X01, 0x09, &config_reg, 1) != 0) {
// return -999.0f; // 读取配置失败
// }
//
// // 检查是否在关机模式 (bit6 = 1 表示关机模式)
// if (config_reg & 0x40) {
// // 如果在关机模式,切换到连续模式
// uint8_t wakeup_cmd[2] = {0x09, config_reg & 0xBF}; // 清除bit6
// I2C_WriteDataRaw(i2c, devAddr, wakeup_cmd, 2);
//
// // 等待转换完成
// // 本地转换时间约14ms,远程约12ms
// // 这里可以添加适当的延时
// // HAL_Delay(15);
// }
// 读取本地温度高字节
if (I2C_ReadData(i2c, devAddr|0X01, 0x00, &temp_high, 1) != 0) {
return -999.0f;
}
// 读取本地温度低字节
if (I2C_ReadData(i2c, devAddr|0X01, 0x15, &temp_low, 1) != 0) {
return -999.0f;
}
// 解析温度值
int8_t temp_int = (int8_t)temp_high;
float temp_frac = (temp_low >> 4) * 0.0625f;
temperature = temp_int + temp_frac;
return temperature;
}
// 读取状态寄存器函数
uint8_t read_status_register(I2C_TypeDef *i2c, uint8_t devAddr)
{
uint8_t status_reg;
if (I2C_ReadData(i2c, devAddr|0X01, 0x02, &status_reg, 1) != 0) {
return 0xFF; // 读取失败
}
return status_reg;
}
// 打印状态寄存器信息
void print_status_info(uint8_t status_reg)
{
printf("Status Register: 0x%02X\n", status_reg);
if (status_reg & 0x04) {
printf(" - Diode Fault Detected (OPEN bit set)\n");
}
if (status_reg & 0x08) {
printf(" - Remote Low Limit Exceeded\n");
}
if (status_reg & 0x10) {
printf(" - Remote High Limit Exceeded\n");
}
if (status_reg & 0x20) {
printf(" - Local Low Limit Exceeded\n");
}
if (status_reg & 0x40) {
printf(" - Local High Limit Exceeded\n");
}
if (status_reg & 0x80) {
printf(" - ADC Busy\n");
}
}
// 改进的远程温度读取函数,包含诊断信息
float read_remote_temperature_diagnostic(I2C_TypeDef *i2c, uint8_t devAddr)
{
uint8_t temp_high, temp_low;
//uint8_t config_reg, status_reg;
float temperature;
//
// // 读取状态寄存器
// status_reg = read_status_register(i2c, devAddr);
// if (status_reg == 0xFF) {
// printf("Error: Cannot read status register\n");
// return -999.0f;
// }
//
// // 检查二极管故障
// if (status_reg & 0x04) {
// printf("Warning: Diode fault detected! Check remote sensor connection.\n");
// print_status_info(status_reg);
// }
//
// // 检查配置寄存器
// if (I2C_ReadData(i2c, devAddr|0X01, 0x09, &config_reg, 1) != 0) {
// return -999.0f;
// }
//
// // 检查是否在关机模式
// if (config_reg & 0x40) {
// uint8_t wakeup_cmd[2] = {0x09, config_reg & 0xBF};
// I2C_WriteDataRaw(i2c, devAddr, wakeup_cmd, 2);
// Delay_ms(15);
// }
// 读取远程温度高字节
if (I2C_ReadData(i2c, devAddr|0X01, 0x01, &temp_high, 1) != 0) {
return -999.0f;
}
// 读取远程温度低字节
if (I2C_ReadData(i2c, devAddr|0X01, 0x10, &temp_low, 1) != 0) {
return -999.0f;
}
//printf("Remote Temp Raw: High=0x%02X, Low=0x%02X\n", temp_high, temp_low);
// 解析温度值
int8_t temp_int = (int8_t)temp_high;
float temp_frac = (temp_low >> 4) * 0.0625f;
temperature = temp_int + temp_frac;
return temperature;
}
int main(void)
{
/* Initialize device clock and peripherals */
Device_init();
/* Disable peripheral register locks */
Device_unlockPeriphReg();
/* Board Initialization
Setup LED pins, Key pins and Serial Communication Interface pins
*/
Board_init();
/* LED4 & LED5 on */
GPIO_clearPin(BOARD_LED4_PIN);
GPIO_clearPin(BOARD_LED5_PIN);
/* Debug information printing */
printf("Gpio example 1 setup start!\n");
//OLED_Init();
//OLED_Clear();
//char shuzhu[20];
i2c_init(I2C1);
Delay_ms(100);
// sprintf(shuzhu,"adcrg");
// OLED_ShowString(1,1,shuzhu);
// OLED_ShowString(2,1,shuzhu);
/* Loop indefinitely */
NST461_Init(I2C1,0X9C);
Delay_ms(100);
while(1)
{
//wd_Read();
double wd,wd1;
wd=read_local_temperature_complete(I2C1,0X9C);
wd1=read_remote_temperature_diagnostic(I2C1,0X9C);
printf("wd:%.2f,%.2f\n\r",wd,wd1);
//printf("wd:%.2f,wd1:%.2f\n\r",wd,wd1);
// printf("wd:%.2f\n\r",wd);
// printf("wd1:%.2f\n\r",wd1);
GPIO_clearPin(BOARD_LED4_PIN);
GPIO_clearPin(BOARD_LED5_PIN);
Delay_ms(100);
GPIO_setPin(BOARD_LED4_PIN);
GPIO_setPin(BOARD_LED5_PIN);
Delay_ms(100);
}
}
main.c中包含NST461的初始化,本地温度及远程温度的读取及运算。