【蓝桥杯真题—04】第七届省赛程序设计题--模拟风扇控制系统

在这里插入图片描述

#include <STC15F2K60S2.H>
#include <intrins.h>
#include <onewire.h>
sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;

unsigned char table[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x7f};
unsigned char mode=1; //睡眠风 1,自然风 2,常风 3。
unsigned int count=0;//定时1S的计数标志
unsigned char time=60;//定时时长,默认1分钟
unsigned char pwm_count=0;//脉宽调制的计数变量
unsigned char pwm_t=2;//具体的脉宽调制值,2表示占空比20%,3表示占空比30%,7表示占空比70%,
unsigned char pwm_f=1;//PWM输出的标志变量
unsigned char temp=0;//存放温度值
unsigned char flag_s7=0;//按下 S7,通过数码管显示当前室温
unsigned char flag_s6=1;//S6按键的标志位,默认为1

/*======================================================================================
数码管延时函数,寄存器选择函数,显示函数
======================================================================================*/
void delay(unsigned int t)
{
    
    
	while(t--);
}
void delay_ms(int n)
{
    
    
	int i,j;
	for(i=n;i>0;i--)
		for(j=110;j>0;j--);
}
void selectHC(unsigned char choose)
{
    
    
	switch(choose)
	{
    
    
		case 4: P2 = (P2&0x1f) | 0x80; break; //LED灯
		case 5: P2 = (P2&0X1f) | 0xa0; break; //蜂鸣器,继电器
		case 6: P2 = (P2&0x1f) | 0xc0; break; //数码管位选
		case 7: P2 = (P2&0X1f) | 0xe0; break; //数码管段选
		case 0: P2 = (P2&0X1f) | 0x00; break;
	}
}
void show(unsigned char w,unsigned char n)
{
    
    
	selectHC(7);
	P0 = 0xff;
	selectHC(6);
	P0 = 0x01 << w ;
	selectHC(7);
	P0 = n;
	delay_ms(1);
	selectHC(0);
}
void show_all(unsigned char dat)
{
    
    
	selectHC(6);
	P0=0xff;
	selectHC(7);
	P0=dat;
	selectHC(0);
}
/*======================================================================================
温度读取函数
======================================================================================*/
void read_temp()
{
    
    
	unsigned char LSB; //温度的低八位
	unsigned char MSB; //温度的高八位

	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	delay_ms(1);

	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB=Read_DS18B20();
	MSB=Read_DS18B20();
	Init_DS18B20();

	temp=MSB;
	temp=(MSB<<8)|LSB;
	temp=temp>>4; //移除小数部分
}

/*======================================================================================
定时器0函数  定时1S  PWM输出
======================================================================================*/
void Init_timer0()
{
    
    
	TMOD=0x01;
	TH0=(65536-100)/256;//定时100us	
	TL0=(65536-100)%256;
	TR0=1;
	ET0=1;
	EA=1;	
}
void service_timer0() interrupt 1
{
    
    
	TH0=(65536-100)/256;//定时100us	
	TL0=(65536-100)%256;
	if(time>0)
	{
    
    
		count++;
		if(count>=10000)	//10000*100us=1s,满1秒了 time减一秒
		{
    
    
			time=time-1;
			count=0;	
		}
	}
	/*
	* 频率1KHz,周期T=1ms,计时100us,则pwm_count加1
	* 如果pwm_count大于等于2了,说明计数了200us,即0.2ms,则实现了占空比20%,以此类推
	*/
	pwm_count=pwm_count+1; 
	if(pwm_count>=pwm_t)
	{
    
    
		pwm_f=0;
	}
	if(pwm_count>=10) //计数了10个100us,则表示一个周期完了3
	{
    
    
		pwm_count=0;
		pwm_f=1;
	}
}

