首页 > 代码库 > AM2320 温湿度传感器 C51程序 uart串口输出温湿度

AM2320 温湿度传感器 C51程序 uart串口输出温湿度



实物图

技术分享


引脚图

技术分享


接线图

技术分享


效果图

技术分享



源代码

//****************************************************************//
//AM系列温湿度传感器,读IIC使用示例 
//单片机 :AT89S52 或 STC89C52RC 
//功能  :串口发送温湿度数据  波特率 9600 
//晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
//波特率:9600
//编译环境:  Keil 4
//****************************************************************//

#include "reg52.h"
#include <intrins.h>

#define USE_T2 
#define FOSC  12000000
#define BAUD  9600	

//端口位定义,可修改
sbit SDA=P1^0;
sbit SCL=P1^1;

//内部数据定义
#define IIC_Add 0xB8    //器件地址
#define IIC_RX_Length 15

unsigned char IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令(无CRC校验)
unsigned char IIC_RX_Buffer[IIC_RX_Length] = {0x00};//读回的温湿度

unsigned char Uart_RX_Buffer[30] = {0x00};
unsigned char *String;
unsigned char WR_Flag;

//字符串定义
#define S_Function  "Function: 03 04"
#define S_Temp "Temp:"
#define S_RH   "RH:"
#define S_CRCT "CRC: True"
#define S_CRCF "CRC: Wrong"
#define S_Data "Data: "
#define S_NotS "Sensor Not Connected"

void Ack(void);
void NoAck(void);
 
void delay10us(void) //这个延时函数 要大于5US以上
{
  _nop_(); _nop_(); _nop_(); 
  _nop_(); _nop_(); _nop_(); 
}
 
void delay1ms(unsigned int t)
{
  unsigned int i;
  unsigned int j;
  for(j=t;j>0;j--)
   for(i=124;i>0;i--);  
}

void InitUART(void)
{
	unsigned int iTmpBaud;
	unsigned long lTmpBaud;
	iTmpBaud = 0;
	//首先选定定时器2作为波特率发生器,16位定时器,自动装载
	SCON = 0x50;	//SM0 SM1 SM2 REN TB8 RB8 TI RI		//0   1   0   1   0   0   0  0	
	PCON = 0x00;	//PCON的地址是87H,这里SMOD =0
	
	T2CON = 0x30;	//TF2 EXF2 RCLK TCLK EXEN2 TR2 C(/T2) CP(/RL2) //0 0 1 1 0 0 0 0 
	T2MOD = 0x00;	// /	/	/	/		/	/	T2OE	DCEN   //0 0 0 0 0 0 0 0

	//fosc = 22.1184M,6T: 144,设置波特率
	//(RCAP2H,RCAP2L) = 65536- fosc/(n*Baud)。n:32(12T-mode),16:(6T-mode)
	lTmpBaud = FOSC/BAUD;
	lTmpBaud /= 32;						//12T-mode
	iTmpBaud = lTmpBaud & 0xFFFF;		
	iTmpBaud = 65536 - iTmpBaud;
	RCAP2H = (iTmpBaud>>8) & 0x0FF;
	RCAP2L = iTmpBaud & 0x0FF;

	RI = 0;			//清除接收中断标志
	REN = 1;		//允许串行接收
	ES = 1;			//允许串行中断
	TR2 = 1;		//启动定时器1

    EA=1;//开总中断
}  

//串口发送
void UARTSend(char UCHAR)
{
   SBUF=UCHAR;
  while(TI==0);
  TI=0;
}

void UARTRead(void) interrupt 4
{
  char temp;
  if(RI)
  {
    RI=0;
    temp = SBUF;
  }
}

//**********************************************
//送起始位 sda=1->0
void I2C_Start()
{
  SDA=1;
  SCL=1;
  delay10us();
  SDA=0;
  delay10us();
  SCL=0; 
}
//************************************************
//送停止位 sda=0->1
void I2C_Stop()
{
   SDA=0;
   delay10us();
   SCL=1;
   delay10us();
   SDA=1;
}
//************************************************
//主应答(包含ack:sda=0和no_ack:sda=0)
void Ack(void)
{  //设置SDA 口为输出
   SDA=0;
   SCL=0;
   delay10us();
   SCL=1;
   delay10us();	
   SCL=0;
   SDA=1;
}

