⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20a.c

📁 ds18b20温度检测
💻 C
字号:
//*************DS18B20数字温度计*******************//
//*MCU:          AT892051                          //
//*MCU-crystal:  12M                               //
//*Version:      01                                //
//*Last Updata:  2007-6-9                          //
//*Author:       zhaojun                           //
//*Description:                                    //
//DS18B20的读写程序,数据脚P3.4                     //
//温度传感器18B20汇编程序,采用器件默认的12位转化   //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值            //
//P1口为段码输入,P0~P3为位选                       //
//***************WAVE-E6000/T**********************//
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
#define Disdata  P1         // 段码入口
sbit DQ=P3^4;               // 温度输入口
uint temp;                  // variable of temperature  定义一个变量
uchar flag1;                // 定义一个标志,标志温度是负还是正,1为负,0为正
sbit DIN=P1^7;              // 小数点控制 
uchar h;                    // 定义变量
//位选位定义
sbit DEC=P3^0;              // 小数
sbit POS=P3^1;              // 个位
sbit TEN=P3^2;              // 十位
sbit HUN=P3^3;              // 百位,符号位

unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; 
//共阳数码管段码表           "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "灭"  "-"

unsigned char code table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的编码
//共阳数码管带小数点段码表    "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" 

uchar data temp_data[2]={0x00,0x00};//读出温度暂放

