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

📄 ddddd.c

📁 基于数字温度传感器DS18B20的温度采集测量
💻 C
字号:
#include <REG52.H>
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int

sbit DQ=P2^4;                //DS18B20接口

sbit LED_CLK=P2^2;           //74HC595输入时钟脉冲
sbit SERD=P0^3;              // 小数位输入
sbit SERP=P0^2;              // 个位输入
sbit SERT=P0^1;              // 十位输入
sbit SERH=P0^0;              // 百位,符号位输入
sbit RCKD=P0^7;              // 小数位输出时钟脉冲
sbit RCKP=P0^6;              // 个位输出时钟脉冲
sbit RCKT=P0^5;              // 十数位输出时钟脉冲
sbit RCKH=P0^4;              // 百位,符号位输出时钟脉冲

sbit Set1=P3^2;              //上限温度设定
sbit Set2=P3^3;              //下限温度设定
sbit Bit=P1^0;               //位选择
sbit Up=P1^1;                //所选位加1
sbit Down=P1^2;              //所选位减1
sbit Out=P1^3;               //退出设定
sbit alm=P2^3;               //报警信号

uint temp_value,tempV;       //温度值
uchar flag1;                 //所测温度为负数的标志位
char tempsh=40,tempsl=10,sym=1; //温度上下限及符号位
uchar count,tbit,intr;       //设定模式标志位

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

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; 
//共阴数码管段码表           "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "灭"  "-"

unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//带小数点的编码
//共阴数码管带小数点段码表    "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" 
 

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"


//***********ds18b20延迟子函数(晶振12MHz )*******//
void delay_18B20(unsigned int i)
{
	while(i--);
}
//************************************************//

//******************延时子程序********************//
void delay(uint delay)
{	uint i;
 	for(;delay>0;delay--)
   		{for(i=0;i<62;i++) //1ms延时.
       		{;}
   		}
}
//***********************************************//

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

//***********ds18b20读一个字节**************// 
unsigned char Read_18B20(void)
{
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	 {
		  DQ = 0; // 给脉冲信号
		  dat>>=1;
		  DQ = 1; // 给脉冲信号
		  if(DQ)
		  dat|=0x80;
		  delay_18B20(4);
	 }
 	return(dat);
}
//*****************************************//

//*************ds18b20写一个字节****************// 
void Write_18B20(uchar dat)
{
 	unsigned char i=0;
 	for (i=8;i>0;i--)
 	{
  		DQ = 0;
 		DQ = dat&0x01;
    	delay_18B20(5);
 		DQ = 1;
    	dat>>=1;
 }
}
//**********************************************//

//**************读取ds18b20当前温度************//
 uint ReadTemp()
 {
	unsigned char a=0;
	unsigned char b=0;
	unsigned char t=0;

	Init_18B20();
	Write_18B20(0xCC);    	// 跳过读序号列号的操作
	Write_18B20(0x44); 	// 启动温度转换

	delay_18B20(100);       // this message is wery important

	Init_18B20();
	Write_18B20(0xCC); 	//跳过读序号列号的操作
	Write_18B20(0xBE); 	//读取温度寄存器等(共可读9个寄存器) 前两个就是温度

	delay_18B20(100);

	a=Read_18B20();    	//读取温度值低位
	b=Read_18B20();   		//读取温度值高位
	temp_value=b;
   temp_value<<=8;
	temp_value=temp_value|a;  
   return temp_value;             
}
//*******************************************//

//*************温度数据处理*****************//
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]- Dis_play[3]*100;    // 取后两位数据暂存
   Dis_play[2]=Dis_play[1]/10;     // 取十位数据暂存
   Dis_play[1]=Dis_play[1]-Dis_play[2]*10;     // 取个位数据暂存

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

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

