温度传感器NST175手册阅读
首先看芯片的输入和输出:主要关注IIC接口,毕竟是要驱动这个芯片读取温度。在编写此博客时还未对改温度传感器进行调试,只是阅读手册,把需要重点关注的地方标记出来。
一、芯片管脚
二、温度输出格式
接下来查看它的寄存器配置,翻译手册:
每个温度测量转换的数字输出存储在只读温度寄存器中。NST175的温度寄存器是一个12位的只读寄存器,它存储了最新转换的输出。必须读取两个字节才能获得数据,并列于表4.5和表4.6中。前12位用于表示温度,所有剩余的位都等于零。温度的数据格式列于表4.1中。负数用二进制补码(2‘s comlement)格式表示。在通电或重位后,温度寄存器读取0°C,直到第一次转换完成.
用户可以通过寻址配置寄存器并相应地设置分辨率位,来获得9、10、11或12位的分辨率。对于9位、10位或11位的分辨率,将使用温度寄存器中的最有效位(MSBs),并将未使用的最小有效位(LSBs)设置为零。
NST175支持快速(最多400 kHz)和高速(最多2 MHz)模式的传输协议。所有的数据字节首先被传输到MSB上。
温度输出格式:
三、NST175设备地址:
要与NST175通信,主必须首先通过从地址字节为从设备地址。从地址字节由七个地址位和一个指示执行读或写操作的意图的方向位组成。NST175具有三个地址引脚,允许在一个总线接口上对多达27个设备进行寻址。表4.2描述了用于正确连接多达27个设备的引脚逻辑电平。A1表示脚连接到电源(VDD);0表示脚连接到GND;float表示脚未连接。引脚A0、A1和A2的状态在每条总线通信上进行采样,并且必须在接口上的任何活动之前进行设置。
硬件配置A2 A1 A0 = 0 Float 1,所以器件地址是:0101001,一共7bit。还有1bit是读写位,读为1写为0,所以器件地址加上读写位一共8bit,值为0101_0011=0x53表示FPGA对NST175进行读操作;值为0101_0010=0x52表示FPGA对NST175进行写操作;
四、NST175读写寄存器操作
寄存器字节首先被发送到MSB,然后是LSB。即先写高位。
写时序:
**读时序:**读时序需要写入两次IIC设备地址,第一次写入是为了改变指针寄存器里面的值,从而访问需要访问的寄存器,这个操作是往IIC设备里面写,读写标志位应该为0(写);第二次的IIC设备地址,读写标志位应该设置为读(1),后面2byte数据是IIC设备返还给FPGA的数据,这些数据是从寄存器读出的。
1)指针寄存器:
指针寄存器用于指向访问的寄存器
寄存器对应的地址如图:
温度寄存器:0000_0000 = 0x00
配置寄存器:0000_0001 = 0x01
低温限制寄存器:0000_0010 = 0x02
高温限制寄存器:0000_0011 = 0x03
产品ID寄存器:0000_0111 = 0x07
2)温度寄存器:
NST175的温度寄存器是一个12位的只读寄存器,它存储了最新转换的输出。必须读取两个字节才能获得数据,如表4.5和表4.6所示。字节1是最重要的字节,其次是字节2,即最不重要的字节。前12位用于指示温度,所有剩余的位等于零。如果不需要该信息,则不必读取最小的字节。在通电或重置值之后,温度寄存器读取0°C,直到第一次转换完成。
3)配置寄存器:
配置寄存器是一个8位的读/写寄存器,用于存储控制温度传感器的工作模式的位。读取和写操作首先执行MSB。NST175的配置寄存器的格式如表4.7所示,然后是寄存器位的分解。配置寄存器的通电或复位值均为等于0的位(上电后全部位置为0)。
-
SD:配置关闭模式
NST175的关闭模式允许用户通过关闭除串行接口以外的所有设备电路来节省最大功率,这将电流消耗减少到通常小于0.1 μA。当SD位为1时,启用关闭模式;当当前转换完成时,设备关闭。当SD等于0时,设备保持连续转换状态。
SD=1:关闭模式 SD=0:连续模式
-
TM:温度控制模式
NST175的温控器模式位向设备指示是在比较器模式(TM = 0)还是在中断模式(TM = 1)下运行。有关比较器和中断模式的更多信息,请参阅上限和下限寄存器部分。
TM=0:比较模式 TM=1:中断模式
-
POL:极性配置
NST175的极性位允许用户调整警报引脚输出的极性。如果POL位设置为0(默认值),则警报销将变为活动低。当POL位设置为1时,警报销变高,警报销的状态反转。警报销在各种模式下的操作如图4.8所示。
POL=0:测量温度超过高温限制寄存器的值时,警报引脚输出0
POL=1:测量温度超过高温限制寄存器的值时,警报引脚输出1
- F1/F2:故障队列
故障条件定义为当测量的温度超过用户在Thigh和Tlow寄存器中设置的自定义限制时。此外,还可以使用故障队列对生成警报所需的故障条件数进行编程。提供故障队列是为了防止由于环境噪声而产生的错误警报。故障队列需要连续的故障测量,以触发警报功能。表4.8定义了可编程在设备中触发警报条件的测量故障数量。有关Thigh和TLOW寄存器格式和字节顺序,请参阅“上限和下限寄存器”部分
F1 F2=0 0:测量1次
F1 F2=0 1:连续测量2次
F1 F2=1 0:连续测量4次
F1 F2=1 1:连续测量6次
- R1/R0:转换器分辨率
转换器分辨率位控制内部ADC转换器的分辨率。这种控制允许用户通过编程更高分辨率或更快的转换时间来最大化效率。表4.9确定了分辨率位以及分辨率与转换时间之间的关系
R1 R2 = 0 0:分辨率为9bit,0.5℃
R1 R2 = 0 1:分辨率为10bit,0.25℃
R1 R2 = 1 0:分辨率为11bit,0.125℃
R1 R2 = 1 1:分辨率为12bit,0.0.0625℃
-
OS:一次性测量模式
NST175采用了一次性的温度测量模式。当设备处于关闭模式时,向OS位写入一个1将开始一次温度转换。在单次转换完成后,设备返回到关机状态。当不需要连续的温度监测时,此特性有助于降低NST175的功耗。当读取配置寄存器时,OS总是读取为零。
要和关闭模式搭配使用 OS = 1:关闭模式下,往OS位写入1,就开始单次温度转换,转换完毕之后,NST175进入关机在状态
配置寄存器配置的值:
config[7:0]=8'b0111_0011;//0x73,配置为连续转换模式、比较模式、极性POL=0、故障队列为01--连续测量2次、分辨率设置我i12bit、OS=0
4)高低温限制寄存器
在比较器模式(TM = 0)中,当温度等于或超过Thigh上的值时,NST175的警报销被激活,并根据故障位F1和F0产生连续数量的故障数。对于相同数量的故障,直到温度低于指示的TLOW值时,警报销将保持激活值。在中断模式(TM = 1)中,当温度等于或超过Thigh时,警报针将处于激活状态。在发生任何寄存器的读取操作,或设备成功响应SMBus警报响应地址之前,警报销一直保持活动状态。如果设备处于关闭模式,警报销也会被清除。当警报销被清除时,它只有在温度低于TLOW时才会再次被激活。当温度降至低于TLOW时,警报销将被激活并保持激活,直到被任何寄存器的读取操作或对SMBus警报响应地址的成功响应清除。当警报销被清除时,上述循环重复,当温度等于或超过Thigh时,警报销被激活。此外,还可以通过使用常规呼叫重置命令重置设备来清除警报销。此操作还可以通过将设备返回到比较器模式(TM = 0)来清除设备中的内部寄存器的状态。
这两种操作模式都如图4.8所示。表4.10、表4.11、表4.12和表4.13描述了Thigh和TLOW寄存器的格式。首先发送最重要的字节,然后是最不重要的字节。Thigh和TLOW的通电复位值为:THIGH = 80°C and TLOW = 75°C
Thigh和TLOW的数据格式与温度寄存器相同。
温度、Thigh和TLOW寄存器的所有12位都用于所有转换器分辨率的警报功能的比较。即使转换器配置为9位分辨率,Thigh和TLOW中的三个LSB也会影响警报输出。
5)产品ID寄存器: PRODID: Product ID Register (Read-Only) Pointer Address: 07h
网上前辈写的代码可以借鉴,是用c来写的,如果是Nios配置的话可以参考:
#include "STC15Fxxxx.H"
//#include "oled.h"
/************* 本地常量声明 **************/
#define MAIN_Fosc 11059200L //定义主时钟
#define BaudRate1 9600UL //选择波特率
#define Timer1_Reload (65536UL -(MAIN_Fosc / 4 / BaudRate1)) //Timer 1 重装值, 对应300KHZ
#define Timer2_Reload (65536UL -(MAIN_Fosc / 4 / BaudRate1)) //Timer 2 重装值, 对应300KHZ
#define uchar unsigned char
#define uint unsigned int
#define Slave_Id 0x90Slave_Id,芯片地址IO配置,对应关系请查询Spec
#define Temp_Reg 0x00温度数值寄存器,深度为2byte
#define Conf_Reg 0x01配置寄存器,深度为1byte
sbit OLED_SCL = P3^2;//时钟 D0(SCLK?
sbit OLED_SDIN = P3^3;//D1(MOSI) 数据
sbit Alert = P5^4;
sbit Alert_Led =P5^5;
#define SCLK_Clr() OLED_SCL=0
#define SCLK_Set() OLED_SCL=1
#define SDIN_Clr() OLED_SDIN=0
#define SDIN_Set() OLED_SDIN=1
#define Alert_Led_On() Alert_Led=0
#define Alert_Led_Off() Alert_Led=1
/************* 本地变量声明 **************/
unsigned char T_flag = 0;
unsigned char Temp_H = 0,Temp_L = 0; //TL:底八位 TH:高八位
bit B_TX1_Busy; //发送忙标志
/*****************************************************
//延时1us
******************************************************/
void delayus(uint i)
{
while(i--);
}
/*****************************************************
//延时1ms
******************************************************/
void delayms(uint ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ; //14T per loop
}while(--ms);
}
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
SCLK_Set() ;
SDIN_Set();
SDIN_Clr();
SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
SCLK_Set() ;
SDIN_Clr();
SDIN_Set();
}
/**********************************************
//IIC Master Ack
**********************************************/
void IIC_Ack()
{
SCLK_Clr();
SDIN_Clr();
delayus(5); //delay 5uS
SCLK_Set();
}
/**********************************************
//IIC Wait Slave Ack
**********************************************/
void IIC_Wait_Ack()
{
SCLK_Set() ;
SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
m=m&0x80;
if(m==0x80)
{SDIN_Set();}
else
{SDIN_Clr(); }
da=da<<1;
SCLK_Set();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK_Clr();
}
}
/**********************************************
// IIC Write byte
**********************************************/
unsigned char Read_IIC_Byte()
{
unsigned char i;
unsigned int da = 0;
SCLK_Clr();
_nop_();
_nop_();
_nop_();
SDIN_Set();
for(i=0;i<8;i++) //8
{
da=da<<1 ;
SCLK_Set();
//delayus(5);
if(OLED_SDIN == 1)
{da++;}
SCLK_Clr();
}
IIC_Ack();
return da;
}
void SendData(char dat)
{
if(!B_TX1_Busy) //发送空闲
{
B_TX1_Busy = 1; //标志发送忙
SBUF = dat; //发一个字节
while(!TI);
TI = 0;
ES = 1;
}
}
void Uart_Init()
{
B_TX1_Busy = 0;
P3M0 = 0xff;
P3M1 = 0xff;
S1_8bit(); //8位数据
S1_USE_P30P31(); //UART1 使用P30 P31口 默认
AUXR &= ~(1 << 4); //Timer stop 波特率使用Timer2产生
AUXR |= 0x01; //S1 BRT Use Timer2;
AUXR |= (1 << 2); //Timer2 set as 1T mode
TH2 = (u8)(Timer2_Reload >> 8);
TL2 = (u8)Timer2_Reload;
AUXR |= (1 << 4); //Timer run enable
delayms(100);
REN = 1; //允许接收
ES = 1; //允许中断
INT1 = 1;
IT1 = 1;
EA = 1; //允许全局中断
EX1 = 0;
}
void read_temp()
{
unsigned int Data = 0;
IIC_Start();
Write_IIC_Byte(Slave_Id); //Slave address,SA0=0 90
IIC_Wait_Ack();
Write_IIC_Byte(Temp_Reg); //write command
IIC_Wait_Ack();
IIC_Stop();
delayms(50);//等待温度准换完成,连续温度转换模式,此句可忽略。
IIC_Start();
Write_IIC_Byte((Slave_Id+1); //Slave address,SA0=0 91
IIC_Wait_Ack();
Temp_H = Read_IIC_Byte(); // MSB
IIC_Ack();
Temp_L = Read_IIC_Byte(); //LSB
//IIC_Ack();
IIC_Stop();
if(Temp_H>127)//温度为负值
{
T_flag = 0;
Data = Temp_H*256 + Temp_L;
Data >>= 4;
Data=~Data;
Data++;
Data <<= 4;
Temp_H = Data/256;
Temp_L = Data%256;
}
else
{
T_flag = 1;
Temp_L >>= 4;
Temp_L <<= 4;
}
}
void Temp_Init()
{
IIC_Start(); //先
Write_IIC_Byte(Slave_Id); //0x90 Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(Conf_Reg); //0x01 配置寄存器 write command
IIC_Wait_Ack();
Write_IIC_Byte(0x60); // 分辨率最高
IIC_Wait_Ack();
IIC_Stop();
}
void main(void)
{
Uart_Init();//配置串口
Temp_Init();//配置最高12bit分辨率,0.0625℃.如不需要配置,此行可忽略。default分辨率是9bit,0.5℃
while (1)
{
read_temp();//读取温度数据
//读取 Temp_H Temp_L 的温度数据; 实际温度数值 = (Temp_H*256+Temp_L)/256,Temp_H和Temp_L 需要转为十进制。
Temp_H=0;
Temp_L=0;
delayms(5);
}
}
/********************* UART1中断函数************************/
void UART1_int (void) interrupt UART1_VECTOR
{
if(RI)
{
RI = 0;
//RX1_Buffer[0] = SBUF; //保存一个字节
}
if(TI)
{
TI = 0;
B_TX1_Busy = 0; //清除发送忙标志
}
}
--晓凡 2024年6月18日于武汉书