找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DS18B20 51单片机冰箱测温程序

[复制链接]
跳转到指定楼层
楼主
ID:243354 发表于 2025-5-16 10:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
编写一个冰箱测温程序,经测试,可以用

#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char

//小板接线
// sbit lcdrs=P2^4;    //液晶接口
// sbit rw=P2^5;            //液晶接口
// sbit lcden=P2^6;  //液晶接口
sbit quanwe=P2^0;
sbit baiwe=P2^1;
sbit shiwe=P2^2;
sbit gewe=P2^3;

sbit Beep=P3^0;
sbit DS=P3^2;               //温度传感器接口

sbit K1=P3^6;      //16脚
sbit K2=P3^7;           //17脚
sbit K3=P3^4;    //14脚
sbit K4=P3^5;   //15脚


uchar K1num;
uchar code smgdu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
bit flag;
uchar Thflag=1;
uchar con;
uchar Th;
uint temp;

//延迟函数
void delayus(uint t)  // 延迟10微秒函数
{
  while(t--);
}

void delayms(uint z)         //延迟1毫秒函数
{
  uint x,y;
        for(x=z;x>0;x--)
          for(y=110;y>0;y--);
}         

//DS18B20温度函数
void DSreset(void)   //复位
{
  DS=1;                           //总线高电平
  delayus(6);     //延迟66us
  DS=0;                         //拉低总线
  delayus(65);  //保持480-960us
  DS=1;        //释放总线
  delayus(14);        
  if(DS==0)         //检测到从件发出应答信号       
    flag=1;
  else
    flag=0;         //未检测到从件发出应答信号
  delayus(20);                 
}                  

bit DSread_bit( )        //读位函数,主机把总线由高拉低1微秒,释放,15微秒内检测并读取总线电平。
{
   bit Dat;
   DS=0;           //拉低总线
   _nop_( );  //延1微秒
   _nop_( );
   DS=1;         //释放总线
   _nop_( );
   Dat=DS;        //读取总线电平
   delayus(10);
   return Dat;         //返出读取值
}

uchar DSreadByte( )           //读取8位并组装1字节函数
{
    uchar i, j,k;
        k=0;               //K赋初值0
    for(i=0; i<8; i++)
    {
        j=DSread_bit( );
        k=(j<<7)|(k>>1);        //j左移7位与上k,8次后组成1字节
    }
    return k;
}               

void DSwrite_byte(uchar dat)   //写1字节函数
{
  uchar i;
  for(i=1;i<=8;i++)
  {
    DS=0;                 //拉低总线
        _nop_( );          //延1微秒
    DS=dat&0x01;  //总线电平等于需写入dat的未位,写1则DS=1,写0则DS=0
        delayus(6);
        DS=1;        //释放总线,准备写入dat的未第2位。
    dat=dat>>1;         //dat右移,未2位移至未位。
   }
   delayus(6);
}         

void tmpconvert(void)  //转换温度函数
{
  DSreset();
  delayms(1);
  DSwrite_byte(0xcc);   //跳过ROM指令
  DSwrite_byte(0x44);  //启动转换温度命令
  }

uint read_temperature( )   //读传感器温度值函数
{
  //uint T;
  uchar LSB,MSB;
  float tp;
  DSreset( );  //复位
  DSwrite_byte(0xcc);  //跳过ROM指令
  DSwrite_byte(0xbe); //读暂存器温度
  LSB=DSreadByte( );  //读低8位字节,存入LSB
  MSB=DSreadByte( ); //读高8位字节,存入MSB
  temp=MSB<<8|LSB;
  if(temp<0)
  {
   temp=temp-1;
   temp=~temp;
   tp=temp;   
   temp=tp*0.0625*10+0.5;
  }
  else
  {
  tp=temp;
  temp=tp*0.0625*10+0.5;  //扩大10倍,显示百十个。
  }
  return temp;        //返出温度值
}  


void displaysmg (uint temp)
{
        uchar quan,bai,shi,ge;
        if(Thflag)                   //标志位置1,数码管显示测量温度
         {
           bai=temp/100;
           shi=temp%100/10;
           ge=temp%10;

           quanwe=0;
           baiwe=0;
           shiwe=0;
           gewe=0;
           //P0=smgdu[quan];
           //quanwe=1;
           //delayms(1);
           //quanwe=0;
           P0=smgdu[bai];
           quanwe=1;
           delayms(1);
           quanwe=0;
          
           P0=smgdu[shi]|0x80;
           baiwe=1;
           delayms(1);
           baiwe=0;
       
           P0=smgdu[ge];
           shiwe=1;
           delayms(1);
           shiwe=0;
}
else                    //标志位置0,数码管显示设定后温度
{
       bai=Th/100;
       shi=Th%100/10;
       ge=Th%10;
           quanwe=0;
           baiwe=0;
           shiwe=0;
           gewe=0;

           P0=smgdu[bai];
           quanwe=1;
           delayms(1);
           quanwe=0;
          
           P0=smgdu[shi]|0x80;
           baiwe=1;
           delayms(1);
           baiwe=0;
       
           P0=smgdu[ge];
           shiwe=1;
           delayms(1);
           shiwe=0;
}
}

void keyscan( )           //键盘设置函数
{
if(K1==0)              //K1按下
  {
        delayms(10); //消抖
        if(K1==0)
        {
          K1num++;           //K1按下次数判断
           while(!K1);//松手检测
           if(K1num==1)                //第1次按下K1
               {
                     Thflag=0;           //标志位置0,显示设置温度报警函数
                   }
           if(K1num==2)                  //第2次按下K1
                     {
                           K1num=0;
                           Thflag=1;  //标志位置1,显示测量温度
                      }
           }
   }
if(K1num==1)           //第1次按下K1情况下
  {
      if(K2==0)          //K2按下执行温度累加设定
             {
                    delayms(10);
                    if(K2==0)
                     {
                           delayms(10);
                          //while(!K2)
                                   {
                                      Th++;
                                   if(Th==300)
                                      Th=180;
                               displaysmg(Th);        //显示设定后温度
                            }
                      }
                 }
         if(K3==0)           //K3按下执行温度累减设定
              {
                    delayms(10);
                    if(K3==0)
                     {
                          delayms(10);
                          //while(!K3)
                            {
                                 Th--;
                                 if(Th==100)
                                    Th=280;
                                 displaysmg(Th);  //显示设定后温度
                            }
                          }
                  }
           }
  }

void timerinit( )          //蜂鸣器断续发声定时器函数
{
  TMOD=0x01;
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  ET0=1;
  EA=1;
  TR0=0;
  Th=225;
  }

void main()
{                                         
timerinit( );               //定时器初始化函数
while(1)
{
    keyscan( );             //键盘设置函数
        tmpconvert();        //温度转换函数
        displaysmg(read_temperature( ));  //温度显示函数
        if(temp>Th)
         {         
           TR0=1;
         }
        else
        {
         TR0=0;
         Beep=1;
         //TH0=(65536-50000)/256;
    // TL0=(65536-50000)%256;
        }
  }
}
void timet0( )interrupt 1         //定时器中断,报警断续声函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
con++;
if(con==20)
  {
   con=0;
   Beep=!Beep;
}
}


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

使用道具 举报

沙发
ID:243354 发表于 2025-5-16 10:45 | 只看该作者
初次写程序,还没有用到模块化程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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