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

📄 temper.c

📁 利用89S51单片机
💻 C
字号:
/***********************************************************
*函数功能:通过DS18B20温度传感器测得当前的温度值,再送入4位8段数码管显示
*创建者:  曹兴
*创建日期:2008-10-2
*版本号:  20081002
***********************************************************/
#include"reg51.h"
#include "intrins.h"
/*******************宏定义*********************************/
#define  TH0_value  0x3C
#define  TL0_value  0xB0
#define  TMOD_value 0x01
#define  TCON_value 0x15
#define  IE_value   0x82
#define  P0_value   0x0ff
/*******************端口定义及开辟相应的存储单元***********/
sbit  DQ = P2^2;	            //DS18B20单总线接入点          
bit   flag  ;		            //检测芯片是否存在的标志位
bit   singal;			    	//符号位
sbit  b=P1^0;		            //芯片存在P1.0置0点亮LED灯
sbit  c=P1^1;					//芯片不存在P1.1置0点亮LED灯
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};	
                                //8段数码管0~9数字的共阳显示代码
unsigned char  buf[3] ;	    //存储转换后温度的高8位与低8位  	
unsigned char  buf1[3];
unsigned char  temper_value;  //存储转化后温度的结果值
/********************************************************** 
* 函数名:  延时子函数delay		
* 函数功能:延时
* 入口参数:i
* 出口参数:无 
***********************************************************/
 void delay(unsigned char i)
{
  while(--i);
 }
/********************************************************** 
* 函数名:  初始化子函数	reset_signal
* 函数功能:信号复位进行初始化
* 入口参数:无
* 出口参数:无 
***********************************************************/
reset_signal()
{
 DQ = 1;
 _nop_();
 DQ = 0;						 //主机发送复位脉冲至少持续480uS
 delay(250);                     //480uS~960uS之间
 DQ = 1;
 delay(20);				         //延时至少16uS
 flag = DQ;						 //DS18B20	等待16uS后发送存在脉冲(低电平)持续60uS~240uS
 if(flag==0)					 //若flag=0则表示存在
 {
  b = 0;						 //P1.0亮
  delay(90);				     //延时60uS~240uS之间
 }
 else  c=0;						 //不存在则P1.1亮
 DQ = 1; 
}
/********************************************************** 
* 函数名:  写命令子函数 w_order
* 函数功能:写入将要执行操作的命令
* 入口参数:cmd
* 出口参数:无 
***********************************************************/
void  w_order(unsigned char cmd)
{
 unsigned char i;
 for(i=0;i<8;i++)
 {
  if(cmd&(0x01<<i))				 //写1
  {
   DQ = 0;						 //主机将数据线拉至低电平产生写时间片
   _nop_();						 //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
   _nop_();						 //15uS内必须拉至高电平(因为DS18B20在15uS~60uS之间对数据线进行采样)
   DQ = 1;
   delay(28);					 //延时60uS(因为一个写周期至少延时60uS)
  }
  else 							 //写0
  { 
   DQ = 0;						 //主机将数据线拉至低电平产生写时间片
   delay(40);					 //延时60uS以上(因为一个写周期至少延时60uS)
   DQ = 1;
   _nop_();						 //恢复延时(因为个写周期之间至少有1uS的恢复时间)	
   _nop_();
   _nop_();
   _nop_();
  }	
  }	  
}
/********************************************************** 
* 函数名:  读数据子函数 r_data
* 函数功能:读出转换后的温度结果存入 buf 中
* 入口参数:无
* 出口参数:无 
***********************************************************/
void   r_data()
{
 unsigned int i,j;	
 for(j=0;j<2;j++)
 {
  buf[j] = 0;
  for(i=0;i<8;i++)				
  {
   DQ = 1;
   _nop_();
   DQ = 0;						 //主机将数据线拉至低电平产生读时间片
   _nop_();						 //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
   _nop_();						 //15uS内必须驱动至高电平(因为DS18B20输出数据在读时间片下降沿后15uS有效)
   DQ = 1;
   _nop_();
   if(DQ)                        //提高总线后马上读取
   {
    buf[j]|=(1<<i);
   }
   else
   {
    buf[j]&=~(1<<i);
   }
   delay(28);					 //每个读周期至少持续60uS
   DQ = 1;				 
   _nop_();						 //恢复延时(因为个读周期之间至少有1uS的恢复时间)
   }  
  } 
 }
