与普通温度计相比,以单片机为核心的数字温度计具有数字显示、超温报警、记录存储、数据上传等优点,因而得到了广泛应用。根据性能要求和器件选型的不同,数字温度计可有多种不同的实现方案。 温度传感器是数字温度计中的关键器件。传统的温度传感器有热电阻、热电偶、PN结等类型,这些传感器的输出均为微弱的模拟信号,必须经过放大、滤波、A/D转换等电路处理,才能得到可为单片机接受的数字量。相比之下,新型数字温度传感器将温度传感元件、数字量转换电路、数据存储器、通信接口等部件集成在一块芯片上,可通过几根(最少只要一根)串行通信线直接输出数字形式的温度值,大大简化了数字温度计的硬件设计。 DS18B20是DALLAS公司生产的单总线(1-Wire)接口的数字温度传感器,数据传输仅需一根信号线。温度测量范围为-55~+125℃,在-10~+85℃范围内,精度可达±0.5℃,有效数据位数可通过程序设置为9~12位,12位时分辨率可达0.0625℃。每个DS18B20具有唯一64位序列码,多个器件可并联在一根数据线上,实现多点测温。 C语言源程序如下: //*****************************头文件声明**************************** #include <reg51.h> //****************************数据类型定义*************************** typedef unsigned char uint8; typedef unsigned int uint16; //****************************I/O口线声明**************************** #define SEG_CODE_PORT P0 #define BIT_CODE_PORT P2 sbit DS18B20_DATA=P3^7; sbit BUZZ= P1^0; //************************常量数组(段码表)声明********************* uint8 code SegCodeTable[]= { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 }; //****************************全局变量声明*************************** int Temperature; uint8 t=27; //****************************函数原型声明*************************** void DS18B20Init(); void DS18B20BitWrite(bit Bit); bit DS18B20BitRead(); void DS18B20ByteWrite(uint8 Byte); uint8 DS18B20ByteRead(); void GetTemperature(); void DispTemperature(); void Delay(uint16 ms); void AlarmCheck(); void UartInit(); void UartSendByte(uint8 Byte); //*******************************主函数****************************** void main() { uint8 Temp; UartInit(); while(1) { GetTemperature(); //采集当前温度 DispTemperature(); //显示当前温度 AlarmCheck(); Temp=Temperature>>4; UartSendByte((Temp/10)*16+Temp%10); } } //*************************DS18B20初始化函数************************* void DS18B20Init() { uint16 i; while(1) { DS18B20_DATA=0; i=640; while(--i); //延时800us(STC12C5A60S2,11.0592MHz,代码5级优化) DS18B20_DATA=1; i=56; while(--i); //延时70us if(DS18B20_DATA==1) continue; //无响应则重发复位脉冲 i=224; while(--i); //延时280us if(DS18B20_DATA==1) break; //复位成功 } i=160; while(--i); //延时200us } //***********************DS18B20位写操作函数************************* void DS18B20BitWrite(bit Bit) { uint16 i; DS18B20_DATA=0; i=4; while(--i); //延时5us DS18B20_DATA=Bit; //发送1位数到DS18B20 i=48; while(--i); //延时60us DS18B20_DATA=1; } //**********************DS18B20位读操作函数************************** bit DS18B20BitRead() { bit temp; uint16 i; DS18B20_DATA=0; i=4; while(--i); //延时5us DS18B20_DATA=1; i=4; while(--i); //延时5us temp=DS18B20_DATA; //读来自DS18B20的1位数 i=48; while(--i); //延时60us return temp; } //**********************DS18B20字节写操作函数************************ void DS18B20ByteWrite(uint8 Byte) { uint8 i; for(i=0;i<8;i++) //一共发送8位 { if(Byte&0x01==1 ) //先发最低位 DS18B20BitWrite(1); //发送1 else DS18B20BitWrite(0); //发送0 Byte>>=1; } } //**********************DS18B20字节读操作函数************************ uint8 DS18B20ByteRead() { uint8 i,temp=0; for(i=0;i<8;i++) //一共读8位 { temp>>=1; //字节变量右移 if(DS18B20BitRead()==1) //读取1位数据并存入临时变量temp中 temp|=0x80; //temp最高位置1 } return temp; //返回读到的8位数 } //*****************************温度采集函数************************** void GetTemperature() { uint8 Buff[2],i; DS18B20Init(); //DS18B20初始化 DS18B20ByteWrite(0xCC); //跳过ROM匹配(因为只有一个DS18B20) DS18B20ByteWrite(0x44); //启动温度转换 for(i=0;i<250;i++) DispTemperature(); //等待750ms,期间不断刷新LED显示 DS18B20Init(); //DS18B20初始化 DS18B20ByteWrite(0xCC); //跳过ROM匹配(因为只有一个DS18B20) DS18B20ByteWrite(0xBE); //准备读转换结果 Buff[0]=DS18B20ByteRead(); //读温度值低字节 Buff[1]=DS18B20ByteRead(); //读温度值高字节 Temperature= (Buff[1]<<8)+Buff[0]; //拼成16位温度值 } //******************************温度显示函数************************* void DispTemperature() { uint8 temp; SEG_CODE_PORT=SegCodeTable[t/10]; //显示十位 BIT_CODE_PORT=0xF2; //选择显示位置 Delay(1); BIT_CODE_PORT=0xFF; SEG_CODE_PORT=SegCodeTable[t%10]; //显示个位 BIT_CODE_PORT=0xF3; //选择显示位置 Delay(1); BIT_CODE_PORT=0xFF; temp=(Temperature>>4)/10; //显示十位 if(temp==0) SEG_CODE_PORT=0xFF ; //十位为0则隐去 else SEG_CODE_PORT=SegCodeTable[temp]; BIT_CODE_PORT=0xF5; //选择显示位置 Delay(1); BIT_CODE_PORT=0xFF; SEG_CODE_PORT=SegCodeTable[(Temperature>>4)%10]&0x7F; //显示个位(带点) BIT_CODE_PORT=0xF6; //选择显示位置 Delay(1); BIT_CODE_PORT=0xFF; SEG_CODE_PORT=SegCodeTable[(Temperature&0x0F)*10/16]; //显示十分位 BIT_CODE_PORT=0xF7; //选择显示位置 Delay(1); BIT_CODE_PORT=0xFF; } //******************************软件延时函数************************* void Delay(uint16 ms) { uint16 i; do{ i=790; while(--i); //延时1ms(STC12C5A60S2,11.0592MHz,代码5级优化) } while(--ms); } /********************************超温报警函数***************************/ void AlarmCheck() { uint8 i; if(Temperature>0x1C8) //判断温度是否超过28.5℃ { for(i=0;i<50;i++) { BUZZ= ~BUZZ; Delay(1); //控制无源蜂鸣器发声50ms } BUZZ=1; Delay(100); } } void UartInit() { TMOD=0x20; TH1=TL1=0xFD; TR1=1; SCON=0x50; PCON=0x00; ES=1; EA=1; TR1=1; } void UartISR() interrupt 4 { if(RI==0) return; RI=0; t=SBUF; } void UartSendByte(uint8 Byte) { SBUF=Byte; while(TI==0); TI=0; } //********************************程序结束***************************
|