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

📄 db18b20.c

📁 DS18B20与AT89C4051驱动程序,解决了许多网站上出现的有些错误代码,现用在家里测温,直接可用
💻 C
字号:
/*   MCU:89C4051  P1.0,P1.1接10K左右上拉电阻,晶振11.0592M


/*  sbit DQ=P3^7;        89C4051的11脚接DS18B20      */

#include <reg52.h>
#include <stdio.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int
#define _Nop() _nop_();
#define Disdata P1             //段码输出口
#define Discan  P3             //扫描口

uint h;


uint temp;
sbit DQ=P3^7;
sbit DIN=P1^7;

//********温度小数部分用查表法*******//
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};
////*共阳LED段码表      0    1    2   3    4    5    6     7    8    9   不亮  -  */
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7};  //列扫描控制字
uchar data temp_data[2]={0x00,0x00};   //读出温度暂放
uchar display[5]={0x08,0x08,0x08,0x0b,0x00};//显示单元数据,共4个数据,一个运算暂存用

/***************11us延时函数******************/ 
//--------------------------------------------------------------------------------------------------
// 函数名称: delay
// 入口参数: N
// 函数功能:延时子程序,实现(16*N+24)us的延时 
// 系统采用11.0592MHz的时钟时,延时满足要求,其它情况需要改动
//--------------------------------------------------------------------------------------------------
void delay(uint t)
 {
 	int i;
 	for(i=0;i<t;i++);
 }

/******************显示扫描函数******************/
scan()
{
	char k;
	for(k=0;k<4;k++)            //4位LED扫描控制
	{
		Disdata=dis_7[display[k]];
		if(k==1) {DIN=0;}
	    Discan=scan_con[k];delay(120);Discan=0xff;
	}
}
/*************DS18B20复位函数*****************/
 
 uchar ow_reset(void)
 {
   	
   uchar deceive_ready;
   DQ=0;                               //拉低DQ线  
   delay(35);                          //延时至少480us~960us(471uS)
   DQ=1;                               //将DQ线设置位逻辑高    
   delay(3);                           //延时等待deceive_ready响应 (54uS)
   deceive_ready=DQ;                   //采样deceive_ready信号
   delay(25);                          //等待时序结束 (340uS)
   return(deceive_ready);              //有deceive_ready信号时返回0,否则返回1
 }
 
 /************DS18B20写命令函数******************/ 
 //--------------------------------------------------------------------------------------------------
// 函数名称: write_bit
// 入口参数: bitval
// 函数功能:写一个bit子程序 
//--------------------------------------------------------------------------------------------------
void write_bit(unsigned char bitval)
  {
    DQ=0;                            //拉低DQ线开始时序
    if(bitval==1)
    DQ=1;                             //如果写逻辑为高
    delay(5);                         //延时  (80uS)
    DQ=1;                             //升高DQ线 
}
 //向1-WIRE总线上写1个字节
 
 void write_byte(uchar val)
 {
 	uchar i,temp;
 	for(i=0;i<8;i++)
 	{
	  temp=val>>i;                         //将val位右移i位赋值给比temp
      temp=temp&0x01;                      //取temp最低位
      write_bit(temp);
      delay(5);                           //延时至时序结束	(80uS)
     }
 }

 
 /************DS18B20读命令函数******************/ 
 //--------------------------------------------------------------------------------------------------
// 函数名称:read_bit
// 入口参数: 无
// 返回接收的数据
// 函数功能:读一个bit子程序 
//--------------------------------------------------------------------------------------------------
unsigned char read_bit(void)
{
 unsigned char i;
 DQ=0;                                 //拉低DQ线开始时序
 DQ=1;                                 //升高DQ线                        
 for(i=0;i<3;i++);					    //延时至时序开始15us
 return(DQ);                           //返回DQ值
}
//--------------------------------------------------------------------------------------------------
// 函数名称: read_byte
// 返回接收的数据 value
// 函数功能:读一个byte子程序 
//--------------------------------------------------------------------------------------------------
unsigned char read_byte(void)
{unsigned char i,m,receive_data;
   m=1;receive_data=0;                          //初始化
   for(i=0;i<8;i++)
   {
    if(read_bit()) 
    {
     receive_data=receive_data+(m<<i);
     }                                            //每读一位数据据,左移一位  
   delay(6);                                    //延时至时序结束 (93uS)
   }  
 return(receive_data);                           //返回value
}
 		 
 /*******************读出温度函数******************/ 
 
 read_temp()
 {
 	ow_reset();                                     //总线复位
 	write_byte(0xCC);                               //发出跳过ROM命令
 	write_byte(0xBE);                               //发读命令
    temp_data[0]=read_byte();                       //温度低8位
    temp_data[1]=read_byte();                       //温度高8位
    ow_reset();                                     //总线复位 */
 	write_byte(0xCC);                               //发出跳过ROM命令
 	write_byte(0x44);                               //发转换命令
 }

 /*****************温度处理函数******************/ 
 
 work_temp()
 {
 	uchar n=0;
 	if(temp_data[1]>127)
 		{temp_data[1]=(~temp_data[1]);temp_data[0]=((~temp_data[0])+1);n=1;} 
 	//temp_data[0]=0x91;	  temp_data[1]=0x01;  */
	//temp=temp_data[0]&0x0f;  //作为暂存
	//display[0]=ditab[temp];  //小数部分查表法
	//temp=((temp_data[0]>>4)|((temp_data[1]&0x07)<<4));
 	temp=(temp_data[0]>>4)|((temp_data[1]&0x07)<<4);
	display[3]=temp/100;              //百位
    display[2]=temp%100/10;          //十位
	display[1]=temp%10;              //个位
	temp=(temp_data[0]&0x0f)*625;    
	display[0]=temp/1000;	         //小数

  
  if(n)							         //温度为负数
   {
	if(!display[2])					     //十位为0
	   {
		display[3]=0x0a;				 //百位不显示
		display[2]=0x0b;			     // 十位显示负号
	   }        
	else
	   display[3]=0x0b;				    //否则百位上显负号
   }
   else								    //温度为正数
   {
    if(!display[3])						   //百位为0
     {
       display[3]=0x0a;                   //dis_7[display[3]]=dis_7[10]=0xFF,为不显示
      if(!display[2])					  //十位为0
      {
       display[2]=0x0a;					  //十位不显示
	  }
    } 
   }	                             
}

/**************************************/
/*               主函数               */
/**************************************/ 

 main()
{
  Disdata=0xff;
  Discan=0xff;

  ow_reset();                    //开机复位
  write_byte(0xCC);              //跳过ROM
  write_byte(0x44);              //发出转换命令
  
  for(h=0;h<150;h++)	             //开机显示2秒的“8888”
  {
   scan();
  }
  
  while(1)
  {
   read_temp();                  //读出DS18B20温度数据
   work_temp();                  //处理温度数据 	
   scan();                      //调用显示子程序 
 } 
} 

⌨️ 快捷键说明

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