标题: 51单片机数字温度计设计 原理图及源代码 [打印本页]
作者: 梦幻承影 时间: 2020-5-9 10:01
标题: 51单片机数字温度计设计 原理图及源代码
与普通温度计相比,以单片机为核心的数字温度计具有数字显示、超温报警、记录存储、数据上传等优点,因而得到了广泛应用。根据性能要求和器件选型的不同,数字温度计可有多种不同的实现方案。
温度传感器是数字温度计中的关键器件。传统的温度传感器有热电阻、热电偶、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;
}
//********************************程序结束***************************
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |