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

📄 便携式温度计.bak

📁 小型便携式温度计的源代码第一版
💻 BAK
字号:
/***********************************************************************
;便携式温度计
;数码管引脚连接:a=P1.3 b=P1.2 c=P1.1 d=P1.0 e=P1.6 f=P1.4 g=P1.5 h=nc共阳;
;编写人:芦庆
;时间:2008年7月27日
;主控芯片:AT89C2051-24PU
;温度传感器:DS18B20
;占用资源:定时器0,P1口,P3.2,P3.3,P3.4,P3.5,P3.7
;晶振速度:6MHz
;版本:1.0
;ROM指令                       	       	代码
;Read ROM(读ROM)                 [33H]
;Match ROM(匹配ROM)           [55H]
;Skip ROM(跳过ROM]             [CCH]
;Search ROM(搜索ROM)           [F0H]
;Alarm search(告警搜索)          [ECH]
;
;存储器操作指令 					代码
;Write Scratchpad(写暂存存储器)  	[4EH]
;Read Scratchpad(读暂存存储器)  	[BEH]
;Copy Scratchpad(复制暂存存储器) 	[48H]
;Convert Temperature(温度变换)   		[44H]
;Recall EPROM(重新调出) 			[B8H]
;Read Power supply(读电源)	    		[B4H]
;
************************************************************************/

/*****************数据类型定义***********************/
#define uchar unsigned char
#define uint unsigned int

/****************包含文件声明************************/
#include "intrins.h"
#include "AT89x051.H"

//定义数据引脚
sbit dq=P3^7;

/****************全局变量声明************************/
uchar flag;//18b20存在标志
uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
uchar id_buff[8];//64位id寄存
uchar *p;//地址指针
uchar Temperature;//温度换算中间寄存器
uchar code CrcTable [256]={
0,  94, 188,  226,  97,  63,  221,  131,  194,  156,  126,  32,  163,  253,  31,  65,
157,  195,  33,  127,  252,  162,  64,  30,  95,  1,  227,  189,  62,  96,  130,  220,
35,  125,  159,  193,  66,  28,  254,  160,  225,  191,  93,  3,  128,  222,  60,  98,
190,  224,  2,  92,  223,  129,  99,  61,  124,  34,  192,  158,  29,  67,  161,  255,
70,  24,  250,  164,  39,  121,  155,  197,  132,  218,  56,  102,  229,  187,  89,  7,
219,  133, 103,  57,  186,  228,  6,  88,  25,  71,  165,  251,  120,  38,  196,  154,
101,  59, 217,  135,  4,  90,  184,  230,  167,  249,  27,  69,  198,  152,  122,  36,
248,  166, 68,  26,  153,  199,  37,  123,  58,  100,  134,  216,  91,  5,  231,  185,
140,  210, 48,  110,  237,  179,  81,  15,  78,  16,  242,  172,  47,  113,  147,  205,
17,  79,  173,  243,  112,  46,  204,  146,  211,  141,  111,  49,  178,  236,  14,  80,
175,  241, 19,  77,  206,  144,  114,  44,  109,  51,  209,  143,  12,  82,  176,  238,
50,  108,  142,  208,  83,  13,  239,  177,  240,  174,  76,  18,  145,  207,  45,  115,
202,  148, 118,  40,  171,  245,  23,  73,  8,  86,  180,  234,  105,  55,  213, 139,
87,  9,  235,  181,  54,  104,  138,  212,  149,  203,  41,  119,  244,  170,  72,  22,
233,  183,  85,  11,  136,  214,  52,  106,  43,  117,  151,  201,  74,  20,  246,  168,
116,  42,  200,  150,  21,  75,  169,  247,  182,  232,  10,  84,  215,  137,  107,  53};
uchar code DispDB[15]={//字形码
	0xA0,0xF9,0x92,0xD0,0xC9,0xC4,0x84,0xF1,//0,1,2,3,4,5,6,7
	0x80,0xC0,0xDF,0xD9,0x87,0x81,0xAE};//8,9,-,-1,F,A,L
