AM2321介绍

AM2321湿敏电容数字温湿度模块是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个高精度测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在单片机中,传感器内部在检测信号的处理过程中要调用这些校准系数。标准单总线接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上。产品为3引线(单总线接口)连接方便。AM2321的响应时间约2S,这比一般的温湿度传感器的响应时间要快。

AM2321的传感器性能

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_数据

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_单总线_02

AM2321的单总线通信协议

SDA(数据引脚)用于微处理器与 AM2321之间的通讯和同步如下图所示, 采用单总线数据格式,一次传送40位数据,高位先出。具体通信时序如图3.5所示。

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_温湿度传感器 SpringBoot_03


温湿度传感器 SpringBoot 温湿度传感器 纳芯微_单片机_04


单总线具体通信时序:

用户主机(MCU)发送一次起始信号(把数据总线SDA拉低至少800μs)后,AM2321从休眠模式转换到高速模式。待主机开始信号结束后,AM2321发送响应信号,从数据总线SDA串行送出40Bit 的数据,先发送字节的高位;发送的数据依次为湿度高位、湿度低位、温度高位、温度低位、校验位,发送数据结束触发一次信息采集,采集结束传感器自动转入休眠模式,直到下一次通信来临。单总线具体通信时序如下图所示。

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_单总线_05

注:主机从AM2321读取的温湿度数据总是前一次的测量值,如两次测量间隔时间很长,请连续读两次以第二次获得的值为实时温湿度值,同时两次读取间隔时间最小为2S。

单总线时间表如下

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_温湿度传感器 SpringBoot_06

外部设备读取温湿度信号的步骤

步骤一:AM2321上电后(AM2321上电后要等待2S 以越过不稳定状态,在此期间读取设备不能发送任何指令),测试环境温湿度数据,并记录数据,此后传感器自动转入休眠状态。AM2321的SDA数据线由上拉电阻拉高一直保持高电平,此时 AM2321的 SDA 引脚处于输入状态,时刻检测外部信号。

步骤二:微处理器的I/O设置为输出,同时输出低电平,且低电平保持时间不能小于800us,典型值是拉低1MS,然后微处理器的I/O设置为输入状态,释放总线,由于上拉电阻,微处理器的I/O即AM2321的SDA数据线也随之变高,等主机释放总线后,AM2321发送响应信号,即输出80微秒的低电平作为应答信号,紧接着输出80微秒的高电平通知外设准备接收数据,信号传输如下图所示。

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_温湿度传感器 SpringBoot_07


步骤三:AM2321发送完响应后,随后由数据总线SDA连续串行输出40位数据,微处理器根据I/O电平的变化接收40位数据。

位数据“0”的格式为: 50 微秒的低电平加26-28 微秒的高电平;

位数据“1”的格式为: 50 微秒的低电平加70微秒的高电平;

位数据“0”、位数据“1”格式信号如图所示

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_温湿度传感器 SpringBoot_08


AM2321的数据总线SDA输出40位数据后,继续输出低电平50微秒后转为输入状态,由于上拉电阻随之变为高电平。同时AM2321内部重测环境温湿度数据,并记录数据,测试记录结束,单片机自动进入休眠状态。单片机只有收到主机的起始信号后,才重新唤醒传感器,进入工作状态。

外部设备读取温湿度流程

温湿度传感器 SpringBoot 温湿度传感器 纳芯微_单片机_09

STC12C5A16S2读取温湿度源程序如下

sbit Sensor_SDA = P1^1;//定义P1.1为数据口


unsigned char Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};//定义温湿度传感器数据存放区
unsigned char Sensor_Check;		  //温湿度传感器校验和,判断读取温湿度数据是否正确
unsigned char Sensor_AnswerFlag;  //温湿度传感器收到起始标志位
unsigned char Sensor_ErrorFlag;   //读取传感器错误标志



//**********************************************************************
//函数名:Read_SensorData(void)
//输入	:无
//输出	:单字节的温湿度数据或者校验值
//功能描述:读取单字节的AM2321的数据
//*************************************************************************
unsigned char Read_SensorData(void)
  {
	unsigned char i,cnt;
	unsigned char buffer,tmp;
	buffer = 0;
	for(i=0;i<8;i++)
	{
		cnt=0;
		while(!Sensor_SDA)	//检测上次低电平是否结束
		{
		  if(++cnt >= 290)
		   {
			  break;
		   }
		}
		//延时Min = 26us Max = 50us 跳过数据"0"的高电平
		delay_30us();//延时30us
		tmp =0;
		if(Sensor_SDA)//延时30us后如果数据口还是高,则该为1,否则为0		
		{
		  tmp = 1;
		}  
		cnt =0;
		while(Sensor_SDA)		//等待高电平结束
		{
		   	if(++cnt >= 200)
			{
			  break;
			}
		
		buffer <<=1; //移位,使得数据的最低位 准备接收下一位
		buffer |= tmp;//把本次接收到的位加入数据中	
	}
	return buffer;//返回单字节数据
  }

//**********************************************************************
//函数名:Read_Sensor(void)
//输入	:无
//输出	:无
//功能描述:读取AM2321的温湿度及校验值放在Sensor_Data[]中
//*************************************************************************
unsigned char Read_Sensor(void)
  {
	unsigned char i;

    Sensor_SDA = 0;//起始信号拉低
	delay_3ms();  //延时3ms,一半只需延时1ms即可
	Sensor_SDA = 1; //拉高释放总线
	delay_30us(); //延时30us
	Sensor_AnswerFlag = 0;  //传感器响应标志	 
	if(Sensor_SDA ==0)//从高电平到低电平经过30us(大于20us)是否为低
	{  
	   //如果为低,那么传感器发出响应信号
	   Sensor_AnswerFlag = 1;//接收到起始信号
	   Sys_CNT = 0;//判断从机是否发出80us的低电平响应信号是否结束 
	   while((!Sensor_SDA))	//等待传感器响应信号80us的低电平结束
	   {
	     if(++Sys_CNT>300) //防止进入死循环
		 {
		   Sensor_ErrorFlag = 1;
		   return 0;
		  } 
	    }
	    Sys_CNT = 0;
	    //判断从机是否发出80us的高电平,如发出则进入数据接收状态
	    while((Sensor_SDA))//等待传感器响应信号80us的高电平结束
	    {
	       if(++Sys_CNT>300) //防止进入死循环
		   {
		     Sensor_ErrorFlag = 1;
		     return 0;
		   } 
	    } 		 
	    // 数据接收 传感器共发送40位数据
	    // 即5个字节 高位先送 5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和
	    // 校验和 = 湿度高位+湿度低位+温度高位+温度低位
	    for(i=0;i<5;i++)
	    {
	      Sensor_Data[i] = Read_SensorData();
	    }
	   
	  }
	  else
	  {
	    Sensor_AnswerFlag = 0;	  // 未接收到传感器响应
	  }
	  return 1;
  }