/*======================================================================================
数码管显示   s7按下即flag_s7=0显示温度,否则显示模式和时间
======================================================================================*/
void show_mode_temp()
{
    
    
	if(flag_s7==0)
	{
    
    
		show(0,table[10]);
		show(1,table[mode]);
		show(2,table[10]);
		show(3,0xff);
		show(4,table[time/1000]);
		show(5,table[time/100%10]);
		show(6,table[time/10%10]);
		show(7,table[time%10]);
	}
	if(flag_s7==1)
	{
    
    
		show(0,table[10]);
		show(1,table[4]);
		show(2,table[10]);
		show(3,0xff);
		show(4,0xff);
		show(5,table[(temp/10)%10]);
		show(6,table[temp%10]);
		show(7,0xc6);
	}
}

/*======================================================================================
PWM蜂鸣器输出   LED灯显示
======================================================================================*/
void buzz ()
{
    
    
	selectHC(0);
	if (pwm_f == 1)
	{
    
    
		P0 = 0x40;	
	}
	else if (pwm_f == 0)
	{
    
    
		P0 = 0x00;	
	}
	selectHC(5);
}

void led()
{
    
    
	selectHC(0);
	if(time>0)
	{
    
    
		if(mode==1)
		{
    
    
			P0=0xfe;
		}
		else if(mode==2)
		{
    
    
			P0=0xfd;
		}
		else if(mode==3)
		{
    
    
			P0=0xfb;
		}
	}else if(time==0|flag_s6==0)
	{
    
    
		P0=0xff;
	}
	selectHC(4);
}
/*======================================================================================
按键开关扫描函数
======================================================================================*/
void keys()
{
    
    
	if(s7==0)
	{
    
    
		delay_ms(1);
		if(s7==0)
		{
    
    
			while(s7==0)
			{
    
    
				show_mode_temp();
				if(time>0)
				{
    
    
					buzz();
				}
				else if(time==0)
				{
    
    
				 	selectHC(5);
					P0=0X00;
				}
			}
			if(flag_s7==0)
			{
    
    
				flag_s7=1;
			}
			else if(flag_s7==1)
			{
    
    
				flag_s7=0;
			}
		}
	}
	
	if(s6==0)
	{
    
    
		delay_ms(1);
		if(s6==0)
		{
    
    
			while(s6==0)
			{
    
    
				show_mode_temp();
				if(time>0)
				{
    
    
					buzz();
				}
				else if(time==0)
				{
    
    
				 	selectHC(5);
					P0=0X00;
				}	
			}
			time=0;
		}
	}
	
	if(s5==0)
	{
    
    
		delay_ms(1);
		if(s5==0)
		{
    
    
			while(s5==0)
			{
    
    
				show_mode_temp();
				if(time>0)
				{
    
    
					buzz();
				}
				else if(time==0)
				{
    
    
				 	selectHC(5);
				}
			}
			if(flag_s6==1)
			{
    
    
				flag_s6=2;
				time=120;
			}
			else if(flag_s6==2)
			{
    
    
				flag_s6=0;
				time=0;
			}
			else if(flag_s6==0)
			{
    
    
				flag_s6=1;
				time=60;
			}
		}
	}
	
	if(s4==0)
	{
    
    
		delay_ms(1);
		if(s4==0)
		{
    
    
			while(s4==0)
			{
    
    
				show_mode_temp();
				if(time>0)
				{
    
    
					buzz();
				}
				else if(time==0)
				{
    
    
				 	selectHC(5);
					P0=0X00;
				}
		    }
			if(mode==1) //睡眠风 占空比20%
			{
    
    
				mode=2;
				pwm_t=5;
			}
			else if(mode==2) //自然风 占空比30%
			{
    
    
				mode=3;
				pwm_t=10;
			}
			else if(mode==3) //常风 占空比70%
			{
    
    
				mode=1;
				pwm_t=2;
			}		
		}
	}					
}

void main()
{
    
    
	selectHC(4); P0 = 0xff;
	selectHC(5); P0 = 0x00;
	selectHC(0);
    Init_timer0();
	while(1)
	{
    
    
		keys();
		if(flag_s7==1)
		{
    
    
			read_temp();
		}
		show_mode_temp();
		if(time>0)
		{
    
    
			buzz();
		}
		else if(time==0)
		{
    
    
			selectHC(0);
			P0=0X00;
			selectHC(5);
		}
		led();	
	}	
}

猜你喜欢

转载自blog.csdn.net/z3447643805/article/details/115051701