第十四届蓝桥杯单片机设计与开发省赛程序参考

   

此题目难度适中,与前几年相比题量较大,细心去做还是很简单,祝大家都取得好成绩。

下面是程序部分:

主程序代码:

#include <main.h>
#include <ds1302.h>
#include <onewire.h>
#include <iic.h>

void Task_Clock(void)
{
	if(++LED_tt == 100){ LED_tt = 0; LED_Ref = 1; }
	if(++SEG_tt == 50)	{ SEG_tt = 0; SEG_Ref = 1; }
	if(++KEY_tt == 10) 	{ KEY_tt = 0; 	KEY_Ref=1;}
	if(++Temp_tt == 550) 	{ Temp_tt = 0;  Temp_Ref = 1; }
	if(++AD_tt == 300) 		{ AD_tt = 0;  	AD_Ref = 1;		}
	if(++DS_tt == 1000) 	{ DS_tt = 0;  DS_Ref = 1;			}
	if(++PWM_IN_tt == 500)	{PWM_IN_tt = 0; PWM_IN_Ref = 1; }
	if(SEG_Show==9){WS_Show_TT++;}
	if(WS_Show_TT==3000){WS_Show_TT=0;SEG_Show=SEG_Show_Flag;}
}

void main(void)
{
	ALL_Init();
	Timer0Init();
	EA=1;ET0=1;
	Temp_DotValue = Temp_get() ;Delay_MS(5);
		#if (PWM != 0)
	Timer2Init();  IE2 |= 0X04;    //初始化定时器2,且开启定时器2中断
	#endif
	DS_init();
	DS_get();
	while(1)
	{
		if(SEG_Ref == 1)
		{
			SEG_Ref = 0;
			SEG_Refresh();
		}
		
		if(KEY_Ref==1)
		{
			KEY_Ref=0;
			ArrKeyScan();
			if(KEY_Flag == 1)
			{
				KEY_Flag = 0;
				Task_Key();
			}
		}

		if(Temp_Ref == 1)
		{
			Temp_Ref = 0;		
			Temp_DotValue = Temp_get() ;
		}
			if(PWM_IN_Ref == 1)
				{
					PWM_IN_Ref = 0 ;
					PWM_IN_Freq = 100000 / (PWM_INH_Save + PWM_INL_Save);
				}
		if(DS_Ref == 1)
		{
			DS_Ref = 0;
			DS_get();
		}


		if(AD_Ref == 1)
		{
			AD_Ref = 0;
			AD_Value = AD_read(0X01);		//滑动变阻器0X03,光敏电阻0X01
		
//			AD_write(AD_Value);
			if(AD_Value<=125)//暗状态
			{
				Dimmed_state=0;
			}
			else //亮状态
			{
				Dimmed_state=1;
			}
			if(SEG_Show!=9)
			{
				if((Dimmed_state==0)&&(Dimmed_state_befor==1))
				{
					if(SEG_Show_2!=2)
					{
						trigger_number++;
						gather_time_hour=Get_Time[2];
						gather_time_minute=Get_Time[1];
					}
						gather_Ref=1;
						SEG_Show_Flag=SEG_Show;
						SEG_Show=9;
				}
			}
			Dimmed_state_befor=Dimmed_state;
		}
			if(gather_Ref==1)
		{
			gather_Ref=0;
				Temp_Vaue=Temp_DotValue/10000;
				if(Temp_Vaue>=99)Temp_Vaue=99;
				if(Temp_Vaue<=0)Temp_Vaue=0;
			
				if((PWM_IN_Freq>=200)&&(PWM_IN_Freq<=2000))
				{
					PWM_IN_Flag=0;
					Humidity=(PWM_IN_Freq*2+50)/45;
				}
				else {PWM_IN_Flag=1;	Humidity_invalid++;}
				
				if(SEG_Show_2==0)
				{	
					if(Temp_Max<Temp_Vaue)Temp_Max=Temp_Vaue;
					Temp_Average=(Temp_Average*(trigger_number-1)*10+Temp_Vaue*100)/10/trigger_number;
					if(PWM_IN_Flag!=1)
					{
						if(Humidity_Max<Humidity)Humidity_Max=Humidity;
						Humidity_Average=(Humidity_Average*(trigger_number-Humidity_invalid-1)*10+Humidity*100)/10/(trigger_number-Humidity_invalid);
					}

				}
		}
				

		if(LED_Ref==1)
		{
			LED_Ref=0;
			LED_Reference();
		}
	}
}

void Task_Key(void)
{

	
		if((KEY_Value==9)&&(KEY_Press_TIME<2000)){
			KEY_Value=0;KEY_Press_TIME=0;
			if(SEG_Show==3)
			{
				if(Temper_Para==0)Temper_Para=0;
				else Temper_Para-=1;
			}
		}
		else if((KEY_Value==9)&&(KEY_Press_TIME>=2000)){
		KEY_Value=0;	KEY_Press_TIME=0;
			if((SEG_Show==2)&&(Back_Show==3))
			{
				trigger_number=0;
				gather_time_hour=0;
				gather_time_minute=0;
			}

		}
		if(KEY_Value==8){
			KEY_Value=0;
			if(SEG_Show==3)
			{
				if(Temper_Para>=99)Temper_Para=99;
				else Temper_Para+=1;
			}
		}
	

	if(KEY_Value==5){
		KEY_Value=0;
		if(SEG_Show==2)
		{
			if(Back_Show==1)Back_Show=2;
			else if(Back_Show==2)Back_Show=3;
			else if(Back_Show==3)Back_Show=1;
		}

	}
	if(KEY_Value==4){
		KEY_Value=0;

		if(SEG_Show==1){SEG_Show=2;SEG_Show_2=1;}
		else if(SEG_Show==2){SEG_Show=3;Back_Show=1;SEG_Show_2=0;}
		else if(SEG_Show==3)SEG_Show=1;
	}			
}

