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

📄 13.c

📁 温度传感器液晶显示实验
💻 C
字号:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit DQ=P3^6;
sbit BEEP=P3^7;
sbit HI_LED=P1^4;
sbit LO_LED=P1^5;

//共阴数码管段码及空白显示
uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};

//温度小数位对照表
uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
//报警温度上下限,为进行正负数比较,此处注意设为char型
//取值范围为-128~+127,DS18B20支持范围为-50~+125
char Alarm_Temp_HL[2]={40,-20};
uchar CurrentT=0;					    //当前读取的温度整数部分
uchar Temp_Value[]={0x00,0x00};		//从DS18B20读取的温度值
uchar Display_Digit[]={0,0,0,0};	       //待显示的各温度数位
bit HI_Alarm=0,LO_Alarm=0;			//高低温报警标志
bit DS18B20_IS_OK=1;				   //传感器正常标志
uint Time0_Count=0;				    	//定时器延时累加

//延时
void Delay(unsigned int x)
{
 while(--x);
}

//初始化SD18B20
uchar Init_DS18B20( )
{
 uchar status;
 DQ=1;Delay(8);
 DQ=0;Delay(90);
 DQ=1;Delay(8);
 status=DQ;
 Delay(100);
 DQ=1;
 return status;		     //初始化成功时返回0
} 

//读一字节
uchar ReadOneByte( )
{
 uchar i,dat=0;
 DQ=1;_nop_( );
 for(i=0;i<8;i++)
 {
  DQ=0;dat>>=1;DQ=1;_nop_( );_nop_( );
  if(DQ)dat|=0x80;Delay(30);DQ=1;
 }
 return dat;
}

//写一字节
void WriteOneByte(uchar dat)
{
 uchar i;
 for(i=0;i<8;i++)
 {
  DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
 }
}

//读取温度值
void Read_Temperature( )
{
 if(Init_DS18B20()==1)			      //DS18B20故障
 DS18B20_IS_OK=0;
 else
 {
  WriteOneByte(0xcc);				  //跳过序列号
  WriteOneByte(0x44);				  //启动温度转换
  Init_DS18B20( );
  WriteOneByte(0xcc);				  //跳过序列号
  WriteOneByte(0xbe);				     //读取温度寄存器
  Temp_Value[0]=ReadOneByte( );		  //温度低八位
  Temp_Value[1]=ReadOneByte( );		  //温度高八位
  Alarm_Temp_HL[0]=ReadOneByte( );	  //报警温度TH
  Alarm_Temp_HL[1]=ReadOneByte( );	  //报警温度TL
  DS18B20_IS_OK=1;
 }
}

//设置DS18B20温度报警值
void Set_Alarm_Temp_Value( )
{
 Init_DS18B20( );
 WriteOneByte(0xcc);				  //跳过序列号
 WriteOneByte(0x4e);				  //将设定的温度报警值写入DS18B20
 WriteOneByte(Alarm_Temp_HL[0]);	  //写HL
 WriteOneByte(Alarm_Temp_HL[1]);	  //写TL
 WriteOneByte(0x7f);				  //12为精确度
 Init_DS18B20( );
 WriteOneByte(0xcc);				  //跳过序列号
 WriteOneByte(0x48);				  //温度报警值存入DS18B20
}

//在数码管上显示温度
void Display_Temperature( )
{
 uchar i;
 uchar t=150;						   //延时值
 uchar ng=0,np=0;					   //负数标识及负号显示位置
 char Signed_Current_Temp;			   //注意类型为char
 
//如果为负数则取反加1,并设置负号标识及负号显示位置
 if((Temp_Value[1]&0xf8)==0xf8)
 {
  Temp_Value[1]=~Temp_Value[1];
  Temp_Value[0]=~Temp_Value[0]+1;
  if(Temp_Value[0]==0x00)Temp_Value[1]++;
  ng=1;np=0xfd;							//默认负号显示在左边第2位
 }
 
//查表得到温度小数部分
 Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];
 
//获取温度整数部分(无符号)
 CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
 
//有符号的当前温度值,注意定义为char,其值可以为-128~+127
 Signed_Current_Temp=ng?-CurrentT:CurrentT;
 
//高低温报警标志设置(与定义为char类型的Alarm_Temp_HL比较,这样可区分正负比较)
 HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;
 LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;
 //将整数部分分解为三位待显示数字
 Display_Digit[3]=CurrentT/100;
 Display_Digit[2]=CurrentT%100/10;
 Display_Digit[1]=CurrentT%10;
 if(Display_Digit[3]==0)				      //高位为0则不显示
 {
  Display_Digit[3]=10;
  np=0xfb;								   //调整负号位置
  if(Display_Digit[2]==0)
  {
   Display_Digit[2]=10;
   np=0xf7;								   //调整负号位置
  }
 }
 
//刷新显示若干时间
 for(i=0;i<30;i++)
 {
  P0=0x39;P2=0x7f;Delay(t);P2=0xff;		   //显示C
  P0=0x63;P2=0xbf;Delay(t);P2=0xff;		   //显示°
  P0=DSY_CODE[Display_Digit[0]];		      //小数位
  P2=0xdf;Delay(t);P2=0xff;
  P0=(DSY_CODE[Display_Digit[1]])|0x80;	   //个位及小数
  P2=0xef;Delay(t);P2=0xff;
  P0=DSY_CODE[Display_Digit[2]];		       //十位
  P2=0xf7;Delay(t);P2=0xff;
  P0=DSY_CODE[Display_Digit[3]];		       //百位
  P2=0xfb;Delay(t);P2=0xff;
  if(ng)		         //如果为负则在调整后的位置显示"-"
  {
   P0=0x40;P2=np;Delay(t);P2=0xff;
  }
 }
}

//定时器中断,控制警报声音
void T0_INT( )interrupt 1
{
 TH0=-1000/256;
 TL0=-1000%256;
 BEEP=!BEEP;
 if(++Time0_Count==400)
 {
  Time0_Count=0;
  if(HI_Alarm)HI_LED=~HI_LED;else HI_LED=1;
  if(LO_Alarm)LO_LED=~LO_LED;else LO_LED=1;
 }
}


//主程序
void main(void)
{
 IE=0x82;
 TMOD=0x01;
 TH0=-1000/256;
 TL0=-1000%256;
 TR0=0;
 HI_LED=1;
 LO_LED=1;
 Set_Alarm_Temp_Value( );
 Read_Temperature( );
 Delay(50000);
 Delay(50000);
 while(1)
 {
  Read_Temperature( );
  if(DS18B20_IS_OK)
  {
   if(HI_Alarm==1||LO_Alarm==1)TR0=1;
   else TR0=0;
   Display_Temperature( );
  }
  else
  {
   P0=P2=0x00;
  }
 }
} 

⌨️ 快捷键说明

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