码迷,mamicode.com
首页 > 其他好文 > 详细

通过红外实现温度的无线测量与传输

时间:2016-05-27 12:27:57      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:

技术分享为保持网友一定的独立性,作者挂出绝大部分

源码(并非全部)以供参考,拒绝不动脑筋的伸手党!   

 1、介绍

本系统两部分组成

  • 温度采集端
  • 温度显示端
  • 原理:通过温度传感器采集温度显示在液晶屏或者数码管上,并将温度通过红外发送到红外接收头,然后解调解码数据,将温度显示出来,实现温度的无线测量


2.控制器选择

方案一:采用MSP430来处理

Msp430是一种超低功耗的混合信号处理器,采用精简指令集,单个始终走起就可以执行一条指令,速度比51快得多。因此用430来处理比较器返回来的数据是比较快捷的,但价格相对较贵。430供电为3.3V,且操作起来较复杂。

方案二:采用51内核单片机

单片机操作方便快捷,成本低,开发资源丰富,位寻址方便等,来的数据不需要很大的数据处理过程,51已完全能够胜方便,所以该装置采用STC89c52型的单片机来进行处理,本单片机一个机器一个时钟周期执行一条指令,无法解密,低功耗,超低价,高速,高可靠性。

  3.温度显示方式选择

方案一:采用数码管显示

数码管是由多个发光二极管封装在一起组成的8字型的器件,引线已在内部连接完成,只需引出他们的各个笔画和公共电极。可以用来显示数字和字母。

方案二:采用LCD1602

一种专门用来显示字母,数字,符号等的点阵型液晶模块。它由若干个5X7或者5X11等的点阵字符位组成,每个点阵自字符位都可以显示一个字符,每位之间有一个点距的间隔,可以显示两行,每行16位数字或者字符。1602采用标准的16脚借口,相比数码管,同样引脚的情况下,显示的内容更多,焊接更加方便快捷,所以我们选用显示部分选用LCD1602.


3.1.红外的编码和解码

  • 采用脉宽调制的串行码

  • ---------二进制“0”表示---------

  • 脉宽:0.565ms

  • 间隔:0.56ms

  • 周期:1.125ms

  • -------------分割线---------------


  • ---------二进制“1”表示---------

  • 脉宽:0.565ms

  • 间隔:1.685ms

  • 周期:2.25ms

  • -------------分割线--------------

》》》其波形如下图所示:

     技术分享

>>>>上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。

>>>>然后再通过红外发射二极管产生红外线向空间发射。编码数据,载波,发射.

》》》接收解码如下图所示:

 技术分享

----》温度传感器DS18B20采集温度

     ----》通过单片机处理显示在液晶上

             ----》对温度数据进行编码通过红外发射电路将温度信息发射出去。

     4、软件设计

 此次用的是DSl8B20作为温度传感器进行温度采集,然后将温度数据转化为电信号,通过红外线发射,再让接受端收到温度信息,并显示出来。因为焊接的是单片机最小系统,所以,我们用的就是无线红外发射管和无线红外接收管来实现发送端与接收端数据的传输,基本可以实现五米以上距离的信息传输。

接收端主循环一直检测红外是否接收完成,如果完成清除完成标志,并进行数据校验,校验通过则对红外数据进行转换,temperature为全局,将在display.c由定时器扫描数码管进行显示。信号灯的闪烁则利用ledcount变量自减进行控制

发送端主循环以一定间隔进行18B20温度读取,再将温度数据转换为红外数据码,进行红外发射,伴随信号灯闪烁

定时器0进行38K载波的产生。红外数据存入IR_Code数组,前两位为引导码 3——18为校验码 19——41数据具体编码0 和1 的表示参考NEC红外协议,对0 1的编码时间适当增大了,以避免其他红外遥控的干扰。



     5、程序模块

             5.1、数据采集

#include"18b20.h"

void DelayUs2x(unsigned char t)
{   while(--t);   }

void DelayMs(unsigned char t)		 //延时tms
{  while(t--)
	 {	 DelayUs2x(245);DelayUs2x(245); } //大致延时1mS 
}

