📄 便携式温度计.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 + -