void NoAck(void)
{  //设置SDA 口为输出
   SDA=1;  
   SCL=0;
   delay10us();
   SCL=1;
   delay10us();
   SDA=1;
   SCL=0;
}

// 检测 SDA是否回ACK
bit Test_Ack()
{  //设置SDA 口为输入
   bit ACK_Flag=0;
   SCL=0;
   SDA=1;    
   delay10us();
   SCL=1;
   delay10us();
   if(SDA==0)
     ACK_Flag = 1;
   else 
     ACK_Flag = 0;
   SCL=0;
   return ACK_Flag;
}

//*************************************************
//字节发送程序
//发送c(可以是数据也可是地址),送完后接收从应答
//不考虑从应答位
void SendData(unsigned char buffer)
{
   unsigned char BitCnt=8;//一字节8位
   //设置SDA 口为输出
   do
   {
 	  SCL=0;
	  delay10us();
      if((buffer&0x80)==0) //判断最高位是0还是1
        SDA=0;
      else
        SDA=1;
      SCL=1;
	  delay10us();
      buffer=buffer<<1;//将buffer中的数据左移一位
      BitCnt--;
   }
   while(BitCnt);
   SCL=0;        
}
//**************************************************
//字节接收程序
//接收器件传来的数据,此程序应配合|主应答函数|i2c_ack_main()使用
//return: uchar型1字节
unsigned char ReceiveData()
{
  unsigned char BitCnt=8,IIC_RX_Data=http://www.mamicode.com/0;"Function: 03 04"
	       UART_PutString(String);
 	       UARTSend(‘ ‘);
	       UARTSend(‘ ‘);

	       String = S_RH;//"RH:"	   
	       Tmp = IIC_RX_Buffer[2]*256+IIC_RX_Buffer[3];	   
	       UART_PutStringAndNum(String,Tmp); 
	   
	       UARTSend(‘ ‘);
	       UARTSend(‘ ‘);
	       String = S_Temp; //"Temp:"
		   	          
		   Tmp = IIC_RX_Buffer[4]*256+IIC_RX_Buffer[5];	   
	       UART_PutStringAndNum(String,Tmp);
		   
		   UARTSend(‘ ‘);
	       UARTSend(‘ ‘);

		   String = S_CRCT;//"CRC: True";
		   UART_PutString(String);

		 }else
		 {
			String = S_Data;//"Data: ";

			UART_PutStringAnd_Data(String,IIC_RX_Buffer);
			  UARTSend(‘ ‘);
			  UARTSend(‘ ‘);
			String = S_CRCF;//"CRC: Wrong";
		      UART_PutString(String); 
		 }
	    }
		else
		{
		   String = S_NotS;//"Sensor Not Connected";
 		   UART_PutString(String);
		}	    
	   UARTSend(0x0A); 			  

       }  
void Clear_Data (void)
     {
	    int i;
	    for(i=0;i<IIC_RX_Length;i++)
	     {
	     IIC_RX_Buffer[i] = 0x00;
	     }//接收数据清零
	  }

void main(void)
{
  SCL = 1;
  SDA = 1; //上电时保证两总线为高
  InitUART();
  Clear_Data();
  while(1)
  {
	Clear_Data(); // 清除收到数据
	WR_Flag = 0;
	Waken();	  // 唤醒传感器
    //发送读指令
    WriteNByte(IIC_Add,IIC_TX_Buffer,3); 
    //发送读取或写数据命令后,至少等待2MS(给探头返回数据作时间准备)
	delay1ms(2);    
	//读返回数据
    ReadNByte(IIC_Add,IIC_RX_Buffer,8);

	SCL = 1; SDA = 1;	//确认释放总线
  	//通过串口向上发送传感器数据
	UARTSend_Nbyte();

    delay1ms(2000);	  //延时 2S	(两次读取间隔至少2S)
  }
}

编译图:

技术分享






本文出自 “魂斗罗” 博客,请务必保留此出处http://990487026.blog.51cto.com/10133282/1880145

AM2320 温湿度传感器 C51程序 uart串口输出温湿度