/*------------------------------------------------
                    18b20初始化
------------------------------------------------*/
bit Init_DS18B20(void)
{	 bit dat=0;DQ = 1;        //DQ复位
	 DelayUs2x(10);DQ = 0;     //稍做延时   //单片机将DQ拉低    
	 DelayUs2x(200); DelayUs2x(200); //精确延时 大于 480us 小于960us
	 DQ = 1;   DelayUs2x(50); //拉高总线 //15~60us 后 接收60-240us的存在脉冲
	 dat=DQ;  DelayUs2x(25);  //如果x=0则初始化成功, x=1则初始化失败 //稍作延时返回
	 return dat;
}
/*------------------------------------------------
                    读取一个字节
------------------------------------------------*/
unsigned char ReadOneChar(void)
{
	unsigned char i=0;
	unsigned char dat = 0;
	for (i=8;i>0;i--)
	{ DQ = 0;  dat>>=1; DQ = 1; // 给脉冲信号	// 给脉冲信号
	  if(DQ)   dat|=0x80;	DelayUs2x(25); 
	}	  
	 return(dat);
}  
/*------------------------------------------------
                    写入一个字节
------------------------------------------------*/
void WriteOneChar(unsigned char dat)
{	 unsigned char i=0;
	 for (i=8; i>0; i--)
	 {DQ = 0;  DQ = dat&0x01; DelayUs2x(25);					
	  DQ = 1;  dat>>=1; 
	 }
	DelayUs2x(25);
}
/*------------------------------------------------
              读取温度
------------------------------------------------*/
unsigned int ReadTemperature(void)
{	unsigned char a=0;unsigned int b=0;unsigned int t=0;

	Init_DS18B20();
	WriteOneChar(0xCC);         // 跳过读序号列号的操作
	WriteOneChar(0x44);         // 启动温度转换

	DelayMs(20);
	Init_DS18B20();
	WriteOneChar(0xCC);         //跳过读序号列号的操作 
	WriteOneChar(0xBE);         //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

	a=ReadOneChar();            //低位
	b=ReadOneChar();            //高位
 
	t = ((int)b << 8) + a;	
	return(t);
}


           5.2  发射模块(子函数部分源码)

/**************数据转换函数**************
***函数名 :DataConversion
***参 数  :待转换的数值num,红外码存放地址 irdata
***功 能  :将数值转换为红外发射码
***返回值 :无
#define IR_CODE_0     20				  //发射码的0
#define IR_CODE_1     50
#define IR_CODE_START 240				  //发射码起始
#define IR_CODE_SIZI  42				  //发射码个数
*****************************************/
void DataConversion(unsigned int num,unsigned char* irdata)
{	unsigned char i=IR_CODE_SIZI-3,n=1,f=1;
	IrcodeReset();						  //存储区初始化
	for(n=3;n<18;n+=2)		              //前8个存放校验码10101010 0xAA 
	{	if(f)
	    	{	
			irdata[n] = IR_CODE_1;
			f=0;
			}		
		else
	    	{	irdata[n] = IR_CODE_0;f=1;}		
	}
	while(num!=0)					              //数据码存放 十进制转二进制
	{
		if(num%2)	{  irdata[i] = IR_CODE_1; }  						  
		
		else	 	{  irdata[i] = IR_CODE_0; }	   
	
		num = num/2;
		i-=2;
	}	
}
/**************红外波发射函数**************
***函数名 :SendIrWave()
***参 数  :储存红外编码数据的首地址irdata
***功 能  :以红外的方式发送irdata 的红外波形数据
***返回值 :无
*****************************************/
void SendIrWave(unsigned char* irdata)
{	unsigned char count=0;
	unsigned char i=0;

	while(1)								 //发射引导码 校验码 数据码 
	{
		ON_CARR;
		for(i=irdata[count]; i>0; i--)	  	 //载波发射延时
	    	{	
			CarrierWave_DELAY;	
			}							    
				OFF_CARR;
				IR_SEND_OFF;						 //低电平保持	
				count++;
							  
	    for(i=irdata[count]; i>0; i--)	     //低电平延时
	    	{	
			Low_DELAY;  

			}

		if(count == IR_CODE_SIZI-1)	         //发射结束
	    	{	break;       }	
		count++;			
	}
}

           5.3 接收模块

