找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4113|回复: 12
收起左侧

DS18B20电冰箱温控器程序

  [复制链接]
ID:920755 发表于 2021-10-8 15:30 | 显示全部楼层 |阅读模式
       这是一个用DS18B20与AT89C2051单片机,加四位共阴数码管,小型12V继电器等做的一个电冰箱温控器,很实用,有一个设置温度的按键,把冰箱温度控制在设置温度值的正负2度内,DS1B20安装在冰箱的保鲜室内,单片机读取冰箱保鲜室内的实际温度值,并与设置温度值对比,如果实际温度值大于设置温度值2度时,启动压缩机,冰箱开始制冷,当冰箱保鲜温度低于设置温度值2度时,停止压缩机,如此不断循环,使冰箱温度保持在设置温度的正负2度内。

电路原理图如下:

电路原理图

电路原理图


      单片机程序用C51编写,通过Keil uVision编译通过。部分程序如下:
//DS18B20        测温  电冰箱温控器   
#include <AT892051.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define data P1
unsigned char code DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0~9
unsigned char TempData[3];
unsigned char Tempv[9];
unsigned int temp;
unsigned int settemp;
bit ReadTempFlag;   // 读温度标志
bit runfig;                   //  运行标志
sbit DQ=P3^7;
void  disp();
void keyscan();
void tempconv();
void Init_Timer0(void)
{ TR0=1;           //定时器开关打开
}
/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
unsigned int num;  ReadTempFlag=1; //读标志位置1
  TR0=1;        
}
void DelayUs2x(unsigned char t)
{   
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{

while(t--)
{
     //大致延时1mS
     DelayUs2x(245);
         DelayUs2x(245);
}
}
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1;    //DQ复位
DelayUs2x(5);   //稍做延时
DQ = 0;         //单片机将DQ拉低
DelayUs2x(200); //精确延时 大于 480us 小于960us
DelayUs2x(200);
DQ = 1;        //拉高总线
  return dat;
}

/*------------------------------------------------
                    读取一个字节
------------------------------------------------*/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
   dat|=0x80;
  DelayUs2x(25);
}
return(dat);
}
/*------------------------------------------------
                    写入一个字节
------------------------------------------------*/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
  DQ = 0;
  DQ = dat&0x01;
  DelayUs2x(25);
  DQ = 1;
  dat>>=1;
}
DelayUs2x(25);
}