//***************74HC595四位读程序**************//
void WR_74HC595(uchar dat,uchar k)
{
   uchar i;
      for(i=0;i<8;i++)
	   {
	     switch(k)
    	  {
          case 0:SERD=0;LED_CLK=0;dat=dat<<1;SERD=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break;  //小数位
          case 1:SERP=0;LED_CLK=0;dat=dat<<1;SERP=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break;  //个位
			 case 2:SERT=0;LED_CLK=0;dat=dat<<1;SERT=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break;  //十位
			 case 3:SERH=0;LED_CLK=0;dat=dat<<1;SERH=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break;  //百位 负号位
			 default:break;
	     }
		}
}
//****************************************************//

//****************74HC595四位写出程序*****************//
void Send_74HC595(uchar k)
{
	   switch(k)
		{
		    case 0:RCKD=0;_nop_();_nop_();RCKD=1;_nop_();_nop_();RCKD=0;_nop_();break;  //小数位
          case 1:RCKP=0;_nop_();_nop_();RCKP=1;_nop_();_nop_();RCKP=0;_nop_();break;  //个位
			 case 2:RCKT=0;_nop_();_nop_();RCKT=1;_nop_();_nop_();RCKT=0;_nop_();break;  //十位
			 case 3:RCKH=0;_nop_();_nop_();RCKH=1;_nop_();_nop_();RCKH=0;_nop_();break;  //百位 负号位
			 default:break; 
		}
}
//***************************************************//

//******************温度数据显示********************//
void display()
  {
  uchar k;
     for(k=0;k<4;k++)                     //4位轮流显示
  {
     if (k==1)
       {WR_74HC595(table1[Dis_play[k]],k); //小数点显示
	    Send_74HC595(k);}                   
     else  
       {WR_74HC595(table[Dis_play[k]],k);
        Send_74HC595(k);}
  }
  }
//*************************************************//

//****************上下限显示***********************//
void display_data(char temp)
{
   uchar i,j,k;
	if(temp<0)
	{
	   i=11;                      //显示负号
      temp=0-temp;
	}
	else
	   i=0;
	j=temp/10;
	k=temp-j*10;
	WR_74HC595(table[i],3);
	Send_74HC595(3);              //显示百位为0
//	_nop_();
//	_nop_();
	WR_74HC595(table[j],2);       //显示十位
	Send_74HC595(2);
//	_nop_();
//	_nop_();
	WR_74HC595(table1[k],1);      //显示个位
	Send_74HC595(1);
//	_nop_();
//	_nop_();
//	_nop_();
	WR_74HC595(table[0],0);       //显示小数位
   Send_74HC595(0);
}
//************************************************//

//***************设定模式按键*****************//
void setkey1()    //设定上限
{
   Set1=1;
   if(Set1==0)
   {
       delay(8);
       count=1;   //设定模式标志
		 tbit=0;    //位选择归零
		 while(Set1==0);
   }
}
void setkey2()   //设定下限
{
   Set2=1;
   if(Set2==0)
   {
       delay(8);
       count=2;   //设定模式标志
		 tbit=0;    //位选择归零
		 while(Set2==0);
   }
}
//********************************************//

//***************位选择按键*******************//
void bitkey()
{
    Bit=1;
	 if(Bit==0)
	 {
	     delay(8);
		  tbit=tbit+1;
		  if(tbit==4)
		     tbit=1;
		  while(Bit==0);
	 }
}
//*******************************************//

//***************升序按键********************//
void upkey()
{
    uchar one,ten;   //个位与十位
    Up=1;
	 if(Up==0)
	 {
	     delay(8);
		  if(count==1)  //上限增加
		  {
				ten=tempsh/10;
				one=tempsh-ten*10;
				switch(tbit)
				{
				   case 1:
					      one=one+1;
							if(one>9)
							one=0;
							break;
					case 2:
					      ten=ten+1;
							if(ten>9)
							ten=0;
							break;
				}
				tempsh=ten*10+one;  //设定后的值
		  }
		  if(count==2)  //下限增加
		  {
				
		      if(tempsl<0)
				{
				   ten=(0-tempsl)/10;
				   one=(0-tempsl)-ten*10;
				}
				else
				{
				   ten=tempsl/10;
					one=tempsl-ten*10;
				}
				switch(tbit)
				{
				   case 1:
					      one=one+1;
							if(one>9)
							one=0;
							break;
					case 2:
					      ten=ten+1;
							if(ten>9)
							ten=0;
							break;
					case 3:            //设定是否为负数
					      if(sym==1)
							sym=-1;
							else if(sym==-1)
							sym=1;
				}
				tempsl=sym*(ten*10+one);  //设定后的值
		  }
		  while(Up==0);
	 }
}
//******************************************//