/*******红外数据接收初始化函数*********
***函数名 :InitIrReceive
***参 数  :无
***功 能  :配置红外接收需要的定时器和中断
***返回值 :无
*****************************************/
void InitIrReceive(void)
{
/*------------------------------------------------
                定时器0初始化
------------------------------------------------*/
	TMOD|= 0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
	//8位自动重装
    TH0  = 0x00;//重载值
    TL0  = 0x00;//初始化值  
    ET0  = 1;	//开中断
    TR0  = 1;	//定时器/计数器启动
/*------------------------------------------------
                  外部中断0初始化
------------------------------------------------*/
	IT0  = 1;	//指定外部中断0下降沿触发,INT0 (P3.2)
	EX0  = 1;	//使能外部中断
	EA   = 1;
}??
/*******红外数据时间计数函数*********
***函数名 :IRTimeCount()
***参 数  :无
***功 能  :记录每两个红外脉冲时间间隔
***返回值 :无
*****************************************/
void IRTimeCount() interrupt 1
   {  Ir_Time_count++; }
/*************红外码接收中断函数***********
***函数名: IRReceive(void)
***参 数:  无
***功能描述:接收红外码,存入IR_CODE
***返回值: 无
*****************************************/
void IRReceive() interrupt 0
{
	static startflag=0,bitnum=0;
	if(startflag)
	{  if(Ir_Time_count<IR_START_TIEM_MAX && Ir_Time_count>IR_START_TIEM_MIN)	
	   //引导码判断
	     {bitnum=0;  }
	   IR_CODE[bitnum]=Ir_Time_count;
	   //引导码 TC9012的头码,9ms+4.5ms
	   Ir_Time_count=0;	   bitnum++;
	          
	   if(bitnum==IR_CODE_SIZI)		   //接收完成
	     {IR_RECEIVE_OK=1;  bitnum=0;}  		 
	}  

    else							   //第一个触发信号
	{Ir_Time_count=0; 	startflag=1;  	}		
}
/************红外码数据转换函数***********
***函数名: DataConversion()
***参 数:  无
***功能描述:接收红外码,存入IR_CODE
***返回值: 数据区的数据
*****************************************/
unsigned int DataConversion(void)
{
	  unsigned char i=9;
	  unsigned int num=0;
	  for(i=9;i<IR_CODE_SIZI-1;i++)
	  {
	  	if(IR_CODE[i]>IR_CODE_1)
		{
			num+=pow(2,IR_CODE_SIZI-2-i);//二进制转十进制
		}
	  }
	  return num;
}
/*************红外码数据校验***********
***函数名: CheckSucceed()
***参 数:  无
***功能描述:转换IR_CODE 1——8的校验码,与事先设定值进行比较判断
***返回值: 成功1 失败0
*****************************************/
unsigned char CheckSucceed(void)
{
	unsigned char i=1;
	unsigned int num=0;
	for(i=1;i<9;i++)	                 //校验码位于1——8
		{	
			if(IR_CODE[i]>IR_CODE_1)  
			{	
			 num+=pow(2,8-i); //转换  	
			}	 
		}			

	if(num==CHECK_NUM && IR_CODE[0]>IR_START_TIEM_MIN &&  IR_CODE[0]<IR_START_TIEM_MAX)
	//校验码和引导码均校验
     {	
	  return 1; 
	 }		
	else
	{  	
	 return 0; 
	}	
}


技术分享转载请注明来源,么么哒!原创声明:本文为-Sure-原创作品,转载时请注明“转自-Sure-”及原文链接。





通过红外实现温度的无线测量与传输

标签:

原文地址:http://blog.csdn.net/u013346007/article/details/51489223

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!