找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ds18b20单片机温控程序

[复制链接]
跳转到指定楼层
楼主
ID:77367 发表于 2015-4-19 03:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg51.h>       //调用51单片机的头文件
#include <Intrins.h>
sbit ds18b20=P3^7;
sbit OK=P3^6;
unsigned char TT,temp1,num,TL=20,TH=27;
unsigned char temp,temp2,key,dat;
unsigned char  code tabcc[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};//共阴极
unsigned char  code tabca[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00};//共阳极
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
void delay(int ms)
{
  int i;
  while(ms--)
   for(i=0;i<120;i++);
}
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
bit Reset(void)
{
   unsigned int i;
   bit k;
   ds18b20=0;            //拉低DQ总线开始复位
   i=95;          //保持DQ低大约870uS,符合不低于48US的要求
   while(i--);        //保持DQ低大约870uS,符合不低于48US的要求
                     //保持DQ低大约870uS,符合不低于48US的要求     
   ds18b20=1;        //拉高准备接收数据   
   i=9;         //大约80uS后
   while(i--);        //大约80uS后
                //大约80uS后
   k=ds18b20;          //读出数据并保存   
   i=55;          //维持约490US,符合总读时隙不低于480US的要求
   while(i--);        //维持约400US,符合总读时隙不低于480US的要求
                 //维持约400US,符合总读时隙不低于480US的要求
   return k;               //k=0为复位成功,k=1为复位失败
}
//---------------------------------------
//名称:读一字节函数
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
   unsigned char j,buf=0;
   for(j=0;j<8;j++)   //接收8次还原一个字节数据
   {
  buf=buf>>1;     //接收前,想将接收缓冲区右移
  ds18b20=0;     //拉低      
        _nop_();         //维持2US,符合大于1US小于15US的规范
        _nop_();         //维持2US,符合大于1US小于15US的规范        
        ds18b20=1;      //拉高,为读数据做准备
  _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
     _nop_();         //维持6US,符合大于1US小于15US的规范
  _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范   
  if(ds18b20==1)
       buf|=0x80;  //读出1位数据保存于buf中
    i=7;       //维持约52US,符合总读时隙不低于60US的要求
          while(i--);     //维持约52US,符合总读时隙不低于60US的要求
                   //维持约52US,符合总读时隙不低于60US的要求
}
   return buf;             //退出的同时将接收缓冲区参数返回
}
//---------------------------------------
//名称:写一字节函数
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
    unsigned char j;
    for(j=0;j<8;j++)
     {            
  if(dat&0x01)   //如果写1
         {      
      ds18b20=0;    //拉低      
            _nop_();        //维持2US,符合大于1US小于15US的规范
            _nop_();        //维持2US,符合大于1US小于15US的规范
            ds18b20=1;     //拉高        
            i=7;      //维持约63US,符合不低于60US的要求
            while(i--);    //维持约63US,符合不低于60US的要求         
      }
      else      //如果写0
         {            
   ds18b20=0;    //拉低         
            i=7;     //维持约63US,符合不低于60US的要求
            while(i--);   //维持约63US,符合不低于60US的要求               
            ds18b20=1;    //拉高         
            _nop_();        //维持2US,符合大于1US的规范
            _nop_();        //维持2US,符合大于1US的规范         
         }
   dat=dat>>1;    //写入字节右移1位
}
}
//---------------------------------------
//名称:DS18B20温度转换函数
//---------------------------------------
bit Convert(void)
{   
if(Reset()==0)          //复位DS18B20成功
   {  
     WriteByte(0xcc);  //写入跳过序列号命令字 Skip Rom
        WriteByte(0x44);  //写入温度转换命令字 Convert T  
    return 1;            //启动温度转换成功
   }
else                    //失败
   {   
    return 0;            //启动温度转换失败
   }
}
//---------------------------------------
//名称:转换结束处理函数
//---------------------------------------
void ReadFlash(void)
{   
unsigned char Lsb,Msb;
    if(Reset()==0)          //复位DS18B20成功
    {
        WriteByte(0xcc);  //写入跳过序列号命令字 Skip Rom
        WriteByte(0xbe);  //写入读取数据令字 Read Scratchpad
        Lsb=ReadByte();  //读出第一个字节暂存于LSB
        Msb=ReadByte();  //读出第二个字节暂存于MSB
    temp1=Lsb;  //temp1内装温度参数的小数部分
        temp2=Msb;//>>4)|(Lsb<<4);//temp2内装温度参数的整数部分   
    }
else
    {
  temp1=0;     //如果复位失败,温度参数清零
        temp2=0;     //如果复位失败,温度参数清零
    }
}
//---------------------------------------
void display(unsigned char ddd)
{
  P2=0x80;
  P0=0xbf;
  delay(2);
  P0=0xff;
  delay(1);
  P2=0x20;
  P0=0xbf;
  delay(2);
  P0=0xff;
  delay(1);
  
  P2=0x40;
  P0=0x7f;
  delay(2);
  P0=tabca[num]&0x7f;
  delay(1);
  P2=0x02;
  P0=tabca[ddd/10];
  delay(2);
  P0=0xff;
  delay(1);
  P2=0x01;
  P0=tabca[ddd%10];
  delay(2);
  P0=0xff;
  delay(1);
}
void keyboard()
{

}
void main(void)            //主函数,单片机开机后就是从这个函数开始运行
{
   unsigned char TT;
   EA=1;
   EX0=1;
  
   while(1)               //死循环,单片机初始化后,将一直运行这个死循环
   {     
      if(Convert()==1)       //启动转换
  {      
      ReadFlash();                //读取温度
            TT=(temp2<<4)|(temp1>>4);
   if(TT<TL)
              num=0;
   if((TT>=TL)&(TT<=TH))
     num=1;
   if(TT>TH)
     num=2;
    display(TT);
         
     }   
    }
}