uchar code DispCon[4]={0xFB,0xF7,0xEF,0xDF};//段位控制码
uchar DispLED[4];//数码管显示缓冲区

uchar code DayStr[]=__DATE__;
uchar code TimeStr[]=__TIME__;

/*****************精确延时函数************************/
void TempDelay (uchar us)//微秒级延时
{
 	while(us--);
}

/******************一般延时函数************************/
void mDelay(uint num)
{
	uint i;
	for(;num>0;num--)
	{	for(i=0;i<124;i++)
			{;}
	}
}

/********************18B20初始化函数******************/
void Init18b20 ()
{
	dq=1;
	_nop_();
	dq=0;
	TempDelay(86/2);   //delay 530 uS//80
	_nop_();
	dq=1;
	TempDelay(14/2);   //delay 100 uS//14
	_nop_();
	_nop_();
	_nop_();
	
	if(dq==0)
		flag = 1;   //detect 1820 success!
	else
		flag = 0;    //detect 1820 fail!
	TempDelay(20/2);       //20
	_nop_();
	_nop_();
	dq = 1;
}

/********************向18B20写入一个字节***********/
void WriteByte (uchar wr)  //单字节写入
{
	uchar i;
	for (i=0;i<8;i++)
	{
		dq = 0;
		_nop_();
		dq=wr&0x01;
		TempDelay(5/2);   //delay 45 uS //5
		_nop_();
		_nop_();
		dq=1;
		wr >>= 1;
	}
}

/***************读18B20的一个字节*******************/
uchar ReadByte()     //读取单字节
{
	uchar i,u=0;
	for(i=0;i<8;i++)
	{
		dq = 0;
		u >>= 1;
		dq = 1;
		if(dq==1)
		u |= 0x80;
		TempDelay (4/2);
		_nop_();
	}
	return(u);
}

/*****************读18B20*************************/
void reads (uchar k) //reentrant
{
	 uchar i;
	 for(i=0;i<k;i++)
	 {
		  *p = ReadByte();
		  p++;
	 }
}

/********************CRC校验**********************/
uchar CRC (uchar j)
{
   	uchar i,crc_data=0;
  	for(i=0;i<j;i++)  //查表校验
    	crc_data=CrcTable[crc_data^temp_buff[i]];
    return (crc_data);
}


/********************内部配置********************/
/*void Config18b20(uchar max,uchar min)  //重新配置报警限定值和分辨率
{
    Init18b20();
    WriteByte(0xcc);  //跳过rom
    WriteByte(0x4e);  //写温度报警触发
    WriteByte(max);  //上限
    WriteByte(min);  //下限
    WriteByte(0x7F);  //设分辨率12位
    Init18b20();
    WriteByte(0xcc);  //跳过rom
    WriteByte(0x48);  //保存设定值
    mDelay(6);
    Init18b20();
    WriteByte(0xcc);  //跳过rom
    WriteByte(0xb8);  //回调设定值
}*/

/***********************读18B20ID**********************/
void ReadID ()//读取器件 id
{
	p = id_buff;
	Init18b20();
	WriteByte(0x33);  //read rom
	reads(8);
}

/********************温度转换全处理********************/
void Temperature_change()
{
	Init18b20 ();//初始化18B20
	WriteByte(0xcc);   //跳过ROM
	WriteByte(0x44);   //启动温度转换
	mDelay(50);//重要延时
	Init18b20 ();
	WriteByte(0xcc);   //跳过ROM
	WriteByte(0xbe);   //读取温度
	p = temp_buff;
	reads (9);
	if (CRC(9)==0) //校验正确
	{
		if(temp_buff[1]<0xF0)//温度大于0度
		{
			DispLED[3]=(temp_buff[0]&0x0F)*625/1000%10;//小数
			Temperature=(temp_buff[0]>>4)+(temp_buff[1]<<4);
			DispLED[2]=Temperature%10;//个位
			DispLED[1]=Temperature/10;//十位
			DispLED[0]=Temperature/100;//
		}
		else//温度小于0度
		{
			temp_buff[0]=~temp_buff[0]+1;
			temp_buff[1]=~temp_buff[1];
			DispLED[3]=(temp_buff[0]&0x0F)*625/1000%10;//小数
			Temperature=(temp_buff[0]>>4)+(temp_buff[1]<<4);
			DispLED[2]=Temperature%10;//个位
			DispLED[1]=Temperature/10;//十位
			DispLED[0]=Temperature/100+10;//百位+负号
		}
	}
}