//**************降序按键********************//
void downkey()
{
    uchar one,ten;    //个位与十位
    Down=1;
	 if(Down==0)
	 {
	     delay(8);
		  if(count==1)   //上限减少
		  {
				ten=tempsh/10;
				one=tempsh-ten*10;
				switch(tbit)
				{
				   case 1:
					      if(one==0)
							one=9;
							else
					      one=one-1;
//							down_flag=1;
							break;
					case 2:
					      if(ten==0)
							ten=9;
							else
					      ten=ten-1;
//							down_flag=1;
							break;
				}
				tempsh=ten*10+one;  //设定后的值
		  }
		  if(count==2)
		  {
		      if(tempsl<0)
				{ten=(0-tempsl)/10;
				one=(0-tempsl)-ten*10;}
				else
				{
				   ten=tempsl/10;
					one=tempsl-ten*10;
				}
				switch(tbit)
				{
				   case 1:
					      if(one==0)
							one=9;
							else
					      one=one-1;
//							down_flag=1;
							break;
					case 2:
					      if(ten==0)
							ten=9;
							else
					      ten=ten-1;
//							down_flag=1;
							break;
				}
				tempsl=sym*(ten*10+one);  //设定后的值
		  }
		  while(Down==0);
	 }
}
//***********************************************//

//******************退出按键*****************//
void outkey()
{
   Out=1;
	if(Out==0)
	{
	   delay(8); 
	   count=0;
	   intr=0;
		while(Out==0);
	}
}
//***********************************************//

//****************中断初始化*********************//
void init(void)
{ 
   EA=1;//中断总开关 
   EX0=1;//开中断0开关。中断1为,EX1=1;
   EX1=1;
   IT0=1;//采用边沿触发,下降沿有效。IT1=0为低电平触发中断
	IT1=1;
} 
//**********************************************//

//***************中断0服务程序(设定上限)***************//
void int_0()interrupt 0 using 1
{
   intr=1;
   EA=0;
	count=0;
	alm=0;
	delay(100);
	while(intr==1)
	{
      display_data(tempsh);
		setkey1();
		delay(1);
		bitkey();
		upkey();
		downkey();
		outkey();
	}
	EA=1;
}
//******************************************************//

//****************中断1服务程序(设定下限)*************//
void int_1()interrupt 2 using 2
{
    EA=0;
	 count=0;
    intr=1; 
	 alm=0;
	 delay(100);
    while(intr==1)
	{
      display_data(tempsl);
		delay(1);
		setkey2();
		bitkey();
		upkey();
		downkey();
		outkey();
	}
	EA=1;
}
//***************************************************//

//****************超限报警***********************//
void alarm()
{
   uchar temp;
	alm=0;
	temp=Dis_play[2]*10+Dis_play[1];
//	if((flag1)&&(temp>(0-tempsl)))
//	   alm=1;
	if(temp>tempsh)
	   alm=1;
	else if(temp==tempsh)
	     if(Dis_play[0])
		  alm=1;
		delay(300);
			if(temp<tempsl)
	   alm=1;
//	else
//	   alm=0;
}
//***********************************************//

void main()
{
   	
   P1=0xff;
	P0=0x00;
   P3=0xff;
   count=0;
		intr=0;
   alm=0;
	init();  
    do
    {
		  while(intr==0)
          {
			    delay(100);
			    tempV=ReadTemp();
				 delay(100);
             tem_deal(tempV);
				 display();
				 delay(10);
				 alarm();
			 }
    }
	 while(1);
}



⌨️ 快捷键说明

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