【第十三届蓝桥杯单片机省赛模拟冲刺】

第十三届蓝桥杯单片机省赛模拟冲刺

赛前一两周一定要多练习,把之前写过的程序在好好看看,把每个模块的代码都多敲几遍,把常考的每个模块部分都吃透,如果理解不了的趁时间还比较充足该背的背牢。同时在准备编程题的同时 也要多看看客观题,比较所占分值还是挺多的。
总之加油加油 尽自己最大努力就好。

在这里插入图片描述

一、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

该模拟题的整体 难度并不是很大,不同界面之间的切换是必考的,所以如何去实现不同界面之间的合理切换是很重要的。还是那句把常用的模块熟悉掌握,剩下的就多练习,练习不同功能之间处理的逻辑思路,这一点是非常重要的。
这套模拟题难一点的就是按键的长按处理,因为自己之前没有写过长按的按键,下面的demo中就只差长按的处理了。还望各位大佬指教。

二、代码解析

#include "reg52.h"
#include "iic.h"


/*****************************************************
*第十三届省赛模拟
*Date:2022-3-23
*Author:小殷
*****************************************************/


//独立按键定义
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

//LED定义
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sbit LED4 = P0^3;
sbit LED5 = P0^4;

unsigned int Frequent = 0 ,f_data = 0,count = 0,count_flag = 0;   //频率相关变量
unsigned int Period = 0;    //周期
unsigned int Voltage_Rd1 = 0,Voltage_Rb2 = 0,Voltage = 0; //电压
unsigned int old_voltage  = 0,old_frequent = 0;
unsigned char led_flag = 0; //0 代表开启  1 代表关闭
unsigned char channel = 1,interface = 1 ; //通道编号  和显示界面
unsigned char time_flag = 0; //1s标志
unsigned char code smg_data[] = {
    
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};
unsigned char code smg_data_dot[] = {
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char led[] = {
    
    0xfe,0xfd,0xfb,0xf7,0xef,0xff,0xff,0xff}; //led

/**********************简单延时**********************/
void delay(unsigned char t)
{
    
    
 	while(t--);
}

/**********************锁存器操作********************/
void Init_74HC138(unsigned char n)
{
    
    
 	switch(n)
	{
    
    
	 	case 4:P2 = (P2 & 0x1f) | 0x80;break;
		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 SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
    
    
 	Init_74HC138(6);
	P0 = (0x01 << pos);
	Init_74HC138(7);
	P0 = dat;
	Init_74HC138(0);
}

/*************************关闭所有数码管***************/
void SMG_Close(void)
{
    
    
	Init_74HC138(6);
	P0 = 0xff;
	Init_74HC138(7);
	P0 = 0xff;
	Init_74HC138(0);
}	

/**********************系统初始化**********************/
void Init_System(void)
{
    
    
 	Init_74HC138(4);
	P0 = 0xff;
	Init_74HC138(5);
	P0 = 0x00;
	Init_74HC138(0);
}

/***********************数码管功能显示******************/
void SMG_Display_F(void)
{
    
    
 	SMG_DisplayBit(0,0x8e);  // F ->0111 0001 0x8e
	delay(200);
	if(Frequent > 999999)
	{
    
    
		SMG_DisplayBit(1,smg_data[Frequent/1000000]);
	    delay(200);
	}
 	if(Frequent > 99999)
	{
    
    
		SMG_DisplayBit(2,smg_data[Frequent/100000%10]);
	    delay(200);
	}
	 if(Frequent > 9999)
	{
    
    
		SMG_DisplayBit(3,smg_data[Frequent/10000%10]);
		delay(200);
	}
	 if(Frequent > 999)
	{
    
    
		SMG_DisplayBit(4,smg_data[Frequent/1000%10]);
	    delay(200);
	}
	 if(Frequent > 99)
	{
    
    
		 SMG_DisplayBit(5,smg_data[Frequent /100%10]);
		 delay(200);
	}
	 if(Frequent > 9)
	{
    
    
		SMG_DisplayBit(6,smg_data[Frequent /10%10]);
		delay(200);
	}

		SMG_DisplayBit(7,smg_data[Frequent %10]);
		delay(200);
		SMG_Close();

}

/*****************************周期显示***********************/
void SMG_Display_T(void)
{
    
    
	Period = 1.0/Frequent *1000000;
	SMG_DisplayBit(0,0xc8);  // >0001 0011  0xc8
	delay(200);
	if(Period > 999999)
	{
    
    
		SMG_DisplayBit(1,smg_data[Period/1000000]);
	  delay(200);
	}
 	if(Period > 99999)
	{
    
    
		SMG_DisplayBit(2,smg_data[Period/100000%10]);
	 delay(200);
	}
	 if(Period > 9999)
	{
    
    
		SMG_DisplayBit(3,smg_data[Period/10000%10]);
		delay(200);
	}
	 if(Period > 999)
	{
    
    
		SMG_DisplayBit(4,smg_data[Period/1000%10]);
	  delay(200);
	}
 	if(Period > 99)
	{
    
    
		 SMG_DisplayBit(5,smg_data[Period /100%10]);
		 delay(200);
	}
	 if(Period > 9)
	{
    
    
		SMG_DisplayBit(6,smg_data[Period /10%10]);
		delay(200);
	}

		SMG_DisplayBit(7,smg_data[Period %10]);
		delay(200);
		SMG_Close();
	
}

/*******************************电压显示**********************/
void SMG_Display_V(void)
{
    
    
	SMG_DisplayBit(0,0xc1);  // >1000 0011  0xc8
	delay(200);
	SMG_DisplayBit(1,0xbf); // -  
	delay(200);
	SMG_DisplayBit(2,smg_data[channel]);  
	delay(200);
	SMG_DisplayBit(3,0xff);  
	delay(200);
	SMG_DisplayBit(4,0xff);  
	delay(200);
	SMG_DisplayBit(5,smg_data_dot[Voltage/100]);  
	delay(200);
	SMG_DisplayBit(6,smg_data[Voltage/10%10]);  
	delay(200);
	SMG_DisplayBit(7,smg_data[Voltage%10]);  
	delay(200);
	SMG_Close();
	delay(200);
}
/******************************定时器初始化******************/
void Init_Timer(void)
{
    
    
 	TMOD = 0x16; //定时器0计数 定时器1 计时
	TH0 = 0xff;
	TL0 = 0xff;
	TH1 = (65535-50000)/256; //50ms
	TL1 = (65535-50000)%256;
	ET0 = 1;
	ET1 = 1;
	TR0 = 1;
	TR1 = 1;
	EA  = 1;
}

//通道1获取光敏数值
unsigned char  Read_RD1(void)
{
    
    
	 unsigned char temp  = 0;
	 IIC_Start();
	 IIC_SendByte(0x90);
	 IIC_WaitAck();
	 IIC_SendByte(0x01);   //光敏通道
	 IIC_WaitAck();
	 IIC_Stop(); 
	 
	 IIC_Start();
	 IIC_SendByte(0x91);
	 IIC_WaitAck();
	 temp = IIC_RecByte();
	 IIC_SendAck(1);
	 IIC_Stop(); 
	 return temp;
}


//通道3获取电位器电压值
unsigned char  Read_RD2(void)
{
    
    
	 unsigned char temp  = 0;
	 IIC_Start();
	 IIC_SendByte(0x90);
	 IIC_WaitAck();
	 IIC_SendByte(0x03);   //电位器通道
	 IIC_WaitAck();
	 IIC_Stop(); 
	 
	 IIC_Start();
	 IIC_SendByte(0x91);
	 IIC_WaitAck();
	 temp = IIC_RecByte();
	 IIC_SendAck(1);
	 IIC_Stop(); 
	 return temp;
}

/***************************按键处理*************************/
void KeyScans(void)
{
    
    
 	if(S4 == 0)
	{
    
    
	 	delay(20);
		if(S4 == 0)
		{
    
    
		 	while(S4 == 0); //等待按键松开
			if(interface == 1)
			{
    
    
			 	interface = 2;
				SMG_Display_F();
			}
			else if(interface == 2)
			{
    
    
			 	interface = 3;
				SMG_Display_T();
			}
			else if(interface == 3)
			{
    
    
			 	interface = 1;
				SMG_Display_V();
			}
			
		}
	}

	if(S5 == 0)
	{
    
    
	 	delay(20);
		if(S5 == 0)
		{
    
    
		 	while(S5 == 0); //等待按键松开
			if(channel == 1)
			{
    
    
			 	channel = 3;
			}
			else if(channel == 3)
			{
    
    
				channel = 1;
			}
		}
	}

	if(S6 == 0)
	{
    
    
	 	delay(20);
		if(S6 == 0)
		{
    
    
		 	while(S6 == 0); //等待按键松开
			old_voltage = Voltage ;		 //保存旧值
		}
	}

	if(S7 == 0)
	{
    
    
	 	delay(20);
		if(S7 == 0)
		{
    
    
			while(S7 == 0); //等待按键松开
			old_frequent = Frequent;	 //保存旧值
		}
	}
}

/************************Led操作函数*************************/
void Led_Running(void)
{
    
    
 	if(led_flag == 0)
	{
    
    	
		Init_74HC138(4); //选通Y4 进行LED 控制
		//通道3的实时电压数据大于缓存电压数据,指示灯L1点亮,否则熄灭
		if(Voltage > old_voltage )
		{
    
    
		 	//P0 = led[0];
			LED1 = 0;
		}
		else
		{
    
    
		 	LED1 = 1;
		}
		//实时频率值大于缓存频率数据,指示灯L2点亮,否则熄灭
		 if(Frequent > old_frequent )
		{
    
    
			//P0 = led[1];
			LED2 = 0;	
		}
		else
		{
    
    
		 	LED2 = 1;
		}
		 //处于频率界面,指示灯L3点亮,否则熄灭
		if(interface == 1)
		{
    
    
		 	//P0 = led[2];
			LED3 = 0;
		}
		else
		{
    
    
		 	LED3 = 1;
		}
		//处于周期界面,指示灯L4点亮,否则熄灭。
		if(interface == 2)
		{
    
    
		 	//P0 = led[3];
			LED4 = 0;
		}
		else
		{
    
    
		 	LED4 = 1;
		}
		//处于电压界面,指示灯L5点亮,否则熄灭
		 if(interface == 3)
		{
    
    
		 	//P0 = led[4];
			LED5 = 0;
		}
		else
		{
    
    
		 	LED5 = 1;
		}
	}
	else if(led_flag == 1)
	{
    
    
	 	Init_74HC138(4);
		P0 = 0xff;
	}
	//Init_74HC138(0);
}
/****************************主函数**************************/
void main(void)
{
    
    
 	Init_System();
	Init_Timer();
	while(1)
	{
    
    
		KeyScans();
		switch(interface)
		{
    
    
		 	case 1:SMG_Display_F();break;
			case 2:SMG_Display_T();break;
			case 3:SMG_Display_V();break;
		}
	 	if(interface == 3)
		{
    
    
			switch(channel)
			{
    
    
			  case 1: Voltage_Rd1 = Read_RD1();
	 	   			  Voltage = ( Voltage_Rd1/255.0 *5*100);//将其扩大100倍方便显示
					  break;
				case 3:	Voltage_Rb2 = Read_RD2();
	 	   				Voltage = ( Voltage_Rb2/255.0 *5*100);//将其扩大100倍方便显示
				        break;
			}
		}

		Led_Running();
	}

}

void Server_Timer0() interrupt 1
{
    
    
	 f_data++;
}


void Server_Timer1() interrupt 3
{
    
    
	TH1 = (65535-50000)/256; //50ms
	TL1 = (65535-50000)%256;
	count++;
//	count_flag++;
	if(count == 20) //1s
	{
    
    
	 	Frequent = f_data;
		f_data = 0;
		count = 0;
	}
}

加油

猜你喜欢

转载自blog.csdn.net/boybs/article/details/123691926