void SEG_Refresh(void)
{
	if(SEG_Show == 1)
	{
//		LEDx_OFF(2);LEDx_OFF(3);LEDx_ON(1);
		DigBuf[0] = Get_Time[2] / 10;   DigBuf[1] = Get_Time[2] % 10;   DigBuf[2] = 20;
		DigBuf[3] = Get_Time[1] / 10;   DigBuf[4] = Get_Time[1] % 10;   DigBuf[5] = 20;
		DigBuf[6] = Get_Time[0] / 10;   DigBuf[7] = Get_Time[0] % 10; 			
	}
	else	if(SEG_Show == 2)
	{
//		SEG_Show_2=1;
//		LEDx_OFF(1);LEDx_OFF(3);LEDx_ON(2);
		if(Back_Show==1)//温度回显
		{
			DigBuf[0] = 22; DigBuf[1] = 21;
			DigBuf[2] = Temp_Max / 10;
			DigBuf[3] = Temp_Max % 10;		
			DigBuf[4] = 20;
			DigBuf[5] = Temp_Average / 100;
			DigBuf[6] = Temp_Average % 100 / 10 + 10;
			DigBuf[7] = Temp_Average % 10;	
		}
		else if(Back_Show==2)//湿度回显
		{
			DigBuf[0] = 23; DigBuf[1] = 21;
			DigBuf[2] = Humidity_Max/10;
			DigBuf[3] = Humidity_Max%10;		
			DigBuf[4] = 20;
			DigBuf[5] = Humidity_Average / 100;
			DigBuf[6] = Humidity_Average % 100 / 10 + 10;
			DigBuf[7] = Humidity_Average % 10;	
		}
		else if(Back_Show==3)//时间回显
		{
			DigBuf[0] = 24; DigBuf[1] = trigger_number / 10;
			DigBuf[2] = trigger_number % 10;
			DigBuf[3] = gather_time_hour / 10;		
			DigBuf[4] = gather_time_hour % 10;
			DigBuf[5] = 20;
			DigBuf[6] = gather_time_minute / 10;
			DigBuf[7] = gather_time_minute % 10;	
		}
		if(trigger_number==0)
		{
			DigBuf[1] = 21;
			DigBuf[2] = 21;
			DigBuf[3] = 21;		
			DigBuf[4] = 21;
			DigBuf[5] = 21;
			DigBuf[6] = 21;
			DigBuf[7] = 21;	
		}			
	}
	else	if(SEG_Show == 3)//参数界面
	{

		DigBuf[0] = 25; DigBuf[1] = 21;
		DigBuf[2] = 21;
		DigBuf[3] = 21;		
		DigBuf[4] = 21;
		DigBuf[5] = 21;
		DigBuf[6] = Temper_Para/10;
		DigBuf[7] = Temper_Para%10;		
		if(Temper_Para < 10){DigBuf[6] = 21;DigBuf[7] = Temper_Para;		}
	}
	else	if(SEG_Show == 5)//测试界面
	{
		DigBuf[0]=Humidity/10;DigBuf[1]=Humidity%10;
		DigBuf[2]=21;		
		DigBuf[3]=PWM_IN_Freq/10000;
		DigBuf[4]=PWM_IN_Freq%10000/1000;
		DigBuf[5]=PWM_IN_Freq%1000/100;
		DigBuf[6]=PWM_IN_Freq%100/10;
		DigBuf[7]=PWM_IN_Freq%10; 
			if(PWM_IN_Flag==1)
			{
				DigBuf[0]=26;DigBuf[1]=26;
			}
	}
	if(SEG_Show == 9)//温湿度界面
	{
//		LEDx_OFF(1);LEDx_OFF(2);LEDx_ON(3);
		DigBuf[0] = 27; DigBuf[1] = 21;
		DigBuf[2] = 21;
		DigBuf[3] = Temp_Vaue/10;		
		DigBuf[4] = Temp_Vaue % 10;
		DigBuf[5] = 20;
		DigBuf[6] = Humidity / 10;
		DigBuf[7] = Humidity % 10;
		if(PWM_IN_Flag==1)
		{
			DigBuf[6]=26;DigBuf[7]=26;
		}		
	}
}
void LED_Reference(void)
{
	if(SEG_Show==1){LEDx_ON(1);}
	else LEDx_OFF(1);
	if(SEG_Show==2){LEDx_ON(2);}
	else LEDx_OFF(2);
	if(SEG_Show==9){LEDx_ON(3);}
	else LEDx_OFF(3);
	if(Temp_Vaue>Temper_Para)
	{
		if(LED_4_Flag==0){LED_4_Flag=1;LEDx_ON(4);}
		else if(LED_4_Flag==1){LED_4_Flag=0;LEDx_OFF(4);}
	}
	if(PWM_IN_Flag==1){	LEDx_ON(5);}
	else if(PWM_IN_Flag==0){LEDx_OFF(5);}
	
}


void Timer2(void) interrupt 12
{
	if(PWM_IN == 1)
	{
		PWM_INH_tt++;
		if(PWM_Deuty_flag == 1)
		{
			PWM_Deuty_flag = 0;
			PWM_INL_Save = PWM_INL_tt;
			PWM_INL_tt = 0;
		}
	}
	else if(PWM_IN == 0)
	{
		PWM_INL_tt++;
		if(PWM_Deuty_flag == 0)
		{
			PWM_Deuty_flag = 1;
			PWM_INH_Save = PWM_INH_tt;
			PWM_INH_tt = 0;
		}
	}	
}


void Timer2Init(void)		//10微秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x88;		//设置定时初始值
	T2H = 0xFF;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
}
void Timer0(void) interrupt 1
{
	P0 =0X00;						//先设置选择数码管位选的P0输出值(消影)
	P2|=0XC0;						// 将P27 P26 设置为1 其他位保持不变
	P2&=0XDF;						// 将P26设置为0 其他位保持不变
	P2&=0X1F;						//关闭所有的74HC573锁存器

	P0=tab[DigBuf[DigCom]]; 		//先设置选择数码管段选的P0输出值
	P2|=0XE0;									//将P27 P26 P25设置为1 其他位保持不变
	P2&=0XFF;									//这行程序可以不用写。
	P2&=0X1F;									//关闭所有的74HC573锁存器  0001 1111 

	P0=(0X01<<DigCom);		//先设置选择数码管位选的P0输出值
	P2|=0XC0;						// 将P27 P26 设置为1 其他位保持不变
	P2&=0XDF;						// 将P26设置为0 其他位保持不变
	P2&=0X1F;						//关闭所有的74HC573锁存器
	
	if(++DigCom==8)DigCom=0;	
	
	Task_Clock();
}