/********************************************************** 
* 函数名:  获取温度子函数 get_temper_value
* 函数功能:获得当前的温度值 
* 入口参数:无
* 出口参数:无 
***********************************************************/
 void  get_temper_value()
{
 DQ = 1;
 reset_signal();				 //初始化 ,检测是否存在 DS18B20
 if(flag==0)					 
 {
  w_order(0xcc);				 //跳过ROM
  w_order(0x44);				 //启动温度变换 
  reset_signal();				 //复位
  w_order(0xcc);				 //跳过ROM
  w_order(0xbe);				 //准备读暂存器
  r_data();						 //读暂存器中温度变化的结果 
 }
}
/********************************************************** 
* 函数名:  二-十进制转换子函数Conversion
* 函数功能:将二进制数转入十进制中
* 入口参数:无 
* 出口参数:无 
***********************************************************/
void Conversion() 
{
 singal = (buf[1]&0xf8);		 //检温度测是正还是负
 buf1[2] = 0;					 //温度的符号位 
 if(singal)
 {
  buf[0]=~buf[0];
  buf[1]=~buf[1];
  buf1[2]=10;
 } 
 buf[0]=(buf[0]>>4);			 //将温度转换结果的低8位的高4位移入低4位  
                                 //这里我们抛弃了温度转换结果的第四位(小数部分,因为我们不需要那么准确)
 buf[0]=(buf[0]&0x0f);			 //保留低4位并存入buf[0]中  
 buf[1]=(buf[1]<<4);			 //将温度转换结果的高8位的低4位移入高4位
 buf[1]=(buf[1]&0xf0);			 //保留高4位并存入buf[1]中
 temper_value=(buf[0]|buf[1]);	 //将buf[0]与buf[1]相或得温度转换结果存入temper_value中
 if(singal)
 {temper_value++;}				 //为负时取反加1
 buf1[0]=temper_value%10;		 //将个位保存在buf1[0]中
 buf1[1]=temper_value/10;		 //将十位保存在buf1[1]中
}
/********************************************************** 
* 函数名:   LED显示子函数display
* 函数功能:将获得的温度结果通过LED显示
* 入口参数:无 
* 出口参数:无 
***********************************************************/
void display()
{
 unsigned  char i,a;
 long int j;
 for(i=0;i<3;i++)
 {
  P2=~(0x10<<i);				 //动态扫描显示 
  a =buf1[i];
  P0=~tab[a];					 //P0口输出显示数据
  for(j=400;j>0;j--);
 }
}

/********************************************************** 
* 函数名:  中断函数timer0
* 函数功能:定时对DS18B20的转换温度进行更新
* 入口参数:无 
* 出口参数:无 
***********************************************************/
void timer0(void)  interrupt 1  using  0
{
 TH0 =TH0_value;
 TL0 =TL0_value;
 get_temper_value();
 Conversion();
}
/********************************************************** 
* 函数名:  主函数main		
* 函数功能:通过温度传感器测当前室温
* 入口参数:无
* 出口参数:无 
***********************************************************/ 
void main()
{
 TMOD=TMOD_value;
 TH0 =TH0_value;
 TL0 =TL0_value;
 TCON=TCON_value;
 IE  =IE_value ;
 P0  =P0_value;
 while(1)
 {	         
  display();					 //将当前温度值送入LED显示
 }
 }

⌨️ 快捷键说明

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