【蓝桥杯第五届省赛题-简易温度采集与控制装置】

蓝桥杯第五届省赛题-简易温度采集与控制装置

【蓝桥杯第五届省赛题-简易温度采集与控制装置】
【蓝桥杯第五届省赛题-简易温度采集与控制装置】
【蓝桥杯第五届省赛题-简易温度采集与控制装置】
【蓝桥杯第五届省赛题-简易温度采集与控制装置】

#include "reg52.h"
#include "onewire.h"
#include "intrins.h"

/*####################################################
Date:2022-1-22

Author:小殷同学
#####################################################*/

sfr  P4 = 0xC0;	

sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;
sbit Led1 = P0^0;
sbit Led2 = P0^1;

unsigned char clr = 0,key_value = 0; 	//清除标志位和键值
unsigned char Current_Temp = 0,T_Max = 30,T_Min = 20; //分别记录当前温度和默认最大值与最小值温度
unsigned char setmode = 0; //温度显示模式和设置模式标志
unsigned char T_Mode = 0 ;// 温度模式
unsigned char t_count = 0; //计时用于Led的不同闪烁时间
unsigned char flag = 0,Led_flag;	//按键按下标志位 和led闪烁标志
unsigned char yi,er,san,si,wu,liu,qi,ba; //数码管位
//0-9  0xbf代表 -
unsigned char code SMG_Duan_num[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};

//-----------------------------简单延时-----------------------------

void Delay_ms(unsigned char t)		//@11.0592MHz
{
 	while(t--);
}
//--------------------------------74HC138初始化-------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 4:P2 = (P2 & 0x1f) | 0x80;break;//Y4
		case 5:P2 = (P2 & 0x1f) | 0xa0;break;//Y5
		case 6:P2 = (P2 & 0x1f) | 0xc0;break;//Y6
		case 7:P2 = (P2 & 0x1f) | 0xe0;break;//Y7
		case 0:P2 = (P2 & 0x1f) | 0x00;break;//关闭
	}
}
//--------------------------------系统初始化----------------------------
void InitSystem(void)
{
 	//关闭Led
	Init_74HC138(4);
	P0 = 0xff;
	//关闭继电器和蜂鸣器
	Init_74HC138(5);
	P0 = 0x00;
}
//---------------------------------数码管安位显示-------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
 	Init_74HC138(6); //Y6
	P0 = (0x01 << pos);
	Init_74HC138(7);//Y7
	P0 = dat;
}
//---------------------------------关闭所有数码管--------------------------
void SMG_Close(unsigned char dat)
{
 	Init_74HC138(6);
	P0 = 0xff; //全部选通
	Init_74HC138(7);
	P0 = dat;
}
//------------------------------------设置温度界面显示---------------------
void Display1(unsigned char yi,unsigned char  er)
{
 	 SMG_DisplayBit(0,SMG_Duan_num[yi]); //-
	 Delay_ms(100);
	 SMG_DisplayBit(1,SMG_Duan_num[er]); //
	 Delay_ms(100);
}

void Display2(unsigned char san,unsigned char  si)
{
 	 SMG_DisplayBit(2,SMG_Duan_num[san]); //-
	 Delay_ms(100);
	 SMG_DisplayBit(3,SMG_Duan_num[si]); //
	 Delay_ms(100);
}

void Display3(unsigned char wu,unsigned char  liu)
{
 	 SMG_DisplayBit(4,SMG_Duan_num[wu]); //-
	 Delay_ms(100);
	 SMG_DisplayBit(5,SMG_Duan_num[liu]); //
	 Delay_ms(100);
}