void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初始值
	TH0 = 0xD1;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void ALL_Init(void)
{
	P0 =0X00;		//先设置关闭蜂鸣器继电器的P0输出值(全关)
	P2|=0XA0;		// 将P27 P25 设置为1 其他位保持不变
	P2&=0XBF; 	// 将P26设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器

	P0 =0XFF;		//先设置关闭所有的LED的P0输出值(全关)
	P2|=0X80;		// 将P27设置为1 其他位保持不变
	P2&=0X9F;		// 将P26 P25设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器
	
	P0 =0X00;		//先设置选择数码管位选的P0输出值(全不选)
	P2|=0XC0;		// 将P27 P26 设置为1 其他位保持不变
	P2&=0XDF;		// 将P26设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器
}
void Key_W(unsigned char Value)
{
	unsigned char Val = Value;
	P3=Val;P44=Val>>7;P42=(Val&0x40)>>6;  	//	0111 1111   0100 0000
}

unsigned char Key_R()
{
	unsigned char Val = 0XFF,Val_P3=0,Val_P44=0,Val_P42=0;
	Val_P3 = P3;  Val_P44 = P44;  Val_P42 = P42;
	Val = ((Val_P3&0X3f)|(Val_P44<<7)|(Val_P42<<6)); //0011 1111 | 1000 0000 |  0100 000 
	return Val;
}

/***矩阵按键**/
void ArrKeyScan(void)
{
	unsigned char key,key1,key2;
	
	switch(KeyState)
	{
		case KEY_Check:  
		{
			Key_W(0X0F);	//P3=0XF0;			//所有列全部输出低电平
			if((Key_R()&0X0F)!=0X0F)			//有按键被按下,能知道那一行,但不知道那一列
			{
				KeyState = KEY_Press;
			}
		}
		break;
		case KEY_Press:
		{
//			Key_W(0X0F);
			if((Key_R()&0X0F)!=0X0F)		//消抖之后继续判断,是否按键依然被按下着,证明确实有按键被按下了
			key1=Key_R()&0X0F;					//key1 存储按键的行值(即哪一行有按键被按下) 1110 1101 1011 0111
			
			Key_W(0XF0);								//改变为所有行全部输出低电平
			if(((Key_R()&0XF0)|0X10)!=0XF0)		//还是有按键被按下,能知道那一列,但不知道那一行
			{
					key2=(Key_R()&0XF0)|0X10;			//key2 存储按键的列值(即哪一行有按键被按下)  1110 1101 1011 0111
					key=key1|key2;					//行值与列值相或,下面就可以得出那一列哪一行被按下了
					if(key!=0xff)						//判断一下是都真的有按键被按下,其实这一句可以不写。
					{
						switch(key)						//分析出哪一个按键被按下了
						{			
	
							case 0x7b: KEY_Value = 5 ;break;
							case 0x77: KEY_Value = 4 ;break;
	
							case 0xbb: KEY_Value = 9 ;break;
							case 0xb7: KEY_Value = 8 ;break;

							default: break;
						}
						KeyState = KEY_Release;	
					}
			}
		}
		break;
		case KEY_Release:	
		{
			Key_W(0X0F);	//P3=0XF0;			//所有列全部输出低电平
			if((Key_R()&0X0F)!=0X0F)			//有按键被按下,能知道那一行,但不知道那一列
			{
				if(KEY_Value==9)
				{
					KEY_Press_TIME = KEY_Press_TIME + 10;
				}
			
			}
			else 
			{
				KeyState = KEY_Check;
				KEY_Flag = 1;
			}
		}
		break;
		default: break;		
	}	
}

void Delay_MS(unsigned int MS)
{
	unsigned int i,j;
	for(i=0;i<MS;i++)
		for(j=910;j>0;j--);		
}

程序是我按照以前学习大科的方法之后写出来的,可能有些理解和大家不是很一样,还会出一点小Bug,请大家指教。如有侵权,联系删除。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值