使用STC89C52单片机完成一个温度预警系统

前言:

    使用温度传感器和一个显示器,将温度显示在显示器上,并且设定警报值(超过警报值蜂鸣器长鸣)和界限值(当温度超过界限值,温度越接近警报值,蜂鸣器响的越快)。

    

/*********************************************************************************
* 【编写时间】: 2018年6月29日
* 【实验平台】: QX-MCS51 单片机开发板
* 【外部晶振】: 11.0592mhz
* 【主控芯片】: STC89C52
* 【编译环境】: Keil μVisio4
* 【程序功能】: 温度预警
**********************************************************************************/

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit DS=P2^2;           
sbit dula=P2^6;
sbit wela=P2^7;
sbit lcden=P3^4;
sbit rs=P3^5;
sbit rw=P3^6;

sbit beep=P2^3;//蜂鸣器
sbit led=P1^0; //led灯

uint f = 100;//可以通过改这个来控制蜂鸣器的频率


 
sbit key_s0 = P3^0;//S2按键位定义
sbit key_s1 = P3^1;//S3按键位定义
sbit key_s2 = P3^2;//S4按键位定义
sbit key_s3 = P3^3;//S5按键位定义

uint d; //预警温度和实际温度的差值
uint temp;  //实际温度
uint setTemp = 280;//界限温度
uint setTemp1 = 300;//预警温度

uchar table2[]="Tem:25.0"; //显示实际温度
uchar table3[]="Cri:25 War:30";//显示预警温度和界限温度

//延时函数
void delay(uint x)
{
	uint a,b;
	for(a=x;a>0;a--)
		for(b=10;b>0;b--);
}

//初始化温度传感器接口
void dsreset(void)       
{
  uint i;
  DS=0;
  i=100;
  while(i>0)i--;
  DS=1;
  i=4;
  while(i>0)i--;
}

//读字节的一位
bit tmpreadbit(void)       
{
   uint i;
   bit dat;
   DS=0;i++;          //i++ for delay
   DS=1;i++;i++;
   dat=DS;
   i=8;while(i>0)i--;
   return (dat);
}

//读一个字节数据
uchar tmpread(void)   
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();
    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);
}

 //将数据写入ds18b20
void tmpwritebyte(uchar dat)  
{
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)     //write 1
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {
      DS=0;       //write 0
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }

  }
}

//DS18B20开始变化
void tmpchange(void)  
{
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);  // address all drivers on bus
  tmpwritebyte(0x44);  //  initiates a single temperature conversion
}

//获取温度
uint tmp()               
{
  float tt;
  uchar a,b;
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);
  tmpwritebyte(0xbe);
  a=tmpread();
  b=tmpread();
  temp=b;
  temp<<=8;             //two byte  compose a int variable
  temp=temp|a;
  tt=temp*0.0625;
  temp=tt*10+0.5;
  return temp;
}

//下面都是控制显示器的函数
void write_com(uchar com)
{
	P0=com;
	rs=0;
	lcden=0;
	delay(10);
	lcden=1;
	delay(10);
	lcden=0;

}

void write_date(uchar date)
{
	P0=date;
	rs=1;
	lcden=0;
	delay(10);
	lcden=1;
	delay(10);
	lcden=0;

}

//初始化显示器
void init()
{
    rw=0;
	dula=0;
	wela=0;
	write_com(0x38);   //显示模式设置:16×2显示,5×7点阵,8位数据接口
	delay(20);
	write_com(0x0f);   //显示模式设置
	delay(20);
	write_com(0x06);   //显示模式设置:光标右移,字符不移
	delay(20);
	write_com(0x01);   //清屏幕指令,将以前的显示内容清除
	delay(20);
}

//显示实际温度
void dis1(uint temp){
	//温度传感器读到的值是实际温度的10倍
	uint x;
	uint y;
	uint z;

	if(temp == 850)//第一时间读温度时,会出现这个850的值,但不知道原因,所以写了一个温度的初始化
		temp = 250;

	x = temp/100;
	y = (temp - 100 * x)/10;
	z = temp%10;


	//分别输出温度的位
	table2[4] = (uchar)(x + 48);
	table2[5] = (uchar)(y + 48);
	table2[7] = (uchar)(z + 48);


	//判断蜂鸣器响的频率及时间
	if ((temp > setTemp)&&(temp < setTemp1))
	{
		d = setTemp1 - temp;
		beep = 1;
		led = 1;
		delay(f * d);
		beep = 0;
		led = 0;
	}else if(temp > setTemp1){
		beep = 0;
		led = 0;
	}

	else{
		beep = 1;
		led = 1;
	}
}

//显示界限温度
void dis2(uint setTemp){
	uint j = setTemp/100;
	uint k = (setTemp - 100 * j)/10;

	table3[4] = (uchar)(j + 48);
	table3[5] = (uchar)(k + 48);
}

//显示预警温度
void dis3(uint setTemp1){
	uint j = setTemp1/100;
	uint k = (setTemp1 - 100 * j)/10;

	table3[11] = (uchar)(j + 48);
	table3[12] = (uchar)(k + 48);

}


void main()
{

	uchar a;
	init();

   	 do{	
	write_com(0x80);	 //将第一个字符写在向右偏移17个字符处,为后面的由右向左划入做准备。
	delay(20);
	tmpchange();
	dis1(tmp());
	dis2(setTemp);
	dis3(setTemp1);

	for(a=0;a<8;a++)
	{
	write_date(table2[a]);
	delay(2);
	}

	write_com(0xc0);
	delay(5);

	for(a=0;a<13;a++)
	{
	write_date(table3[a]);
	delay(2);
	}

	delay(40) ;

	if(key_s0 == 0)//判断S2是否按键
		{
			delay(5);//软件延时
			if(key_s0 == 0)
			{
				if(setTemp <= setTemp1-1)
				setTemp = setTemp + 10; //计数加1
			}
			while(!key_s0);	//松手检测
		}

	if(key_s1 == 0)//判断S3是否按键
		{
			delay(5);//软件延时
			if(key_s1 == 0)
			{
				setTemp = setTemp - 10; //计数加1
			}
			while(!key_s1);	//松手检测
		}
	if(key_s2 == 0)//判断S4是否按键
		{
			delay(5);//软件延时
			if(key_s2 == 0)
			{
				setTemp1 = setTemp1 + 10; //计数加1
			}
			while(!key_s2);	//松手检测
		}

	if(key_s3 == 0)//判断S5是否按键
		{
			delay(5);//软件延时
			if(key_s3 == 0)
			{
				if(setTemp <= setTemp1-1)
				setTemp1 = setTemp1 - 10; //计数加1
			}
			while(!key_s3);	//松手检测
		}
	}while(1);
}
欢迎大家用来参考,提出意见!

猜你喜欢

转载自blog.csdn.net/qq_36236684/article/details/80867693