找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4403|回复: 14
收起左侧

单片机+DS18B20温度控制程序仿真与原理图PCB文件 可设上下限

  [复制链接]
ID:492633 发表于 2022-10-23 12:25 | 显示全部楼层 |阅读模式
基于51单片机温度控制,使用18b20来做温度传感器,四位共阳数码管显示。功能说明书:系统启动后默认温度下限28℃、上限30℃。当温度低于设定下限温度时继电器开启、加热指示灯亮起,当温度达到设定上限温度时蜂鸣器响起、保温指示灯亮起,当温度高于设定下限温度低于上限温度时蜂鸣器关闭保温指示灯继续亮起,温度低于下限温度时切换继电器开启加热指示灯亮起。(假设设置烧水,温度下限设置在90℃、上限设置100℃就行)

制作出来的实物图如下:
51hei图片20221023115815.jpg
电路原理图如下:
51hei图片20221023122146.png

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei图片20221022204816.png

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei图片20221022213922.png 51hei图片20221022214102.png
单片机源程序如下:
#include<reg52.h>         //51单片机的头文件
#include<intrins.h>   //函数程序中需要使用到空指令
/***_crol_ 字符循环左移
    _cror_ 字符循环右移
    _irol_ 整数循环左移
    _iror_ 整数循环右移
    _lrol_ 长整数循环左移
    _lror_ 长整数循环右移
    _nop_ 空操作 (相当于8051 NOP 指令)
    _testbit_ 测试并清零位 (相当于8051 JBC 指令) ***/