void Display4(unsigned char qi,unsigned char  ba)
{
 	 SMG_DisplayBit(6,SMG_Duan_num[qi]); //-
	 Delay_ms(100);
	 SMG_DisplayBit(7,SMG_Duan_num[ba]); //
	 Delay_ms(100);
}
//---------------------------------按键初始化-------------------------------
void Init_Keys(void)
{
		H1 = 0;
		H2 = H3 = H4 = 1;
		L1 = L2 = L3 = L4 = 1;
		if(L2 == 0)
		{
		 	Delay_ms(20);
			if(L2 == 0)
			{
				while(L2 == 0);
				key_value = 2;
			//	S15_Flag = 1;
			flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}
		else if(L3 == 0)
		{
		 	Delay_ms(20);
			if(L3 == 0)
			{
				while(L3 == 0);
				key_value = 1;
			//	S11_Flag = 1;
			flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}
		else if(L4 == 0)
		{
		 	Delay_ms(20);
			if(L4 == 0)
			{
				while(L4 == 0);
				key_value = 0;
				//S7_Flag = 1;
				flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}

		H2 = 0;
		H1 = H3 = H4 = 1;
		L1 = L2 = L3 = L4 = 1;
		if(L2 == 0)
		{
		 	Delay_ms(20);
			if(L2 == 0)
			{
				while(L2 == 0);
				key_value = 5;
				 //S15_Flag = 14;
				 flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}
		else if(L3 == 0)
		{
		 	Delay_ms(20);
			if(L3 == 0)
			{
				while(L3 == 0);
				key_value = 4;
				//S10_Flag = 1;
				flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}
		else if(L4 == 0)
		{
		 	Delay_ms(20);
			if(L4 == 0)
			{
				while(L4 == 0);
				key_value = 3;
				//S6_Flag = 1;
				flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}

		H3 = 0;
		H2 = H1 = H4 = 1;
		L1 = L2 = L3 = L4 = 1;
		if(L2 == 0)
		{
		 	Delay_ms(20);
			if(L2 == 0)
			{
				while(L2 == 0);
				key_value = 8;
				//S13_Flag = 1;
				flag = 1;
				//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
			}
		}
		else if(L3 == 0)
		{
		 	Delay_ms(20);
			if(L3 == 0)
			{
				while(L3 == 0);
				key_value = 7;
				//S9_Flag = 1;
				flag = 1;
			}
		}
		else if(L4 == 0)
		{
		 	Delay_ms(20);
			if(L4 == 0)
			{
				while(L4 == 0);
				key_value= 6 ;
				//S5_Flag = 1;
				flag = 1;
			}
		}

		H4 = 0;
		H2 = H3 = H1 = 1;
		L1 = L2 = L3 = L4 = 1;
		if(L2 == 0)
		{
		 	Delay_ms(20);
			if(L2 == 0)
			{
			
				while(L2 == 0)
				{
					 	if(clr == 0)
						{
							clr = 1;
							yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
						 	
						}
						else if(clr == 1)
						{
						 	clr = 0;
							yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
						}

				}
				//SMG_DisplayBit(0,SMG_Duan_num[clr]);
			}
		}
		else if(L3 == 0)
		{
		 	Delay_ms(20);
			if(L3 == 0)
			{
				//	S8_Flag = 1;
					if(setmode == 0)
					{
					 	setmode = 1;				  //按键按下进入温度设置界面
						Init_74HC138(5);
						P0 = 0x00; //设置界面下时关闭继电器
						//yi = 10,er = T_Max/10,san = T_Max%10,si = 11,wu = 11,liu = 10,qi =T_Min/10,ba = T_Min%10;
						yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi =11,ba = 11;
					}
					else if(setmode == 1)
					{
					 		setmode == 0; //按键按下进入温度显示界面
							EA = 1,ET0 = 1;
						//	yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
					} 
			}
		}
		else if(L4 == 0)
		{
		 	Delay_ms(20);
			if(L4 == 0)
			{
				while(L4 == 0);
				key_value = 9;
			//	S9_Flag = 1;
			flag = 1;
			}
		}
}
//--------------------------------------温度获取-----------------------------
void Read_DS18B20_T(void)
{
	unsigned char LSB ,MSB;		 //分别存储低第0字节和第一字节
 	init_ds18b20();	 //DS18B20复位初始化
	Write_DS18B20(0xCC);  //跳过ROM指令
	Write_DS18B20(0x44);  //开始温度转换
	Delay_ms(800);	 //延时700-900ms

	init_ds18b20();	//DS18B20复位初始化
	Write_DS18B20(0xCC);  //跳过ROM指令
	Write_DS18B20(0xBE);	 //读取高速暂存器

	LSB = Read_DS18B20(); //暂存器第0字节
	MSB = Read_DS18B20();//暂存器第1字节
	Current_Temp = MSB;
	Current_Temp = (Current_Temp << 8) | LSB;			//整体16字节数据
	Current_Temp = Current_Temp >> 4;	 //移除小数部分
	//下面为显示小数处理
 /*
	if((temp & 0xf800) == 0x0000)
	{
	 	temp >>= 4; //将小数移除
		temp = temp *10;
		temp = temp + (LSB & 0x0f)*0.625;
	}
	*/
	if(Current_Temp < T_Min )	//温度区间0 继电器关闭
	{
	 	T_Mode = 0;
		Init_74HC138(5); //选通Y5控制继电器
		P0 = 0x00;//关闭继电器
		
	}
	//温度区间1 继电器关闭	 
	else if(Current_Temp >= T_Min && Current_Temp <= T_Max)
	{
	 	T_Mode = 1;	
		Init_74HC138(5); //选通Y5控制继电器
		P0 = 0x00;//关闭继电器	
	}
	//温度区间2 继电器打开 
	else if(Current_Temp > T_Max)
	{
	 	T_Mode = 2;	
		Init_74HC138(5); //选通Y5控制继电器
		P0 = 0x10;//打开继电器	
	}
}	
//------------------------------定时器初始化----------------------------
void Init_Timer0(void)
{
	TMOD = 0x01;
	TH0  = (65535-20000)/256;
	TL0  = (65535-20000)%256;
	ET0  = 1;
	TR0  = 1;
	EA   = 1;
}
//-------------------------------主函数--------------------------------
void main(void)
{
	InitSystem();
	Init_Timer0();
	yi = 1,er = 2,san = 3,si = 4,wu = 5,liu = 6,qi = 7,ba = 8;//检测数码管是否正常
 	while(1)
	{
		 Init_Keys();
		 if(setmode == 0) //非设置模式 显示实时温度
		 {
				//温度获取
				Read_DS18B20_T();
				Delay_ms(20);
				yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
			
		 }	 
		 else if(setmode == 1) //判断是否在设置状态下
		 {
		 		EA = 0,ET0 = 0;
			 	if (er == 11 && flag == 1)
					{
						flag = 0;
						er = key_value;
					}
					else if(san == 11 && flag == 1)
					{
					 	san = key_value;
						flag = 0;
					} 
					else if(qi == 11 && flag == 1)
					{
					 	qi = key_value;
						flag = 0;
					}
					else if(ba == 11 && flag == 1)
					{
					 	ba = key_value;
						flag = 0;
						if((er * 10 + san) < (qi * 10 + ba))//最大值小于最小值L2点亮
						{
							Init_74HC138(4);
							P0 = 0xfd;
						} 
						else if((er * 10 + san) >= (qi * 10 + ba))
						{
						 	T_Max = (er * 10 + san);
							T_Min = (qi * 10 + ba);
							Init_74HC138(4);
							P0 = 0xff;
						}
					}
		 }	 	
		 Display1(yi,er);
		 Display2(san,si);
		 Display3(wu,liu);
		 Display4(qi,ba);
	}
}

//-----------------------------中断服务函数-------------------------------
void Server_Timer0() interrupt 1
{
	TH0  = (65535-20000)/256;	 //20ms
	TL0  = (65535-20000)%256;
	t_count++;
	if(t_count == 40 && T_Mode == 0)//温度区间0,继电器关闭,指示灯L1以0.8秒为间隔闪烁
	{
			t_count = 0;
			if(Led_flag == 0)
			{
			 Led_flag = 1;
		 	 Init_74HC138(4); //选通Y4控制Led
			 P0 = 0xfe;
			}
			else if(Led_flag == 1)
			{
			 	Led_flag = 0;
				Init_74HC138(4);
				P0 = 0xff;
			}
	}
	//温度区间1,继电器关闭,指示灯L1以0.4秒为间隔闪烁;
	else if(t_count ==  20 && T_Mode == 1)
	{
		 t_count = 0;
		 if(Led_flag == 0)
		 {
				Led_flag = 1;
				Init_74HC138(4);
				P0 = 0xfe;
		 }
		 else if(Led_flag == 1)
		 {
		 		Led_flag = 0;
				Init_74HC138(4);
				P0 = 0xff;
		 }
	}
	//温度区间2,继电器打开,指示灯L1以0.2秒为间隔闪烁。
	else if(t_count == 10 && T_Mode == 2)
	{
	 	t_count = 0;
		if(Led_flag == 0)
		{
			Led_flag = 1;
		 	Init_74HC138(4);
			P0 = 0xfe;
		}
		else if(Led_flag == 1)
		{
		 	Led_flag = 0;
			Init_74HC138(4);
			P0 = 0xff;
		}
	}  
}
上一篇:​LeetCode刷题实战492:构造矩形


下一篇:FreeRTOS 之任务 CPU 使用率统计