⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 温度传感器程序.txt

📁 AT89S52控制的18B20数字温度传感器
💻 TXT
📖 第 1 页 / 共 2 页
字号:
/*=============================================
                 温度控制器

           广州工程职业技术学院
              传感器课程设计

指导老师:    冯伟
    作者:    GIT-3408-YOUJJYY (方畅,曹文荣,梁锐权)
    时间:    2007-4-25

温度传感器用单总线DS18B20
CPU为AT89S52,三个按键(UP,DOWN,SET)
温度调节上限为125度,下限为-55度(本程序只能用于单只18B20)

================================================*/
#include <at89x52.h>
#include <intrins.h>
#include <main_led_display.h>

/*--------用于按键可位寻址的状态寄存器-----------*/
static unsigned char bdata StateREG;      
sbit DS1820ON=StateREG^0;			       //DS18B20是否存在
sbit SetTF=StateREG^1;					   //是否是在温度设置状态
sbit KeySETDown=StateREG^2;			       //"1"为已按过SET键,"0"为没按过SET按
sbit PowTF=StateREG^3;                     //电源标识("0"为开电源,"1"为关电源)
sbit KeyTF=StateREG^4;                     //"0"为按键允许,"1"为不允许
sbit KeySETDowning=StateREG^5;             //SET是否正在按下
sbit LEDTF=StateREG^6;					   //开机LOG标志位

static unsigned char bdata TLV _at_ 0x0029; //温度变量高低位
static unsigned char bdata THV _at_ 0x0028;
static signed char TMV;                     //转换后的温度值
static unsigned char KeyV,TempKeyV;         //键值
static signed char TMRomV _at_ 0x0027;      //高温度限制
static signed char TMSetV _at_ 0x0026;      //温度设定值
static unsigned char KSDNum;                //SET键连按时的采集次数
static unsigned char IntNum,IntNum2,IntNum3;//中断发生次数(IntNum用于SET长按检测,IntNum2用于设定状态时LED闪烁,IntNum用于连按其他键)
static unsigned int IntNum4,IntNum5;
static signed char Sign;                    //负号标识
static unsigned char LED_One,LED_Two,LED_Three;
/*------------------------------------------
              数值转换
-------------------------------------------*/
void V2ToV(void)
{
 TLV>>=4;
 THV<<=4;   //读出的高低位数值移位
 TMV=TLV|THV; //合并高低位放入TM为实际温度值
 Sign=0;
  if(SetTF||!Key_SET)Sign=TMSetV>>7; //取符号
  else Sign=TMV>>7;
  if(Sign)
  {
   if(SetTF||!Key_SET)
    {
	 LED_One=(~(TMSetV-1))/100;    //SET状态下显示设定值
	 LED_Two=((~(TMSetV-1))-LED_One*100)/10;
	 LED_Three=(~(TMSetV-1))-LED_One*100-LED_Two*10;
	 }
	else
	 {
	  LED_One=(~(TMV-1))/100;     //转换百位数值
	  LED_Two=((~(TMV-1))-LED_One*100)/10;  
	  LED_Three=(~(TMV-1))-LED_One*100-LED_Two*10;
	  }
	}
   else
    {
	 if(SetTF||!Key_SET)
	  {
	   LED_One=TMSetV/100;    //SET状态下显示设定值
	   LED_Two=(TMSetV-LED_One*100)/10;
	   LED_Three=TMSetV-LED_One*100-LED_Two*10;
	   }
	 else
	  {
	   LED_One=TMV/100;     //转换百位数值
	   LED_Two=(TMV-LED_One*100)/10;  
	   LED_Three=TMV-LED_One*100-LED_Two*10;
	   }
	  }
//=================转换LED字段==================
 if(LED_One)LED_Two=BCD_ASCII[LED_Two+1];   //超过百时十位的处理
 else
  {
   if(LED_Two==0)LED_Two=BCD_ASCII[0];
   else LED_Two=BCD_ASCII[LED_Two+1];
   }
 if(Sign)LED_One=0xf7;
 else
  {
   if(LED_One==0)LED_One=BCD_ASCII[0];
   else LED_One=BCD_ASCII[LED_One+1];
   }
 LED_Three=BCD_ASCII[LED_Three+1];
 }
 /*-------------------------------------------
                  初始化DS1820
 --------------------------------------------*/
 void InitDS1820(void)
 {
  TMPort=1;
  _nop_();
  TMPort=0;
  Delay_6n5_8us(77);           //延时 DS1820复位时间要500US的抵电平
  TMPort=1;
  Delay_6n5_8us(16);	 //延时112US 等待DS1820的回应
  if(!TMPort){DS1820ON=1;ON_DS1820=1;}             //检测是否有DS1820
  else {DS1820ON=0;ON_DS1820=0;}
  Delay_6n5_8us(55);
  TMPort=1;
  }
/*------------------写数据-------------------*/
void Write_Data(uchar T_DATA)
 {
   uchar i,DATA_T;
   DATA_T=T_DATA;
   for(i=0;i<=7;i++)
   {
    TMPort=0;
    Delay_6n5_8us(1);			   //延时14微秒
    if(DATA_T&0x01)TMPort=1;
	else TMPort=0;
	DATA_T>>=1;
    Delay_6n5_8us(7);	           //延时54微秒
	TMPort=1;
	_nop_();
	}
	TMPort=1;
  }