uchar data Dis_play[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算暂用

uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//小数部分对应十进制   "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "A"  "B"  "C"  "D"  "E"  "F"

/***************************************/
/*        延时子程序                   */
/***************************************/
 void delay(uint i)      //delay   
   {
      while(i--);
   }

/************************************************/
/*          初始化ds18b2子函数*                 */
/************************************************/
 Init_DS18B20(void)
  {
     uchar x=0;
     DQ = 1;               //DQ复位
     delay(8);             //稍做延时
     DQ = 0;               //单片机将DQ拉低
     delay(80);            //精确延时 大于 480us
     DQ = 1;               //拉高总线
     delay(14);
     x=DQ;                 //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
     delay(20);
  }


/*************************************************/
/*              读字节子函数                     */
/*************************************************/
 ReadOneChar(void)
  {
     uchar i = 0;
     uchar dat = 0;
   for (i=8;i>0;i--)
    {
      DQ = 0;              // 给脉冲信号
      dat>>=1;             // 数据右移一位
      DQ = 1;              // 给脉冲信号
      if(DQ)               // DQ为1
      dat|=0x80;          // 读出数据
      delay(4);            // 延时
     }
   return(dat);
  }
/*************************************************/
/*               写字节子函数                    */
/*************************************************/
 WriteOneChar(unsigned char dat)
  {
    uchar i = 0;
    for (i=8; i>0; i--)
     {
       DQ = 0;
       DQ = dat&0x01;   //写入一位数据
       delay(5);
       DQ = 1;
       dat>>=1;        //右移一位数据
     }
  }

/*************************************************/
/*           DS18B20写命令函数                   */
/*************************************************/
/*void tmpwritebyte(uchar dat)   // write a byte to ds18b20 
  {                              // 给温度传感器写一个字节
    uint i;
    uchar j;
    bit testb;
    for(j=1;j<=8;j++)
     {
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)     //写入 1
          {
             DQ=0;
             i++;i++;
             DQ=1;
             i=8;while(i>0)i--; // 适当延时
          }
        else          //写入 0
          {
             DQ=0;       
             i=8;while(i>0)i--; // 适当延时
             DQ=1;
             i++;i++;
          }
      }
  }*/

/******************************************/
/*         发送温度转换命令               */
/******************************************/
void tmpchange(void)          // DS18B20 begin change   
{
  Init_DS18B20();             // 初始化DS18B20
  delay(200);                 // 延时
  WriteOneChar(0xcc);         // 跳过序列号命令
  WriteOneChar(0x44);         // 发送温度转换命令
}
/******************************************/
/*            读出温度函数                */
/******************************************/
uint tmp()                    //get the temperature
{
//  float tt;
  Init_DS18B20();             // 初始化ds18b2子函数 
  delay(1);
  WriteOneChar(0xcc);         // 跳过ROM命令
  WriteOneChar(0xbe);         // 发送读取数据命令
  temp_data[0]=ReadOneChar(); // 连续读两个字节数据
  temp_data[1]=ReadOneChar();
  temp=temp_data[1];
  temp<<=8;                                               
  temp=temp|temp_data[0];     // 两字节合成一个整型变量。
//  tt=temp*0.0625;           // 得到真实十进制温度值,因为DS18B20
                              // 可以精确到0.0625度,所以读回数据的最低位代表的是
                              // 0.0625度。
//  temp=tt*10+0.5;           // 放大十倍,这样做的目的将小数点后第一位
                              // 也转换为可显示数字,同时进行一个四舍五入操作。
  return temp;                // 返回温度值
}
/******************************************/
/*        读出序列号函数                  */
/******************************************/
/*void readrom()              // read the serial 读取温度传感器的序列号
{                             // 本程序中没有用到此函数
  uchar sn1,sn2;
  Init_DS18B20();             // DS18B20初始化
  delay(1);
  WriteOneChar(0x33);         // Read ROM
  sn1=ReadOneChar();          // 8位系列编码
  sn2=ReadOneChar();          // 8位CRC码
}*/
/******************************************/
/*           显示延时函数                 */
/******************************************/
//延时时,主要时间的控制,否则会不断闪烁
void delay_ms()   
  {
    uchar a,b;
    for(a=50;a>0;a--)
      for(b=40;b>0;b--);
   }
/******************************************/
/*       温度数据显示处理函数             */
/******************************************/
void tem_deal(uint tem)
  {
/*************温度数据处理*****************/
   if(tem>6348)                       // 温度值正负判断
     {tem=65536-tem;flag1=1;}         // 负温度求补码,标志位置1
      Dis_play[4]=tem&0x0f;           // 取小数部分的值
	  Dis_play[0]=ditab[Dis_play[4]]; // 存入小数部分显示值
      Dis_play[4]=tem>>4;             // 取中间八位,即整数部分的值
	  Dis_play[3]=Dis_play[4]/100;    // 取百位数据暂存
	  Dis_play[1]=Dis_play[4]%100;    // 取后两位数据暂存
	  Dis_play[2]=Dis_play[1]/10;     // 取十位数据暂存
	  Dis_play[1]=Dis_play[1]%10;     // 取个位数据暂存

   if(!Dis_play[3])       // 最高位为0都不显示
   {
      Dis_play[3]=0x0a;   // 先判断百位是否为0
	   if(!Dis_play[2])
	  {
	    Dis_play[2]=0x0a; // 再判断十位是否为0
	  }
   }

   if(flag1)
   {
      Dis_play[3]=0x0b;    // 为负数时,最高位显示 "-"
   }
  }

/******************温度数据显示********************/
 void display()
  {
      Disdata=table[Dis_play[3]];   // 输入百位显示数据
      HUN=0;TEN=1;POS=1;DEC=1;      // 开百位,关其他位
      delay_ms();                   // 适当延时

      Disdata=table[Dis_play[2]];   // 输入十位显示数据
      TEN=0;HUN=1;POS=1;DEC=1;      // 开十位,关其他位
      delay_ms();                   // 适当延时

      Disdata=table1[Dis_play[1]];  // 输入个位显示数据
      POS=0;HUN=1;TEN=1;DEC=1;      // 开个位,关其他位
      delay_ms();                   // 适当延时

      Disdata=table[Dis_play[0]];   // 输入小数显示数据
      DEC=0;HUN=1;TEN=1;POS=1;      // 开小数位,关其他位
 //     delay_ms();                   // 适当延时
  }
/******************************************/
/*               主函数                   */
/******************************************/
 void main()
 {
  Disdata=0xff;   //端口初始化
  P3=0xff;
//开机显示"888.8";这段程序可以不要.
    for(h=0; h<4; h++)
     {  
          Dis_play[h]=8;
     }
    for(h=0; h<50; h++) 
     {       
	      display();  //显示数据
          delay_ms(); //延时
     }
//温度显示
   do
   {
     tmpchange();      //温度转换
     tem_deal(tmp());  //显示温度值
     display();
   }
     while(1);
 }


//*****************结束**********************//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -