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

📄 ds18b20.c

📁 单片机语言使用C语言肯定要使用到C编译器
💻 C
字号:
/****************************************************************/
/*数码管驱动演示程序,只给出了基本的原理,实现需独立思考*********/
/*By Tony 2008.5.13                                             */
/****************************************************************/
#include <reg51.H>

//声明
unsigned char LedT0;	//数码管驱动中的5个变量
unsigned char Led1;
unsigned char Led2;
unsigned char Led3;
unsigned char Led4;
sbit P2_4=P2^4;		//4个数码管开关
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P2_7=P2^7;

sbit P3_3=P3^3;	   //5个按键
sbit P3_4=P3^4;
sbit P3_5=P3^5;
sbit P3_6=P3^6;
sbit P3_7=P3^7;
sbit BUZZER=P2^3;  //蜂鸣接口

bit flag=0;		  //温度正负的标志,0表示正温度

unsigned char Buzz=0;  //蜂鸣状态开关,默认蜂鸣关闭

unsigned int h_temp=399,l_temp=199;	  //默认温度上限39.9°和温度下限19.9°

unsigned int time=0;  //临时变量,用来在中断中计数,实现 0.9秒刷新一次管子

const unsigned char table[19]=

{0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,0x60,0x25,0x3c,0x23,0x34,0x74,0xF7,0xD7,0xFF};


sbit DQ =P2^2;   //定义1Wire总线通信端口

