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

📄 18b20.c

📁 51单片机控制温度传感器DS18B20,4位数码管显示温度
💻 C
字号:
#include "reg52.h"

#include"intrins.h"
#define  uch unsigned char                     //给unsigned char起别名 uch

#define NOP()  _nop_ ()
bit     read_flag=0;
sbit  BEEP=P1^3;
sbit  relay=P1^2;
sbit  clk=P1^0;
sbit  din=P1^1;
sbit DQ=P2^0;
unsigned char  code ledcode[]={0x11,0x7D,0x23,0x29,0x4D, 0x89,0x81,0x3D,0x01,0x09,0x05,\
0xc1,0x8f,0x61,0x83,0x87}; //数码管段码


//实验目的:熟悉DS18B20的使用
//4位数码管显示温度结果,其中整数部分2位,小数部分2位
//每次按下RB0键后进行一次温度转换。
//硬件要求:把DS18B20插在18B20插座上
//          拨码开关S10第1位置ON,其他位置OFF
//          拨码开关S5、S6全部置ON,其他拨码开关全部置OFF


 

 unsigned char  TLV=0 ;                        //采集到的温度高8位
 unsigned char  THV=0;                         //采集到的温度低8位
 unsigned char TZ=0;                           //转换后的温度值整数部分
 unsigned char TX=0;                           //转换后的温度值小数部分
 unsigned int wd;                              //转换后的温度值BCD码形式

unsigned char shi;                             //整数十位
unsigned char ge;                              //整数个位
unsigned char shifen;                          //十分位
unsigned char baifen;                          //百分位
unsigned char qianfen;                         //千分位
unsigned char wanfen;                          //万分位

//------------------------------------------------
//延时函数
void delay(char x,char y) 
{
  char z;
  do{
      z=y;
      do{;}while(--z);
     }while(--x);
 }
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。

//--------------------------------------------------
//结果显示函数

//系统初始化函数
void  leddisp(unsigned char num)
    {
	 unsigned char i,k;
	 k=ledcode[num];
	 for(i=0;i<8;i++)
	    {
	     if((k&0x01)==0x01)	
		 din=1;
		 else 
		 din=0;
		 clk=0;
		 clk=1;
		 k>>=1;
		 	
		}
	
	}

//-----------------------------------------------
//复位DS18B20函数
void reset(void)
{
 bit presence=1;


  while(presence==1)
  { 
    DQ=0 ;                                //主机拉至低电平
    delay(2,70);                              //延时503us
   DQ=1;                                //释放总线等电阻拉高总线,并保持15~60us
    delay(2,7);                               //延时70us
    if(DQ==1) presence=1;                     //没有接收到应答信号,继续复位
    else presence=0;                          //接收到应答信号
    //delay(2,60);   //延时430us
delay(2,60); 
   }
 BEEP=1;
  }

//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
 uch i;
 uch temp;
 for(i=8;i>0;i--)
 {
   temp=val&0x01;                            //最低位移出
   DQ=0; 
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                    //从高拉至低电平,产生写时间隙
   if(temp==1)  DQ=1;                   //如果写1,拉高电平
   delay(2,7);                               //延时63us
   DQ=1; 
   NOP();
   NOP();
   val=val>>1;                               //右移一位
  }
}

//------------------------------------------------
//18b20读字节函数
uch read_byte(void)
{
 uch i;
 uch value=0;                                //读出温度
 static bit j;
 for(i=8;i>0;i--)
 {
   value>>=1; 
   DQ=0;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                   //6us
   DQ=1;                               //拉至高电平
   NOP(); 
   NOP();
   NOP();  
   NOP(); 
   NOP();                                  //4us
   j=DQ;
   if(j) value|=0x80;
   delay(2,7);                             //63us
  }
  return(value);
}

//-------------------------------------------------
//启动温度转换函数
void get_temp()
{ 
int i;
DQ=1;
reset();                                 //复位等待从机应答 
write_byte(0XCC);                        //忽略ROM匹配 
write_byte(0X44);                        //发送温度转化命令  
for(i=50;i>0;i--)
    {
        
       // display();                       //调用多次显示函数,确保温度转换完成所需要的时间
    }
reset();                                 //再次复位,等待从机应答 
write_byte(0XCC);                        //忽略ROM匹配 
write_byte(0XBE);                        //发送读温度命令 
TLV=read_byte();                         //读出温度低8 
THV=read_byte();                         //读出温度高8位 
DQ=1;                                     //释放总线 
TZ=(TLV>>4)|(THV<<4)&0X3f;               //温度整数部分
TX=TLV<<4;                               //温度小数部分
if(TZ>100)TZ/100;                       //不显示百位
ge=TZ%10;//个位                          //整数部分个位
shi=TZ/10;//十位                         //整数十位
wd=0;  
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625;                //以上4条指令把小数部分转换为BCD码形式             
shifen=wd/1000;                          //十分位                    
baifen=(wd%1000)/100;                    //百分位
qianfen=(wd%100)/10;                     //千分位
wanfen=wd%10;                         //万分位
NOP();
NOP();
}

//--------------------------------------------------
//主函数
void main()
{
   while(1)
     {
       get_temp();   //调用温度转换函数      
      leddisp(shi);    //调用结果显示函数 ,温度十位
      leddisp(ge);    //温度个位
      leddisp(shifen);//温度十分位
      leddisp(baifen);//温度百分位
	  delay(200,200); //调用延时函数
	  delay(200,200);
	  delay(200,200);
	  delay(200,200);
     }
}

⌨️ 快捷键说明

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