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

📄 ds18b20.c

📁 用DS18B20测温度
💻 C
字号:
#include<reg51.h>
#include<intrins.h>  //_nop_();延时函数用;
#define Disdata  P0   //段码输出口
#define discan   P2   //扫描口
#define uchar unsigned char 
#define uint  unsigned int 
sbit DQ=P1^0;        //温度输入口
sbit DIN=P0^7;        //led 小数点控制
sbit P20=P2^0;
sbit P37=P3^7;
uint h,count,jingjie1,jingjie2,jingjie;
uchar sound;
//****温度小数部分用查表法***//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,
 0x08,0x08,0x09,0x09};
uchar code dis_7[12]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
/*"0","1", "2"   "3"  "4"   "5"  "6" "7" "8"  "9" "不亮" "-"*/
uchar code scan_con[4]={0x80,0x40,0x20,0x10}; //位控
uchar data temp_data[2]={0x00,0x00};          //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个,一个运算暂存用

/***11us延时函数****/
void delay(uint t)
{
 for(;t>0;t--);
}

/***显示扫描函数***/
scan()
{
 char k;
   for(k=0;k<4;k++)
   {
    Disdata =dis_7[display[k]];
	if(k==1){DIN=0;}
	discan=scan_con[k];delay(90);discan=0x00;
	}
  }

/****DS18B20复位函数***/
ow_reset(void)
{
 char presence =1;
 while(presence)
 {
  while(presence)
  {
   DQ=1;_nop_();_nop_();
   DQ=0;
   delay(50);
   DQ=1;
   delay(6);
   presence=DQ;
   }
  delay(45);
  presence=~DQ;
 }
 DQ=1;
}

/****DS18B20写命令函数****/
void write_byte(uchar val)
{
 uchar i;
 for(i=8;i>0;i--)
 {
  DQ=1;_nop_();_nop_();
  DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//延时5us
  DQ=val&0x01;        //取出最低位
  delay(6);
  val=val/2;
 }
 DQ=1;
 delay(1);
}

/******DS18B20读1字节函数****/
uchar read_byte(void)
{
 uchar i;
 uchar value =0;
 for(i=8;i>0;i--)
 {
  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()
 {
  ow_reset();
  write_byte(0xcc);
  write_byte(0xbe);
  temp_data[0]=read_byte();
  temp_data[1]=read_byte();
  ow_reset();
  write_byte(0xcc);
  write_byte(0x44);
 }

 /****温度数据处理函数*****/
 work_temp()
 {
  uchar n=0;
  if(temp_data[1]>127)
  //以下一行是负温度求补码
   {temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1;}
  
  display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];
  //显示小数一位,由于小数是16进制,所以要简化成10进制--ditab
  jingjie2=display[4];
  display[4]= ((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
              //右移4位变成低四位   "或合并"   左移4位变成高四位 
  jingjie1=display[4];
  jingjie=(jingjie1<<4)|(jingjie2);
  display[3]=  display[4]/100;
  display[1]=  display[4]%100;
  display[2]=  display[1]/10;
  display[1]=  display[1]%10;
  if(! display[3]){ display[3]=0x00;if(! display[2]){display[2]=0x00;}}
  //最高位为0时都不显示
  if(n){display[3]=0x40;}
 }
/****中断获得发声频率*****/ 
void initial()
{
 TMOD=0x01;
 TH0=(65536-500)/256;
 TL0=(65536-500)%256;
 EA=1;
 ET0=1;
 TR0=0;
}
 /****主函数*****/
 main()
 {initial();
  P37=0;
  Disdata=0x00;
  discan=0x00;                      //初始化端口
  for(h=0;h<4;h++){ display[h]=8;}  //开机显示888
  ow_reset();                       //开机先转换一次
  write_byte(0xcc);
  write_byte(0x44);
  for(h=0;h<500;h++)
   {scan();}
  while(1)
  {TR0=0;
   P37=0;
   read_temp();
   work_temp();
   for(h=0;h<250;h++)          //显示温度1s
   {scan();
    if((jingjie1>=25&jingjie2>=1)|jingjie1>=26){TR0=1;}
    //只要温度超过25.1度就会响铃
	}                    
  }
 }

void tO(void) interrupt 1
{TH0=(65536-100)/256;
 TL0=(65536-100)%256;
P37=~P37;
}












⌨️ 快捷键说明

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