找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8672|回复: 0
打印 上一主题 下一主题
收起左侧

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;
}
//********************************程序结束***************************

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表