//延时函数,在1Wire总线中实现时序的延时
void delay(unsigned int i)
{
     while(i--);
    
}
//初始化1Wire总线函数
Init_DS18B20(void)
{
 unsigned char x=0;
 DQ = 1;    //DQ复位
 delay(8);  //稍做延时
 DQ = 0;    //单片机将DQ拉低
 delay(80); //精确延时 大于 480us
 DQ = 1;    //拉高总线
 delay(14);
 x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
 delay(20);
}
//1Wire总线读一个字节
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
EA=0;
for (i=8;i>0;i--)
 {
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
   dat|=0x80;
  delay(4);
 }
 EA=1;
 return(dat);
}
//1Wire总线写一个字节
WriteOneChar(unsigned char dat)
{
 unsigned char i=0;
 EA=0;
 for (i=8; i>0; i--)
 {
  DQ = 0;
  DQ = dat&0x01;
  delay(5);
  DQ = 1;
  dat>>=1;
 }
 EA=1;
delay(4);
}
//1Wire总线读取温度
ReadTemperature(void)
{
union uni_a{			 //利用union来实现温度低八位和高八位组合在一起
unsigned int temp;
unsigned char a[2];
} uni;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
uni.a[1]=ReadOneChar();   //读取温度值低位
uni.a[0]=ReadOneChar();   //读取温度值高位
if(uni.temp<0x0fff)		//如果正温度
{
flag=0;				    //正温度标志
}
else				   //如果负温度
{
  flag=1;			   //负温度标志
  uni.temp=~uni.temp+1;	//取反加一
}
uni.temp=uni.temp*0.625; //计数温度,为方面显示扩大了10倍
return(uni.temp);  
}
//中断处理函数,实现4个数码管的动态驱动
void int1() interrupt 1 using 1
{
	TF0 = 0;		//清定时0中断标志
	TH0 = 0xF6;		//2.5MS
	TL0 = 0x3D;
	time++;		   //利用来作为每0.9秒刷新显示一次的变量
	if(Buzz==1)	   //温度超过上限,报警蜂鸣
	{
	   if(time%50==0)	//高温报警一种频率蜂鸣提示
	   {
	   BUZZER=!BUZZER;	
	   }
	}
	else if(Buzz==2)	  //温度超过下限,报警蜂鸣
	{
	   if(time%70==0)	 //低温报警一种频率蜂鸣提示
	   {
	   BUZZER=!BUZZER;
	   }
	}
	P2 |= 0xF0;		//对P2口的高四位置1,关数码管

	switch(LedT0)
	  { 
	  	case 0:
			P0 = table[Led1];
	    	P2_4 = 0;
	    	LedT0 = 1;
			break;
	    case 1:
			P0 = table[Led2];
	    	P2_5 = 0;
	    	LedT0 = 2;
	    	break;
	    case 2:
			P0 = table[Led3];
	    	P2_6 = 0;
	    	LedT0 = 3;
	    	break;
	    case 3:
			P0 = table[Led4];
	    	P2_7 = 0;
	    	LedT0 = 0;
	    	break;
	    default://语句d
			LedT0 = 0;
	    	break;
	  }
}
//延时函数,利用参数控制实现不同时间的延时
void delay1(int i)
{
int j,k;
	for(j=0;j<i;j++)
	{
		for(k=0;k<125;k++);
	}

}
//设置函数,可以设置上下限温度值
void shezhi()
{
	unsigned int a;
	unsigned char Ledn;
	for(;;)
	{
		if(P3_3==0)					//按键(SW1)按下
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_3)
			{
				if(Led1<9)		   //数码管1显示a到f表示可以设置6个参数
				{				   //a表示温度上限,b表示温度下限,其余4个参数暂未使用
					Led1=9;
				}
					Led1++;
				if(Led1>15)		  //如果超过了f参数,则循环到a参数
				{
					Led1=10;
				}
				if(Led1==10)	//如果设置a参数,温度上限,则将之前的值在数码管2,3,4上显示出
				{
								//可以增加h_temp从E2prom器件读回
				 Led2=h_temp/100; 
				 Led3=h_temp%100/10;
				 Led4=h_temp%10;  
				}
				else if(Led1==11)	//如果设置b参数,温度下限,则将之前的值在数码管2,3,4上显示出
				{
				 Led2=l_temp/100;
				 Led3=l_temp%100/10;
				 Led4=l_temp%10;  
				}
				else		  //其余4个参数暂未使用,数码管显示000
				{
				 Led2=0;
				 Led3=0;
				 Led4=0;  				
				}
				while(!P3_3);		//等待放开手
			}
		}
		if(P3_4==0)					//按键(SW2)按下
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_4)
			{
				if(Ledn==0)			 //根据SW3键的选择,改变数码管的值
				{
				Led2+=1;
					if(Led2==10)
					Led2=0;
				}
				else if(Ledn==1)
				{
				Led3+=1;
					if(Led3==10)
					Led3=0;
				}
				else
				{
				Led4+=1;
					if(Led4==10)
					Led4=0;
				}
				while(!P3_4);		//等待放开手
			}
		}
		else if(!P3_5)					//按键(SW3)按下
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_5)
			{
				if(Ledn==0)			 //切换改变的数码管
				{
				Ledn=1;
				}
				else if(Ledn==1)
				{
				Ledn=2;
				}
				else 
				{
				Ledn=0;
				}
				while(!P3_5);		//等待放开手
			}
		}
		else if(!P3_6)					//按键(SW4)按下,保存退出
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_6)
			{
				if(Led1==10)
				{
				h_temp=	Led4+Led3*10+Led2*100;	//将设置的值计算保存下	
				                               	//这里可以加IIC保存
				}
				else if(Led1==11)
				{
				l_temp=	Led4+Led3*10+Led2*100;	//将设置的值计算保存下			
												//这里可以加IIC保存
				}
				 else						  //其余4个参数暂未使用
				{
				
				
				}
			break;						    //退出for循环
			while(!P3_6);		//等待放开手
			}
		}
		else if(!P3_7)					//按键SW5按下,不做任何修改退出
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_7)
			{
			break;
			while(!P3_7);		//等待放开手
			}
		}

	}

}
void main(void)				//主程序
{
	unsigned int temp,a;
	unsigned char Ledn;
	TMOD = 0x01;			//设定T0为十六位定时模式。
	TH0 = 0xF6;
	TL0 = 0x3D;				//2MS
	TR0 = 1;				//开定时器0
	ET0 = 1;				//致能定时0中断
	TF0 = 0;				//清定时0中断标志
	EA = 1;					//开总中断
	
	LedT0 = 0;
	
	Led1 = 0;
	Led2 = 0;
	Led3 = 0;
	Led4 = 0;
	Ledn = 0;
	P1=0Xfe;		  //上电做一个流水灯
	for(a=0;a<8;a++)
	{
	P1<<=1;
	delay1(200);
	}
	P1=0xff;
    for(;;)			//空循环,等待
	{
		if(time>350)  //利用定时完成大概0.9秒刷新一次温度显示
		{
		time=0;
			temp=ReadTemperature();//读回来温度,注意已经处理为当前温度的10倍
			if(!flag)			   //如果温度为正
			{
				Led1 = temp/1000;	   //显示温度的百位
				Led2 = temp%1000/100;  //显示温度的十位
				Led3 = temp%100/10;    //显示温度的个位
				Led4 = temp%10;		   //显示温度的小数点后1位
			}
			else
			{
				Led1 = 17;	         //显示负号温度标志
				Led2 = temp%1000/100;//显示温度的十位
				Led3 = temp%100/10;  //显示温度的个位
				Led4 = temp%10;		 //显示温度的小数点后1位
			
			}
		}

		if(P3_3==0)					//按键(SW1)按下
		{
			for (a=0; a<1000; a++); //去抖动,延时
	
			if(!P3_3)
			{
				shezhi();			//进入参数设置,可以设置上下限温度等6个参数。
	//			while(!P3_3);		//等待放开手
			}
		}
		if(temp>=h_temp)	  //温度超过报警上限
		{
		Buzz=1;				 //一种频率的蜂鸣声音,相对下限比较急促
		P1=0XF0;			 //报警灯,可以自己修改
							 //可以自己增加其他的处理
		}
		else if(temp<=l_temp)   //温度超过报警下限
		{
		 Buzz=2;				 //令一种频率的蜂鸣声音
		 P1=0X0F;				 //报警灯,可以自己修改
		                         //可以自己增加其他的处理
		}
		else if(Buzz)					 //正常温度范围
		{
		Buzz=0;					 //关闭蜂鸣,熄灭报警灯
		BUZZER=1;
		P1=0XFF;
		}


	}

}

⌨️ 快捷键说明

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