/****************串口初始化*************************/
/*void Int_UART(void)
{
	SCON=0X40;//8位UART,
	PCON|=0x80;//波特率加倍
	TMOD|=0X20;//T1八位自重装
	TH1=0XCC;//波特率600
	TL1=0XCC;
	TR1=1;//开启定时器1
	REN=1;//允许串行接受
	ES=1;//允许串口中断
}*/

/********************中断初始化函数********************/
void Init_TIME0(void)
{
	TH0=0x3C;//定时器付初值,100ms
	TL0=0xB0;
	TMOD|=0x01;//定时器0工作于定时状态,工作方式1
	ET0=1;//定时器0中断允许开
}
	
/**********************中断服务函数***************************/
void LED_timer0() interrupt 1
{
	static uchar flag_interrupt;//中断次数标志
	static uchar stop_num;//系统停止计数器
	stop_num++;
	flag_interrupt++;
	if(stop>=50) PCON=STOP_;//5秒停机
	if(flag_interrupt==4)//每0.5s转换一次温度
	{
		TR0=0;
		P3&=0xFF;//关闭所有显示,
		Temperature_change();
		flag_interrupt=0;
		TR0=1;
	}
	TH0=0x3C;//定时器付初值
	TL0=0xB0;
}

/***************串口中断服务程序********************/
/*void Serial() interrupt 4
{
	if(RI)
	{
		RI=0;
		Config18b20(0x28,0x8a); //重新配置报警限定值
	}
	if(TI)
	{
		TI=0;
	}
}*/

/**********************主函数******************************/
void main()
{
	uchar flag_LED;//数码管显示段位标志
	uint i;
	
	Init18b20 ();//初始化18B20
	if(flag==0)//效验错误
	{
		DispLED[0]=12;//字母F
		DispLED[1]=13;//字母A
		DispLED[2]=14;//字母L
		DispLED[3]=14;//字母L
		for(i=1250;i>0;i--)
		{
			P1=DispDB[DispLED[flag_LED]];
			P3=DispCon[flag_LED];
			flag_LED+=1;
			if(flag_LED==4)
			{
				flag_LED=0;//flag_LED到4归零
			}
			mDelay(2);
		}
		P3=0xff;
		PCON=STOP_;//主机进入掉电模式
	}
	else  
	{
		ReadID();
		Temperature_change();
	}
	
	Init_TIME0();
	//Int_UART();
	EA=1;//中断总允许开
	TR0=1;
	for(;;)	
	{
		P3|=0x3C;//关闭显示
		P1=DispDB[DispLED[flag_LED]];
		switch(flag_LED)
		{
			case 0:
				if(DispLED[0]==0)//首位0消隐
				{
					P3&=0xFF;//关闭显示
					flag_LED+=1;
				}
				else
				{
					P3&=0xFB;
					flag_LED+=1;
				}
				break;
			case 1:
				P3&=0xF7;
				flag_LED+=1;
				break;
			case 2:
				P3&=0xEF;
				flag_LED+=1;
				break;
			case 3:
				P3&=0xDF;
				flag_LED+=1;
				break;
		}
		if(flag_LED==4)	flag_LED=0;//flag_LED到4归零
		mDelay(1);
	}
}

⌨️ 快捷键说明

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