/*------------------------------------------------
                    读取温度
------------------------------------------------*/
void ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
unsigned int s=0;
unsigned int c=0;
unsigned int d=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换for(t=1;t<9;t++)
{
Tempv[t]=ReadOneChar();
}  //低位
}
void  main()
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
settemp=0xffb0;                //预设置温度
runfig=1;
ReadTempFlag=1;
Init_Timer0();
while (1)         //主循环
  {
    if(ReadTempFlag==1)
    {
     ReadTempFlag=0;
    ReadTemperature();
    a=Tempv[1];
    b=Tempv[2];
   b<<=8;
   t=a+b;
temp=t;
tempconv();
disp();
  if(t>=0xfc80)  
  {
if(settemp>=0xfc80)          //温度小于0度时
if(t>=settemp+0x20)          //温度大于设置温度2度
runfig=0;                //启动        压缩机
if(t<=settemp-0x20)           //  温度低于设置温度2度
   runfig=1;        //停止          压缩机
}
if(t<=0x7d0)        //        温度大于0度时
{
if(settemp<=0x7d0)
   if(t<=settemp-0x20)        //  温度低于设置温度2度
   runfig=1;                 //停止          压缩机
if(t>=settemp+0x20)  //温度大于设置温度2度
   runfig=0;                  //启动        压缩机
}
if(t<=0x7d0)
{
if(settemp>=0xfc8)  
   runfig=0;
}
if(t>=0xfc80)
{
if(settemp<=0x7d0)   
   runfig=1;
}
if(P3_4==0)                        // 设置按键
    keyscan();
    }
  }
}
void disp()          //温度显示
{
   unsigned char f,i,k;
   i=0;
f=0x10;
   for (k=0;k<4;k++)
   {

}
void keyscan()          //按键扫描
{
   unsigned char i;
   TR0=0;
   P3_4=1;
   DelayMs (3);
    temp=settemp;
    tempconv();
    for(i=0;i<120;i++)
{
   disp();
  }
while(P3_4==0)
   {
    settemp=settemp-0x10;
   if(settemp==0xff60)
   settemp=0x7d0;  

    temp=settemp;
    tempconv();
    for(i=0;i<25;i++)
{
   disp();
  }
  }
for(i=0;i<120;i++)
{
   disp();
  }
TR0=1;
}
void tempconv()           //温度值转换
{
  unsigned int TempH,TempL;
if(temp&0x8000)
     {
     TempData[0]=0xbf;//负号标志
     temp=~temp;  // 取反加1
         temp +=1;
         }
  else
     TempData[0]=0xff;
     TempH=temp>>4;
     TempL=temp&0x0F;
     TempL=TempL*6/10;//小数近似处理            
      TempData[2]=DuanMa[(TempH%100)%10]&0x7f; //个位温度,带小数点
     TempData[3]=DuanMa[TempL];
}...........

51hei.png

代码下载:
DS18B20温控器.7z (376.13 KB, 下载次数: 89)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:970710 发表于 2021-10-9 16:57 | 显示全部楼层
弄得不错!看什么时候可以借鉴一下!
回复

使用道具 举报

ID:477512 发表于 2021-10-10 11:01 | 显示全部楼层
我把这个电路仿真实验一下,发现数码管不能正常显示,电路说明是共阴数码管,看电路不像共阴,倒像是共阳,接成共阳的,又会全亮,没有温度显示,不知道啥原因?
回复

使用道具 举报

ID:920755 发表于 2021-10-12 10:56 | 显示全部楼层
wbwcf13e 发表于 2021-10-10 11:01
我把这个电路仿真实验一下,发现数码管不能正常显示,电路说明是共阴数码管,看电路不像共阴,倒像是共阳, ...

是共阳的,说明上有误。显示是可以的,注意DS18B20接线。
回复

使用道具 举报

ID:920755 发表于 2021-10-12 21:40 | 显示全部楼层
wbwcf13e 发表于 2021-10-10 11:01
我把这个电路仿真实验一下,发现数码管不能正常显示,电路说明是共阴数码管,看电路不像共阴,倒像是共阳, ...

是共阳的数码管,我用PROTEUS8.9仿真可以显示。
无标题.png
回复

使用道具 举报

ID:477512 发表于 2021-10-13 13:45 | 显示全部楼层
本帖最后由 wbwcf13e 于 2021-10-18 11:08 编辑

我用的是PROTEUS7.8版,没有温度显示,按说应该显示温度。难道是版本低的缘故?
回复

使用道具 举报

ID:383623 发表于 2021-10-17 08:56 来自手机 | 显示全部楼层
mxdkey 发表于 2021-10-9 16:57
弄得不错!看什么时候可以借鉴一下!

显示乱七八糟的
回复

使用道具 举报

ID:920755 发表于 2021-10-19 06:35 | 显示全部楼层

你好!上面说用共阴数码管是错的,这是我10年前做的,忘记数码管类型,是共阳的,用共阴请修改一下段码显示值 就可以了。
回复

使用道具 举报

ID:315554 发表于 2021-10-20 23:16 | 显示全部楼层
谢谢分享,找时间搭实物试试,很实用的功能
回复

使用道具 举报

ID:157975 发表于 2021-10-21 12:19 | 显示全部楼层
继电器驱动用pnp管明显不能可靠截止
回复

使用道具 举报

ID:140183 发表于 2021-10-27 08:50 | 显示全部楼层
昨天用半导体制冷片做了一个小冰箱。再用这个温度控制器来控制
回复

使用道具 举报

ID:404454 发表于 2022-2-9 10:33 | 显示全部楼层
这几天太冷了,这可以修改为当个温度使用?
回复

使用道具 举报

ID:843811 发表于 2022-4-10 10:04 | 显示全部楼层
xzk123 发表于 2021-10-12 21:40
是共阳的数码管,我用PROTEUS8.9仿真可以显示。

你好,我的初始情况是数码管显示0123,按键没反应,请问怎么解决啊,用的是楼主的代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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