#include <AT89X52.h>       //调用51单片机的头文件
#include <Intrins.h>
sbit ds18b20=P3^7;
unsigned char TT,temp1,num,TL=20,TH=27,n,TH;
unsigned char temp,temp2,OK;
unsigned char  code tabcc[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};//共阴极
unsigned char  code tabca[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00};//共阳极
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
void delay(int ms)
{
  int i;
  while(ms--)
   for(i=0;i<120;i++);
}
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
bit Reset(void)
{
   unsigned int i;
   bit k;
   ds18b20=0;            //拉低DQ总线开始复位
   i=95;          //保持DQ低大约870uS,符合不低于48US的要求
   while(i--);        //保持DQ低大约870uS,符合不低于48US的要求
                     //保持DQ低大约870uS,符合不低于48US的要求     
   ds18b20=1;        //拉高准备接收数据   
   i=9;         //大约80uS后
   while(i--);        //大约80uS后
                //大约80uS后
   k=ds18b20;          //读出数据并保存   
   i=55;          //维持约490US,符合总读时隙不低于480US的要求
   while(i--);        //维持约400US,符合总读时隙不低于480US的要求
                 //维持约400US,符合总读时隙不低于480US的要求
   return k;               //k=0为复位成功,k=1为复位失败
}
//---------------------------------------
//名称:读一字节函数
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
   unsigned char j,buf=0;
   for(j=0;j<8;j++)   //接收8次还原一个字节数据
   {
  buf=buf>>1;     //接收前,想将接收缓冲区右移
  ds18b20=0;     //拉低      
        _nop_();         //维持2US,符合大于1US小于15US的规范
        _nop_();         //维持2US,符合大于1US小于15US的规范        
        ds18b20=1;      //拉高,为读数据做准备
  _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
     _nop_();         //维持6US,符合大于1US小于15US的规范
  _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范
        _nop_();         //维持6US,符合大于1US小于15US的规范   
  if(ds18b20==1)
       buf|=0x80;  //读出1位数据保存于buf中
    i=7;       //维持约52US,符合总读时隙不低于60US的要求
          while(i--);     //维持约52US,符合总读时隙不低于60US的要求
                   //维持约52US,符合总读时隙不低于60US的要求
}
   return buf;             //退出的同时将接收缓冲区参数返回
}
//---------------------------------------
//名称:写一字节函数
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
    unsigned char j;
    for(j=0;j<8;j++)
     {            
  if(dat&0x01)   //如果写1
         {      
      ds18b20=0;    //拉低      
            _nop_();        //维持2US,符合大于1US小于15US的规范
            _nop_();        //维持2US,符合大于1US小于15US的规范
            ds18b20=1;     //拉高        
            i=7;      //维持约63US,符合不低于60US的要求
            while(i--);    //维持约63US,符合不低于60US的要求         
      }
      else      //如果写0
         {            
   ds18b20=0;    //拉低         
            i=7;     //维持约63US,符合不低于60US的要求
            while(i--);   //维持约63US,符合不低于60US的要求               
            ds18b20=1;    //拉高         
            _nop_();        //维持2US,符合大于1US的规范
            _nop_();        //维持2US,符合大于1US的规范         
         }
   dat=dat>>1;    //写入字节右移1位
}
}
//---------------------------------------
//名称:DS18B20温度转换函数
//---------------------------------------
bit Convert(void)
{   
if(Reset()==0)          //复位DS18B20成功
   {  
     WriteByte(0xcc);  //写入跳过序列号命令字 Skip Rom
        WriteByte(0x44);  //写入温度转换命令字 Convert T  
    return 1;            //启动温度转换成功
   }
else                    //失败
   {   
    return 0;            //启动温度转换失败
   }
}
//---------------------------------------
//名称:转换结束处理函数
//---------------------------------------
void ReadFlash(void)
{   
unsigned char Lsb,Msb;
    if(Reset()==0)          //复位DS18B20成功
    {
        WriteByte(0xcc);  //写入跳过序列号命令字 Skip Rom
        WriteByte(0xbe);  //写入读取数据令字 Read Scratchpad
        Lsb=ReadByte();  //读出第一个字节暂存于LSB
        Msb=ReadByte();  //读出第二个字节暂存于MSB
    temp1=Lsb;  //temp1内装温度参数的小数部分
        temp2=Msb;//>>4)|(Lsb<<4);//temp2内装温度参数的整数部分   
    }
else
    {
  temp1=0;     //如果复位失败,温度参数清零
        temp2=0;     //如果复位失败,温度参数清零
    }
}
//---------------------------------------
void display(unsigned char ddd)//显示
{
  P2=0x80;
  P0=0xbf;
  delay(2);
  P0=0xff;
  delay(1);//左-
  P2=0x20;
  P0=0xbf;
  delay(2);
  P0=0xff;
  delay(1);//右-
  
  P2=0x40;
  P0=tabca[num];//两杠中间显示区间编号
  delay(2);
  P0=0xff;
  delay(1);
  P2=0x02;
  P0=tabca[ddd/10];//显示温度十位
  delay(2);
  P0=0xff;
  delay(1);
  P2=0x01;
  P0=tabca[ddd%10];//显示温度个位
  delay(2);
  P0=0xff;
  delay(1);
}
void desplay(void)//调试显示
{
  P2=0x80;
  P0=0xbf;
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x40;
  P0=tabca[n];
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x20;
  P0=0xbf;
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x10;
  P0=tabca[TH1];
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x08;
  P0=tabca[TH0];
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x04;
  P0=0xbf;
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x02;
  P0=tabca[TL1];
  delay(1);
  P0=0xff;
  _nop_();
  P2=0x01;
  P0=tabca[TL0];
  delay(1);
  P0=0xff;
  _nop_();
}
void xswd()
{
      if(Convert()==1)       //启动转换
  {      
      ReadFlash();                //读取温度
            TT=(temp2<<4)|(temp1>>4);
   if(TT<TL)
              num=0;
   if((TT>=TL)&(TT<=TH))
     num=1;
   if(TT>TH)
     num=2;
    display(TT);         
     }   
}
void xssz()
{
  desplay();
}
void main(void)            //主函数,单片机开机后就是从这个函数开始运行
{
   bit ss;
   ss=P2^3;
   EA=1;
   EX0=1;
   EX1=1;
   IT1=1;
   IT0=1;
   PX0=1;
   PX1=0;
   OK=0;
   
   while(1)               //死循环,单片机初始化后,将一直运行这个死循环
   {      
      P1=0xfe;
      delay(2);
      P1=0xfd;
      delay(2);
      P1=0xfb;
      delay(2);
      P1=0xf7;
      delay(2);
     if(OK==0)        
      xswd();
     else
       desplay();      
    }
}
void intsvr0(void) interrupt 0 using 0
{
  unsigned char key;      
  OK++;
  P1=0xfe;
  if(P1_4==0) key=1;
  else if(P1_5==0)key=2;
  else if(P1_6==0)key=3;
  else if(P1_7==0)key=4;

  P1=0xfd;
  if(P1_4==0)key=5;
  else if(P1_5==0)key=6;
  else if(P1_6==0)key=7;
  else if(P1_7==0)key=8;

  P1=0xfb;
  if(P1_4==0)key=9;
  else if(P1_5==0)key=10;
  else if(P1_6==0)key=11;
  else if(P1_7==0)key=12;

  P1=0xf7;
  if(P1_4==0)key=13;
  else if(P1_5==0)key=14;
  else if(P1_6==0)key=15;
  else if(P1_7==0)key=16;
  
  if(n==1)TH1=key;
  if(n==2)TH0=key;
  if(n==3)TL1=key;
  if(n==4)TL0=key;
}
void intsvr2(void) interrupt 2 using 2
{
  OK++;
  n++;
  if(n==5)
   {
    TH=TH1*10+TH0;
    TL=TL1*10+TL0;
   }
  if(n==6)
    {
  OK=0;
  n=0;
}  
}



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

使用道具 举报

沙发
ID:65232 发表于 2015-4-19 10:12 | 只看该作者
做个记号
回复

使用道具 举报

板凳
ID:65916 发表于 2015-4-19 10:55 | 只看该作者
感谢楼主分享
回复

使用道具 举报

地板
ID:121305 发表于 2016-5-24 18:19 | 只看该作者
感谢感谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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