#define dm P0          //段码输出口
#define uchar unsigned char //宏定义,用uchar来代替unsigned char(无符号字符型变量,也即是无符号的8位变量),                                         
//宏定义的原因就是书写方便,宏定义后,uchar可直接用来定义变量
#define uint unsigned int  //原因同上,不过要注意,unsigned int为无符号的整型变量
//sbit是用来管脚的。
sbit DQ=P1^0;          //温度输入口
sbit w0=P2^4;          //数码管4
sbit w1=P2^5;          //数码管3
sbit w2=P2^6;          //数码管2
sbit w3=P2^7;          //数码管1
sbit beep=P2^0;   //蜂鸣器
sbit jidianqi=P2^1; //继电器
sbit yellow=P3^5;          //加热指示灯
sbit led=P3^6;            //高温指示灯
sbit zc=P3^7;         //系统运行正常指示灯
sbit set=P3^4;                     //选择设置
sbit add=P3^3;                  //加
sbit dec=P3^2;                  //减
int temp1=0;//最高温度和最低温度标志位         
uint h;
uint temp;        //温度函数
uchar r;
uchar high=30,low=28;        //开机默认最高温度和最低温度
uchar sign;
uchar q=0;
uchar tt=0;
uchar scale;
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};          //共阳小数断码表
uchar code table_dm[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};          //共阳LED段码表"0""1""2""3""4""5""6""7""8""9""不亮""-"
uchar code table_dm1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};        //共阳个位带小数点的断码表
uchar data temp_data[2]={0xff,0xff};//读出温度暂放
uchar data display[5]={0xff,0xff,0xff,0xff,0xff};//显示单元数据,共四个数据和一个运算暂用
/***************11us延时函数***************/
void delay(uint t)
{
        for(;t>0;t--);
}
/***************数码管显示***************/
void scan()
{
        int j;
        for(j=0;j<4;j++)
        {
                switch(j)
                {
                        case 0:
                        dm=table_dm[display[0]];;
                        w0=0;  //打开数码管显示小数数字的数码管位选端
                        delay(50);
                        w0=1;        //关闭数码管显示小数数字的数码管位选端
                        case 1:
                        dm=table_dm1[display[1]];
                        w1=0;  //打开数码管显示个位数字的数码管位选端
                        delay(50);
                        w1=1;        //关闭数码管显示个位数字的数码管位选端
                        case 2:
                        dm=table_dm[display[2]];
                        w2=0;        //打开数码管显示十位数字的数码管位选端
                        delay(50);
                        w2=1;        //关闭数码管显示十位数字的数码管位选端
                        case 3:
                        dm=table_dm[display[3]];
                        w3=0;        //打开数码管显示百位数字的数码管位选端
                        delay(50);
                        w3=1;        //关闭数码管显示百位数字的数码管位选端
                }
        }
}
/****温度传感器采用的是DS18b20,此传感器采用的
是“单总线”来传输数据。****/
/**************DS18B20初始化**************/
ow_reset(void)         //初始化
{
        char presence=1;
        while(presence)
        {
                while(presence)
                {
                        DQ=1;_nop_();_nop_();   //将数据线拉高并延时
                        DQ=0;           //将DQ(P1.0)引脚拉低。请注意,这里的DQ不是变量,而是单片机的引脚!!!                 
                        delay(50);   //延时
                        DQ=1;     //将DS拉高
                        delay(6);
                        presence=DQ;
                }
                delay(45);
                presence=~DQ;
        }
        DQ=1;        
        return presence;
}
/****************写命令函数*****************/
void write_byte(uchar val)
{
        uchar i;
        for(i=8;i>0;i--)
        {
                DQ=1;_nop_();_nop_();    //将数据线拉高并延时
                DQ=0;_nop_();_nop_();_nop_();_nop_();          //将数据线拉低并延时
                DQ=val&0x01;
                delay(6);
                val=val>>1;               
        }
        DQ=1;
        delay(1);
}        
/****************读一个字节函数*******************/
uchar read_byte(void)
{
        uchar i;
        uchar value=0;
        for(i=8;i>0;i--)  //采用for 循环,读取原始温度数据
        {
                DQ=1;_nop_();_nop_();
                value>>=1;
                DQ=0;_nop_();_nop_();_nop_();_nop_();
                DQ=1;_nop_();_nop_();_nop_();_nop_();
                if(DQ)value|=0x80;
                delay(6);
        }
        DQ=1;        
        return value;
}
/***************读取温度函数***************/
read_temp()           //读取18b20传感器函数
{
        ow_reset();
        delay(200);
        write_byte(0xcc);
        write_byte(0x44);
        ow_reset();
        delay(1);
        write_byte(0xcc);
        write_byte(0xbe);
        temp_data[0]=read_byte();
        temp_data[1]=read_byte();
        temp=temp_data[1];
        temp<<=8;
        temp=temp|temp_data[0];
        return temp;
}
/***************温度数据处理函数***************/
work_temp(uint tem)         //温度转换函数
{
        uchar n=0;
        if(tem>6348)
        {
                tem=65536-tem;
                n=1;
        }
        display[4]=tem&0x0f;
        display[0]=ditab[display[4]];
        display[4]=tem>>4;
        display[3]=display[4]/100;
        display[1]=display[4]%100;
        display[2]=display[1]/10;
        display[1]=display[1]%10;
        r=display[1]+display[2]*10+display[3]*100;
        if(!display[3])
        {
                display[3]=0x0a;
                if(!display[2])        
                {
                        display[2]=0x0a;
                }
        }
        if(n)
        {
                display[3]=0x0b;
        }
        return n;
}
/***************报警提示电路***************/
void BEEP()
{

        {zc=0;}         //系统正常指示灯
        if(r>=high&&r<129)         //如果实际温度高于等于于设定温度
        {
                led=0;//保温灯亮
                beep=0;//蜂鸣器响
                jidianqi=1; //继电器停止加热
                yellow=1;//加热灯灭
        }
        else  //否则
        {
                beep=1;//蜂鸣器停
        }
        if(r<low)         //如果实际温度小于设定温度
        {
                yellow=0;//加热灯亮
            led=1;//保温灯灭
                jidianqi=0;          //继电器开始加热
        }
}
/***************温度显示转换**************/
void xianshi(int horl)                 //数码管显示函数
{
        int n=0;
        if(horl>128)
        {
                horl=256-horl;
                n=1;
        }
        display[3]=horl/100;         //         显示千位
        display[3]=display[3]&0x0f;          //显示千位
        display[2]=horl%100/10;                   // 显示百位
        display[1]=horl%10;                                // 显示个位
        display[0]=0;                          // 显示分
        if(!display[3])
        {
                display[3]=0x0a;
                if(!display[2])        
                {
                        display[2]=0x0a;
                }
        }
        if(n)
        {
                display[3]=0x0b;
        }   

                                                                             
仿真程序和AD PCB文件下载: 51 18b20 .rar (1.78 MB, 下载次数: 284)

评分

参与人数 2黑币 +80 收起 理由
akm4a1 + 30 赞一个!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1049214 发表于 2022-10-25 22:32 | 显示全部楼层
主函数 在附件里面
回复

使用道具 举报

ID:492633 发表于 2022-10-26 07:06 来自手机 | 显示全部楼层
主函数没有复制到网页上 附件里面有
回复

使用道具 举报

ID:492633 发表于 2022-10-26 07:06 来自手机 | 显示全部楼层
东西全部在文件里
回复

使用道具 举报

ID:936755 发表于 2022-11-16 17:33 | 显示全部楼层
试试效果
回复

使用道具 举报

ID:981391 发表于 2022-11-18 14:51 | 显示全部楼层
感谢楼主分享,回去试试效果
回复

使用道具 举报

ID:1052763 发表于 2022-11-24 15:49 | 显示全部楼层
完整的程序在附件里面
回复

使用道具 举报

ID:1048397 发表于 2022-12-24 08:19 | 显示全部楼层
感谢楼主分析,程序层次很清楚,注释很详细,适合初学者学习。
回复

使用道具 举报

ID:894868 发表于 2023-2-8 11:27 | 显示全部楼层
感谢楼主分享,有空自己搞一个先··
回复

使用道具 举报

ID:208271 发表于 2023-2-25 15:50 | 显示全部楼层
8.9版本可以运行,可测正,负温度,可以学习,谢谢楼主
回复

使用道具 举报

ID:821272 发表于 2023-5-9 00:52 | 显示全部楼层
感谢楼主  最近仿真DS18B20一直不成功,然后用了你这个,很稳定,感谢
回复

使用道具 举报

ID:1068711 发表于 2023-6-13 11:57 | 显示全部楼层
为啥超过上限温度,我的蜂鸣器不响?
回复

使用道具 举报

ID:492633 发表于 2023-6-14 07:53 来自手机 | 显示全部楼层
DDDRRR 发表于 2023-6-13 11:57
为啥超过上限温度,我的蜂鸣器不响?

用有源蜂鸣器
回复

使用道具 举报

ID:1114112 发表于 2024-3-25 16:34 | 显示全部楼层
写的好详细,赞赞赞
回复

使用道具 举报

ID:1098146 发表于 2024-3-28 22:25 | 显示全部楼层
程序要用Keil5打开
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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