/*--------------------------------------------
              写入温度限制值
       发出4EH写ROM指令后连发两个字节
---------------------------------------------*/
void WriteDS1820(void)
{
 uchar TM_H,TM_L;
  TM_H>>=4;
  TM_L<<=4;
  Write_Data(TM_H);
  Write_Data(TM_L);
}
/*-----------------读数据-------------------*/
uchar ReadTM(void)
{
 uchar i,TM_DATA;
 for(i=0;i<=7;i++)
 {
  TM_DATA>>=1;
  TMPort=1;
  _nop_();_nop_();
  TMPort=0;
  _nop_();_nop_();_nop_();
  TMPort=1;
  Delay_6n5_8us(1);
  if(TMPort)TM_DATA|=0x80;
  Delay_6n5_8us(6);
  }
  return (TM_DATA);
 }
/*-------------------------------------------
         读出温度值
将温度高位和低位,高温度限制位从DS1820中读出
    低位存入29H(TEMPER_L),
    高位存入28H(TEMPER_H),
    高温度限制位存入27H(TMRomV) 
---------------------------------------------*/
void ReadDS1820(void)
{
 TLV=ReadTM();
 THV=ReadTM();
 TMRomV=ReadTM();
 }
/*====================主程序===================*/
void main(void)
{
 StateREG=0;             //初始化变量
 SetTF=1;				 //在设置温度状态
 PowTF=1;                //关电源
 THV=0;					 //温度数据存储(高地址:0x0028,低地址:0x0029) TLV=0;
 TMV=0;					 //转换后的温度值
 KeyV=0;
 KSDNum=0;				 //SET键连按时的采集次数
 IntNum=0;				 //用于SET长按检测
 IntNum2=0;				 //用于设定状态时LED闪烁
 IntNum3=0;
 LED_One=0;
 LED_Two=0;
 Beep=1;
 LEDTF=0;
 InitDS1820();//初始化
 Write_Data(0xcc);//跳过ROM
 Write_Data(0xb8);//E2RAM中的温度上限值调入RAM
 InitDS1820();
 Write_Data(0xcc);//跳过ROM
 Write_Data(0xbe);//读出温度指令
 ReadDS1820();//读出温度值和上限值
 TMSetV=TMRomV;//拷贝保存在DS1820ROM里的上限值到TMSet
 EA=1;		   //允许CPU中断
 ET0=1;		   //定时器0中断开
 TMOD=0x01;	   //设定时器0为模式1,16位模式
 TH0=0XB1;
 TL0=0XDF;     //设定时值为20MS
 TR0=1;        //开定时
 while(1);
 }
 /*----------------------------------
 定时器0中断处理中键扫描和显示

 ------------------------------------*/
 void KeyAndDis_Time0(void) interrupt 1 using 2
 {
  TH0=0XB1;
  TL0=0XDF;                    //设定时值为20MS
  LEDPort=0xff;				   //关闭LED
/*--------------对按下的键值附值-------------*/
  if(!Key_UP)KeyV=1;		   //检测Key_UP是否按下
  if(!Key_DOWN)KeyV=2;		   //检测Key_DOWN是否按下
  if(!Key_SET)KeyV=3;		   //检测Key_SET是否按下
  KeySETDowning=0;  //清除
/*--------------检测是否有键按下----------------*/
  if(KeyV!=0)				   //KeyV不等于零表示有键按下
   {
	Delay_1ms(10);             //延时防抖  按下10MS再测
	if(!Key_UP)TempKeyV=1;	  
	if(!Key_DOWN)TempKeyV=2;
	if(!Key_SET)TempKeyV=3;
	if(KeyV==TempKeyV)        //两次值相等为确定接下了键
	 {
/*---判断是否是Key_SET按下---*/
	  if(KeyV==3)         //按下SET键,如在SET状态就退出,否则进入
	   {
		 KeySETDowning=1;   //表明SET正在按下
		 PowTF=0;         //电源标识开
		 if(!KeyTF)		  //KeyTF为1不允许执行下程序
		 if(SetTF)
		 {
		  SetTF=0;      //是否是在温度设置状态标识位标识退出设定
		  InitDS1820();
		  Write_Data(0xcc);  //跳过ROM
		  Write_Data(0x4e);  //写温度上限指令
		  WriteDS1820();     //写温度上限到DS1820ROM
		  InitDS1820(); 
		  Write_Data(0xcc);	//跳过ROM匹配
		  Write_Data(0x48);  //温度上限值COPY回E2PRAM
		   }
		  else SetTF=1;	      //为下一次没按SET时,按其他键作准备
		  if(!KeySETDown){KeySETDown=1;OPen=1;}	   //是否已按过SET键标识
		  else KSDNum+=1;  //前一秒内有按SET则开始计数
		  }

/*--------Key_UP和Key_DOWN的检测---------*/
	  if(SetTF)  //在SET状态下
		  {
		   if((KeyV==1)&&(!KeyTF))TMSetV+=1,OPen=0;    //上调温度
		   if((KeyV==2)&&(!KeyTF))TMSetV-=1,OPen=0;   //下调温度
		   if(TMSetV<=-55)TMSetV=-55;
		   if(TMSetV>=125)TMSetV=125;
		   }
	  if((!KeyTF)&&(IntNum3==0))KeyTF=1;     //判断键盘是否处于可用时
	  }

/*---------按键长按的处理----------*/
     if(KeySETDown)IntNum+=1;    //在2秒内按下了SET则计中断发生次数用于长按SET时计时用
     if(IntNum>60)
      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -