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

📄 tem2.c

📁 51单片机实现的温度测量、报警程序
💻 C
字号:
#include <reg51.h>
#include <intrins.h>

sbit K1=P1^4;
sbit K2=P1^5;
sbit K3=P1^6;
sbit K4=P1^7;
sbit BUZZER=P3^7;

//延时函数
void delay(unsigned int i)
{
while(i--);
}
/****************DS18B20驱动程序********************/
sbit DQ=P3^3;
//初始化函数
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);
}

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

//写一个字节
WriteOneChar(unsigned char dat)
{
	unsigned char i=0;
	for (i=8; i>0; i--)
	{
		DQ = 0;
		DQ = dat&0x01;
		delay(5);
		DQ = 1;
		dat>>=1;
	}
}

//读取温度
ReadTemperature(void)
{
	unsigned char a=0;
	unsigned char b=0;
	unsigned int t=0;
	float tt=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0x44); // 启动温度转换
	Init_DS18B20();
	WriteOneChar(0xCC); //跳过读序号列号的操作
	WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
	a=ReadOneChar();
	b=ReadOneChar();
	t=b;
	t<<=8;
	t=t|a;
	tt=t*0.0625; //将温度的高位与低位合并
	t= tt*10+0.5; //对结果进行4舍5入
	return(t);
}

ReadTH(void)        //读最高的温度
{
	unsigned int th=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0xBE);
	ReadOneChar();
	ReadOneChar();
	th=ReadOneChar();
	return(th);
}

ReadTL(void)        //读最高的温度
{
	unsigned int tl=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0xBE);
	ReadOneChar();
	ReadOneChar();
	ReadOneChar();
	tl=ReadOneChar();
	return(tl);
}
/********有关DS18B20的函数初始化完毕********************/

/**********LCD驱动函数**********************************/
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef bit BOOL ; 
sbit rs	= P2^0;		//
sbit rw = P2^1;
sbit ep = P2^2;
sbit right = P2^6;

delayms(BYTE ms)
{							// 延时子程序
	BYTE i;
	while(ms--)
	{
		for(i = 0; i< 250; i++)
		{
			_nop_();
			_nop_();
			_nop_();
			_nop_();
		}
	}
}

BOOL lcd_bz()
{							// 测试LCD忙碌状态
	BOOL result;
	rs = 0;
	rw = 1;
	ep = 1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	result = (BOOL)(P0 & 0x80);
	ep = 0;
	return result;	
}

lcd_wcmd(BYTE cmd)
{							// 写入指令数据到LCD
	while(lcd_bz());
	rs = 0;
	rw = 0;
	ep = 0;
	_nop_();
	_nop_();	
	P0 = cmd;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	ep = 1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	ep = 0;		
}

lcd_pos(BYTE pos)
{							//设定显示位置
	lcd_wcmd(pos | 0x80);
}

lcd_wdat(BYTE dat)	
{							//写入字符显示数据到LCD
	while(lcd_bz());
	rs = 1;
	rw = 0;
	ep = 0;
	P0 = dat;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	ep = 1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	ep = 0;	
}

lcd_init()
{							//LCD初始化设定
	lcd_wcmd(0x38);			//
	delayms(1);
	lcd_wcmd(0x0c);			//
	delayms(1);
	lcd_wcmd(0x06);			//
	delayms(1);
	lcd_wcmd(0x01);			//清除LCD的显示内容
	delayms(1);
}
/******************LCD驱动到此结束*********************/

/******************按键扫描程序开始********************/
unsigned char Read_keyboard()
{
	unsigned char Keys_Value;
	unsigned char Keys_Temp;
	P1=0XFF;
	Keys_Temp = P1;
	delay(150);
	P1=0XFF;
	Keys_Value = P1;
	if(Keys_Temp != Keys_Value)
	return(Keys_Value);
}
/****************按键扫描程序结束***********************/			

main()
{

	typedef unsigned char BYTE;
	BYTE code dis1[] = {"TEMP:"};
	BYTE code dis2[] = {"SET"};
	BYTE code dis3[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
	BYTE code dis4[] = {"TH:"};
	BYTE code dis5[] = {"     TH  TL  ESC"};
	BYTE code dis6[] = {"TH:"};
	BYTE code dis7[] = {"SET UP DOWN ESC"};
	BYTE code dis8[] = {"TL:"};
	BYTE i;
	unsigned int temp=0,th=0,tl=0;
  	unsigned char key;

   lcd_init();// 初始化LCD
	delayms(100);
	while(1)
	{
		lcd_pos(0x01);				
		i = 0;
		while(dis1[i] != '\0')
		{						// 显示字符"TEMP:"
			lcd_wdat(dis1[i]);
			i++;
		}
		
	
		lcd_pos(0x42);	
		i = 0;	
		while(dis2[i] != '\0')
		{						// 显示字符"SET"
			lcd_wdat(dis2[i]);
			i++;
		}
	
		lcd_pos(0x0B);  //显示摄氏度符号
		lcd_wdat(0xDF);
		lcd_wdat(0x43);

		temp=ReadTemperature(); //读取温度值				
		lcd_pos(0x07);         //显示温度值
		lcd_wdat(dis3[temp/100]);
		lcd_wdat(dis3[temp/10%10]);
		lcd_wdat(0x2E);
		lcd_wdat(dis3[temp%10]);
		//比较温度报警
		th=ReadTH();
		tl=ReadTL(); 
		if(temp>th*10)
		{
			lcd_pos(0x0E);         
			lcd_wdat(0x3E);
			lcd_wdat(0x48);
			BUZZER = 0;
		}
		else if(temp<tl*10)
		{
			lcd_pos(0x0E);         
			lcd_wdat(0x3C);
			lcd_wdat(0x4C);
			BUZZER = 0;
		}
		else
		{
			lcd_pos(0x0E);         
			lcd_wdat(0x20);
			lcd_wdat(0x20);
			BUZZER = 1;
		}

		key=Read_keyboard();
		if(key==0xEF)     //进入TH TL数值显示模式
		{
			BUZZER = 1;
			while(key != 0x7F)  //如果按ESC则退出
			{
				key = Read_keyboard();

				lcd_pos(0x00);				
				i = 0;
				while(dis4[i] != '\0')
				{						
					lcd_wdat(dis4[i]);
					i++;
				}

				lcd_pos(0x09);				
				i = 0;
				while(dis8[i] != '\0')
				{						
					lcd_wdat(dis8[i]);
					i++;
				}

				lcd_pos(0x07);
				lcd_wdat(0x20);
				lcd_wdat(0x20);
				
				lcd_pos(0x05);  //显示摄氏度符号
				lcd_wdat(0xDF);
				lcd_wdat(0x43);
				lcd_pos(0x0E);  //显示摄氏度符号
				lcd_wdat(0xDF);
				lcd_wdat(0x43);
				lcd_pos(0x03);   //显示TH
				lcd_wdat(dis3[th/10%10]);
				lcd_wdat(dis3[th%10]);
				lcd_pos(0x0C);   //显示TL
				lcd_wdat(dis3[tl/10%10]);
				lcd_wdat(dis3[tl%10]);
				lcd_pos(0x40);
				
				i = 0;
				while(dis5[i] != '\0')
				{						
					lcd_wdat(dis5[i]);
					i++;
				}
			

				if(key == 0xDF)    //进入TH设置模式
				{
					lcd_pos(0x00);
					for(i=0;i<16;i++)
					lcd_wdat(0x20);
					lcd_pos(0x40);
					for(i=0;i<16;i++)
					lcd_wdat(0x20);
					while(key != 0x7F)
					{
						key = Read_keyboard();
						if(key == 0xCF)
						{
							th=th+0x01;
							delayms(100);
							//把TH值写入EEPROM
							Init_DS18B20();
							WriteOneChar(0xCC); // 跳过读序号列号的操作
							WriteOneChar(0x4E); // 向寄存器写入数据
							WriteOneChar(th);
							WriteOneChar(tl);
							Init_DS18B20();
							WriteOneChar(0xCC);           //跳过DS18B20地址
							WriteOneChar(0x48); //把寄存器中数据拷贝到E2PROM
						}
						if(key == 0xAF)
						{
							th=th-0x01;
							delayms(100);
							//把TH值写入EEPROM
							Init_DS18B20();
							WriteOneChar(0xCC); // 跳过读序号列号的操作
							WriteOneChar(0x4E); // 向寄存器写入数据
							WriteOneChar(th);
							WriteOneChar(tl);
							Init_DS18B20();
							WriteOneChar(0xCC);           //跳过DS18B20地址
							WriteOneChar(0x48); //把寄存器中数据拷贝到E2PROM
						}
						lcd_pos(0x04);				
						i = 0;
						while(dis6[i] != '\0')
						{						
							lcd_wdat(dis6[i]);
							i++;
						}
						lcd_pos(0x40);				
						i = 0;
						while(dis7[i] != '\0')
						{						
							lcd_wdat(dis7[i]);
							i++;
						}
						lcd_pos(0x07);   //显示TH
						lcd_wdat(dis3[th/10%10]);
						lcd_wdat(dis3[th%10]);
						lcd_pos(0x09);  //显示摄氏度符号
						lcd_wdat(0xDF);
						lcd_wdat(0x43);
					}
					
				}
				if(key == 0xBF)
				{
					lcd_pos(0x00);
					for(i=0;i<16;i++)
					lcd_wdat(0x20);
					lcd_pos(0x40);
					for(i=0;i<16;i++)
					lcd_wdat(0x20);
					while(key != 0x7F)
					{
						key = Read_keyboard();
						if(key == 0xCF)
						{
							tl=tl+0x01;
							delayms(100);
							//把TH值写入EEPROM
							Init_DS18B20();
							WriteOneChar(0xCC); // 跳过读序号列号的操作
							WriteOneChar(0x4E); // 向寄存器写入数据
							WriteOneChar(th);
							WriteOneChar(tl);
							Init_DS18B20();
							WriteOneChar(0xCC);           //跳过DS18B20地址
							WriteOneChar(0x48); //把寄存器中数据拷贝到E2PROM
						}
						if(key == 0xAF)
						{
							tl=tl-0x01;
							delayms(100);
							//把TH值写入EEPROM
							Init_DS18B20();
							WriteOneChar(0xCC); // 跳过读序号列号的操作
							WriteOneChar(0x4E); // 向寄存器写入数据
							WriteOneChar(th);
							WriteOneChar(tl);
							Init_DS18B20();
							WriteOneChar(0xCC);           //跳过DS18B20地址
							WriteOneChar(0x48); //把寄存器中数据拷贝到E2PROM
						}
						lcd_pos(0x04);				
						i = 0;
						while(dis8[i] != '\0')
						{						
							lcd_wdat(dis8[i]);
							i++;
						}
						lcd_pos(0x40);				
						i = 0;
						while(dis7[i] != '\0')
						{						
							lcd_wdat(dis7[i]);
							i++;
						}
						lcd_pos(0x07);   //显示TH
						lcd_wdat(dis3[tl/10%10]);
						lcd_wdat(dis3[tl%10]);
						lcd_pos(0x09);  //显示摄氏度符号
						lcd_wdat(0xDF);
						lcd_wdat(0x43);
					}
					
				}		

			}
			lcd_pos(0x00);
			for(i=0;i<16;i++)
			lcd_wdat(0x20);
			lcd_pos(0x40);
			for(i=0;i<16;i++)
			lcd_wdat(0x20);
		}
	}
}
		

	
                                      


⌨️ 快捷键说明

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