做毕设的时候有一个温度检测模块,为了降重没有用已经被用到可以称为泛滥的QT18B20和DS18B20,而是选择了相对少见的纳芯微高精度、双引脚数字脉冲输出温度传感器NST1001。
1.1 NST1001温度传感器主要参数
该温度传感器拥有两种封装,分别是TO-92S封装和DFN2L超小封装,如图1.1所示;两种封装的引脚功能表1.1所示。
图1.1 NST1001的两种封装
表1.1 NST1001TO-92S封装引脚功能
管脚名称 | 描述 | |
TO-92S封装 | DQ | 供电及数据输出引脚 |
NC | 悬空 | |
GND | 接地 | |
DFN2L超小封装 | DQ | 供电及数据输出引脚 |
GND | 接地或下拉电阻到地 |
NST1001的主要性能参数如下表1.2所示:
表1.2 NST1001主要性能参数
性能 | 参数 |
工作电压 工作电流 | 1.65V~5.5V 30uA |
接口方式 | 单线接口 |
工作温度 | -50℃~+150℃ |
单次温度转换时间 | 50ms |
1.2 NST1001温度传感器应用电路
NST1001温度传感器使用起来非常简单,不像其他传统的数字温度传感器在使用时还需要进行初始化和读、写操作,只需要在使用NST1001时的单次温度转换时间后接受其输出的数字脉冲信号并对脉冲进行计数,再将其转换为温度值即可。
如图1.2所示,该温度传感器的应用电路同样十分简单,在使用时只需要在DQ引脚和FPGA芯片管脚之间接上一个上拉电阻,GND管脚直接接地即可。如果想要降低外部电路对NST1001工作时的干扰,还可以在电路上加上一个滤波电容。
图1.2 NST1001应用电路图和输出波形图
NST1001的时序图如图1.3所示,只需要记录Tdata时期的下降沿个数就可以轻松获得温度数值。
图1.3 NST1001时序图
温度传感器读取温度代码如下:
module nst1001(
input clk ,
input rst_n ,
input i_temp ,
output [7:0] o_temp
);
parameter delay_time = 150000;
wire temp_neg;
reg [17:0] dly_3ms_cnt;
reg temp_cnt_start ;
reg temp_d1,temp_d2,temp_d3;
reg [11:0] temp_cnt;
reg [11:0] temp_cnt_cur;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
temp_d1 <= 0;
temp_d2 <= 0;
temp_d3 <= 0;
end
else begin
temp_d1 <= i_temp;
temp_d2 <= temp_d1;
temp_d3 <= temp_d2;
end
end
assign temp_neg = temp_d3 && ~temp_d2;
//空闲时dly_3ms_cnt的值不断自增,每隔3ms其值被置0,无下降沿temp_cnt一直为0,temp_cnt_cur不变(默认为0);
//温度转换完成后,每次出现下降沿后时dly_3ms_cnt值置为0,temp_cnt计下降沿个数;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
dly_3ms_cnt <= 0;
else if(temp_neg)
dly_3ms_cnt <= 0;
else if(temp_cnt_start)
dly_3ms_cnt <= 0;
else
dly_3ms_cnt <= dly_3ms_cnt + 1;
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
temp_cnt_start <= 0;
else if(dly_3ms_cnt == delay_time - 1)
temp_cnt_start <= 1;
else
temp_cnt_start <= 0;
end
//温度转换完成后,每次出现下降沿后时dly_3ms_cnt值置为0,temp_cnt计下降沿个数;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
temp_cnt <= 0;
else if(temp_neg)
temp_cnt <= temp_cnt + 1;
else if(temp_cnt_start)
temp_cnt <= 0;
end
//若3ms内无下降沿则温度转换完成,此时temp_cnt_start值为1,将dly_3ms_cnt值置为0且temp_cnt_cur此时取temp_cnt的值(下降沿个数);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
temp_cnt_cur <= 0;
else if(temp_cnt_start)begin
if((temp_cnt >0) && (temp_cnt < 3202))
temp_cnt_cur <= temp_cnt;
end
end
//temp = num*0.0625 - 50.0625; 0.0625 = 1/16;
//由temp = num*0.0625 - 50.0625可知将temp_cnt右移四位(/16或x0.0625)再-50就可以得到环境温度值。
assign o_temp = temp_cnt_cur[11:4] - 6'd50;
endmodule