1、高精度双引脚数字脉冲输出型温度传感器;
2、测温范围为-50°C到150°C,高分辨率可达0.0625℃;
3、全温域内保持高精度:
25℃ ~ 45℃:±0.2℃(典型)
-20℃ ~ 85℃:±0.5℃(最大)
-50℃ ~ 150℃:±0.75℃(最大);
4、脉冲型数字输出,无需AD转换接口;
单次温度转换时间50ms;
转换电流仅30uA,零待机功耗;
宽供电范围:1.65V ~ 5.5V;
脉冲范围:1~3201;
传感器包括振荡器、温度模数转换器、信号调制电路和控制接口,同时包含一个OTP,每个芯片都经过出厂温度校准。NST1001有两个引脚,DO和GND,其中的电源和信号输出是通过DO引脚完成。NST1001可以从上拉电阻获得电力和执行温度转换。
上拉电阻R1可以直接接到MCU的VDD,也可以通过一个单独的GPIO为NST1001供电,以便不用时关掉其供电来节省功耗。有些MCU的GPIO自带有可配置的上拉电阻,也可以替代外部电阻R1。为了提高对外部的抗干扰能力,可以考虑在NST1001处增加电容C1。
下拉电阻接法,类似于常见的NTC温度采集方案。
此方案中的所有NST1001节点共享GP1O0作为DO计数端口,并共享相同的上拉电阻。通过将GPI01GPIOn中的一个拉低使能待采集的温度节点,将其他未使用的节点对应的GPI0设置为高阻状态。注意两个以上的GPI01GPlOn不能同时拉低。
将数字隔离芯片一起用于需要隔离以进行温度采集的应用。
上拉或下拉电阻R1的取值可以选取500欧姆到10K欧姆之间的值,具体取值需要考虑到最小工作电压,功耗和传输距离。由于NST1001进行温度转换时有最大可达45uA的电流,因此R1越小,在其上的压降就越小,给到芯片的供电电压就越高。VDD的最小值可以用公式估算:VDD > 1.45 + 45 * R1 * 0.000001;
另一方面,温度数据发送时的功耗随着电阻的减小而变大,因此为了最小功耗,需要尽量采用更大的电阻。而在有些需要长距离传输的情况下,考虑到寄生电容的数据传输的影响,为了保证温度脉冲信号可以正常发送,电阻R1不能取得太大。
在上拉模式中,由于DQ引脚开关电阻仅为50欧姆左右,输出拉低速度一般较快,传输能力主要受限于输出由低变高时的速度,输出从低拉高到95%稳态值的时间TLH可用公式:TLH = 3 * R1 * ( C1 + Cpar);其中C1为外部滤波电容,Cpar为线束对地的寄生电容,TLH需要小于DQ高脉冲最短时间4us。假设R1为5.1k,不考虑Cpar,则C1不能大于261pF。
NST1001单次温度周期约为50ms,NST1001上电后立即进入温度数据转换期,数据转换期典型值为24ms。之后进入脉冲通信期,输出温度脉冲数,最少1个脉冲,最多3201个脉冲。在单个脉冲周期内,总时长为8us,占空比为75%,即高电平持续时间约为6us,低电平持续时间约为2us,一次转换和输出脉冲的过程如下图:
NST1001周期进行温度转换和温度数据发送,为方便部分客户使用单次温度转换模式,第二次温度转换后无数据输出,在第三次以及后面的数据传输恢复正常;
温度计算方程为:Temp = Num * 0.0625 - 50.0625 (℃),其中Temp是温度值(-50℃ ~ 150℃),Num是脉冲个数(1 ~ 3201个);
脉冲个数 | 温度数值 |
---|---|
1 | -50 |
161 | -40 |
481 | -20 |
801 | 0 |
1281 | 30 |
1601 | 50 |
2401 | 100 |
3201 | 150 |
为了获得更好的温度精度,消除高低温之间的非线性温差,给出了分段温度计算公式
T = Temp + (Temp - 30) × 0.005 Temp < 30℃
T = Temp 30℃ ≤ Temp ≤ 100℃
T = Temp + (100 - Temp) × 0.012 100℃ < Temp < 150℃
//辅助程序 1,定义用到的变量
unsigned int Count = 0; //定义计数值变量COUNT
bit Flag = 0; //定义中断服务标志位C_FLAG;
sbit DQ = P3^3; //定义IO引脚
//辅助程序 2,中断子函数
void exint1() interrupt 2
{
_nop_();
_nop_();
If (DQ == 0) //误触发判断
{
Count++; //计数+1
Flag = 1; //中断标志Flag
}
}
//辅助程序 3,延时子函数
void Delay2ms()
{
for( i=0; i<xxxx; i++) {;} //时钟周期延时10ms,根据MCU指令周期设计具体的xxxx值
}
//主程序
void main(void) //主程序 main
{
unsigned int Data = 0;
unsigned float Temp = 0;
INT1 = 1; // 中断IO口初始状态为High
IT1 = 1; // 外中断信号方式控制位,1:下降沿中断。单脉冲周期触发一次
EX1 = 1; // 外部中断1允许控制位
EA = 1; // 中断允许总控制位
Count = 0; //计数值清零
while (1)
{
if( Flag == 1)
{
Flag = 0;
Delay2ms();
if(!Flag)
{
EX1 = 0; //关闭外部中断
Data = Count; //锁存计数值
Count = 0;
if(Data >= 801) //正负温度判断
{
Temp = (Data - 801)*0.0625;
} //正温度
else
{
Temp = (801 - Data)*0.0625;
} //负温度
Flag = 0;
EX1=1; //开启外部中断
} //END if(!Flag)
} //END if(Flag == 1)
} //END while 循环
}
//辅助程序 1,定义用到的变量
#define Temp_IN 2
long count = 0, DATA = 0;
char flag = 0;
long TEMP = 0;
//辅助程序 2,中断子函数
void blink() //外部中断函数blink()
{
if(flag == 1) //第一次外部中断
{
flag = 0;//清除第一次外部中断标志
count++;
FlexiTimer2::start();//开启定时器
}
else
{
count++; //非第一次外部中断,均执行此行代码
}
}
void event() //定时器中断函数
{
pinMode(Temp_IN, INPUT); //关闭IO,NST1001 Closed
FlexiTimer2::stop(); //关闭定时器中断
DATA = count; //存储count 计数数值
count = 0; //清零
if(DATA >= 801) //正负温度判断
{
TEMP = (DATA - 801)*625;
} //正温度
else
{
TEMP = (801 -DATA)*625;
} //负温度
}
辅助程序 3,外部中断和定时器配置
void setup() //外部中断和定时器配置
{
FlexiTimer2::set(35,1.0/1000,event); //定时器配置,35mS中断一次
attachInterrupt (0, blink, FALLING); //外部中断,调用blink函数,下降沿触发
}
//主程序
void loop()
{
flag = 1; //标志置位
pinMode( Temp_IN, INPUT_PULLUP); //IO PULLUP,NST1001上电开启
}
void main(void)
{
setup();
//需要采集温度时,调用loop();函数,50ms后,TEMP变量即为实测温度数值
loop();
/*
用户其他执行代码
*/
}
驱动包含两个NST1001端口,通过上拉电阻接法实现,初始化时,channel为1将PD5配置为输入(PD4配置为输出低电平关闭),channel为2将PD4配置为输入(PD5配置为输出低电平关闭),channel为其他值(0)将PD5和PD4配置为输出低电平关闭;
/*******************************************************
*Function:GpioNst1001Set;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
void GpioNst1001Set(uint8_t channel)
{
}
在进行采样时读取端口电平状态;
/*******************************************************
*Function:GpioNst1001Set;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
uint8_t GpioNst1001Get(uint8_t channel)
{
}
进行数据初始化以及端口初始化;
/*******************************************************
*Function:Nst1001Init;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
void Nst1001Init(void)
{
}
通过状态的跳转进行数据读取;当前的MCU无法通过中断进行各个脉冲的捕获(脉冲频率为125kHz),因此通过While循环的方式读取;
/*******************************************************
*Function:Nst1001GetTemp;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
void Nst1001GetTemp(void)
{
}
通过将状态设置为INIT来启动一次数据采集,用于按照特定的频率进行温度采集;
/*******************************************************
*Function:Nst1001EnGetData;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
void Nst1001EnGetData(void)
{
}
将函数放在主循环中即可;
/*******************************************************
*Function:Nst1001Task;
*Description:
*Input:Null
*Output:Null
*Others:Null
*******************************************************/
void Nst1001Task(void)
{
}
使用示波器抓取的一个过程波形;
通过示波器抓取的脉冲信号波形;
示波器统计脉冲个数为1103;
软件计数个数为1103,与目标一致;