免费资源 蓝桥杯比赛 历届省赛题目解答——第十届(省一代码加注释)

蓝桥杯比赛 单片机组 第十届省赛题目解答(代码加注释)


一、题目

  历届的省赛和国赛的题目我已经在前面的文章(点击查看)里给大家分享了(网盘资源),需要的话,直接去下载,我在这里就不再赘述了。

二、hex文件

读者下载这个文件然后用烧录软件直接烧入单片机就可以用了!

链接:https://pan.baidu.com/s/1OQu0UORfoGjJJwGePCUeXA
提取码:wxas

三、主函数实现

  提示:比赛过程中,仅仅主函数修改可能不够,有的时候需要注意,比赛官方给的各个驱动的代码是否写完整了,比如有时候,它的.h文件中就没有把这些写全,故意注释掉,你需要去对应的.c文件里找都需要一些什么函数,一个个都补全了才行。
在这里插入图片描述
  另外,我的代码都是完全在一个文件中写完的,所以各位读者大大用起来就比较方便,可以直接拷贝我的.c文件也可以把内容复制粘贴走,放到你想要的地方去。

上代码:

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

sbit S4 = P3^3;
sbit S5 = P3^2;
sbit S6 = P3^1;
sbit S7 = P3^0;

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;

unsigned int rb2 = 0;				 //读取的电位器RB2的值
unsigned char duanma[18] = {
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char duanmadot [10] = {
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned int f_dat = 0;				 //用于显示的频率
unsigned int u_dat = 0;				 //用于显示的电压
unsigned char k4 = 1;                //S4的标志位,1为显示电压
bit k5 = 0;							 //S5的标志位,0为显示固定电压2V
bit k6 = 0;							 //S6的标志位,0为显示电压LED
bit k7 = 0;							 //S7的标志位,0为显示数码管
unsigned int f_c = 0;				 //定时器T0用来对脉冲计数
unsigned char count = 0;			 //定时器T1的计数变量

void SelectHC573 (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 InitSystem ()
{
    
    
	SelectHC573(4);
	P0 = 0xff;
	SelectHC573(5);
	P0 = 0x00;
	SelectHC573(0);	
}
//==========================================================

//===================读取Rb2的值-AD转换=====================
void ReadRb2_ADC ()
{
    
    
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);		//注意
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	rb2 = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();	
}
//==========================================================

//============写入PCF8591具体电压值-DA转换==================
void SetDat_DAC (unsigned int dat)
{
    
    
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);		 
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();		
}
//==========================================================

//==================定时器初始化函数========================
void InitTime ()
{
    
    	
	TMOD = 0x16;
	
	TH0 = 0xff;
	TL0 = 0xff;
	
	TH1 = (65535 - 50000) / 256;
	TL1 = (65535 - 50000) % 256;

	TR0 = 1;
	TR1 = 1;

	ET0 = 1;
	ET1 = 1;
	EA = 1;
}
//==========================================================

//=================定时器中断服务函数=======================
void ServiceTime0 () interrupt 1
{
    
    
	f_c++;
}

void ServiceTime1 () interrupt 3
{
    
    
	TH1 = (65535 - 50000) / 256;
	TL1 = (65535 - 50000) % 256;
	
	count++;
	if (count == 20)
	{
    
    	
		count = 0;
		f_dat = f_c;
		f_c = 0;	
	}	
}
//==========================================================

//======================SMG相关函数=========================
void DelaySMG (unsigned int t)
{
    
    
	while (t--);
}

void ShowSMG_Bit (unsigned char pos,unsigned char dat)
{
    
    
	SelectHC573(7);
	P0 = 0xff;	
	SelectHC573(6);
	P0 = 0x01 << pos - 1;
	SelectHC573(7);
	P0 = dat;
	SelectHC573(0);	
}

void AllSMG(unsigned char dat)
{
    
    
	SelectHC573(6);
	P0 = 0xff;
	SelectHC573(7);
	P0 = dat;
	SelectHC573(0);	
}

void ShowSMG ()
{
    
    
	if(k4 == 1)				   //电压测量状态
	{
    
    
		ShowSMG_Bit (1,0xc1);
		DelaySMG(500);
		ShowSMG_Bit (6,duanmadot[u_dat / 100]);		   
		DelaySMG(500);
		ShowSMG_Bit (7,duanma[(u_dat / 10) % 10]);		   
		DelaySMG(500);
		ShowSMG_Bit (8,duanma[u_dat % 10]);		   
		DelaySMG(500);
		AllSMG(0xff);		
	}
	else if (k4 == 2)		  //频率测量状态
	{
    
    
		ShowSMG_Bit (1,duanma[15]);
		DelaySMG(500);
		if (f_dat > 99999)
		{
    
    
			ShowSMG_Bit (3,duanma[f_dat / 100000]);		   
			DelaySMG(500);	
		}
		if (f_dat > 9999)
		{
    
    
			ShowSMG_Bit (4,duanma[(f_dat / 10000) % 10]);		   
			DelaySMG(500);	
		}
		if (f_dat > 999)
		{
    
    
			ShowSMG_Bit (5,duanma[(f_dat / 1000) % 10]);		   
			DelaySMG(500);	
		}
		if (f_dat > 99)
		{
    
    
			ShowSMG_Bit (6,duanma[(f_dat / 100) % 10]);		   
			DelaySMG(500);	
		}
		if (f_dat > 9)
		{
    
    
			ShowSMG_Bit (7,duanma[(f_dat / 10) % 10]);		   
			DelaySMG(500);	
		}
		ShowSMG_Bit (8,duanma[f_dat % 10]);		   
		DelaySMG(500);	
		AllSMG(0xff);		
	}
}
//==========================================================

//======================浏览按键============================
void Delay_Key (unsigned char t)
{
    
    	
	while (t--);
}

void ScanKey ()
{
    
    
	if (S4 == 0)
	{
    
    
		Delay_Key (100);
		if (S4 == 0)
		{
    
    
			while (S4 == 0)
			{
    
    
				if (k7 == 0)
				{
    
    
					ShowSMG ();
				}	
			}
			if (k4 == 1)
			{
    
    
				k4 = 2;
			}	
			else if (k4 == 2)
			{
    
    
				k4 = 1;
			}
		}
	}
	if (S5 == 0)
	{
    
    
		Delay_Key (100);
		if (S5 == 0)
		{
    
    
			while (S5 == 0)
			{
    
    
				if (k7 == 0)
				{
    
    
					ShowSMG ();
				}	
			}
			k5 = ~k5;
		}
	}
	if (S6 == 0)
	{
    
    
		Delay_Key (100);
		if (S6 == 0)
		{
    
    
			while (S6 == 0)
			{
    
    
				if (k7 == 0)
				{
    
    
					ShowSMG ();
				}	
			}
			k6 = ~k6;
		}
	}
	if (S7 == 0)
	{
    
    
		Delay_Key (100);
		if (S7 == 0)
		{
    
    
			while (S7 == 0)
			{
    
    
				if (k7 == 0)
				{
    
    
					ShowSMG ();
				}	
			}
			k7 = ~k7;
		}
	}
}
//==========================================================

//====================LED显示函数===========================
void LEDRunning ()
{
    
    
	SelectHC573(4);
	if (k4 == 1)
	{
    
    
		L1 = 0;
		L2 = 1;
	}
	else if (k4 == 2)
	{
    
    
		L1 = 1;
		L2 = 0;
	}
	if (k5 == 1)
	{
    
    
		if ((u_dat < 150) | ((u_dat >= 250) & (u_dat < 350)))
		{
    
    
			L3 = 1;	
		}
		else if (((u_dat >= 150) & (u_dat < 250)) | (u_dat >= 350))
		{
    
    
			L3 = 0;	
		}
	}
	else if (k5 == 0)
	{
    
    
		L3 = 1;
	}
	if ((f_dat < 1000) | ((f_dat >= 5000) & (f_dat < 10000)))
	{
    
    
		L4 = 1;	
	}
	else if (((f_dat >= 1000) & (f_dat < 5000)) | (f_dat >= 10000))
	{
    
    
		L4 = 0;	
	}
	if (k5 == 0)
	{
    
    
		L5 = 1;
	}
	else if (k5 == 1)
	{
    
    
		L5 = 0;
	}
	SelectHC573(0);		
}
//==========================================================

//=======================主函数=============================
void main (void)
{
    
    
	InitSystem ();
	InitTime ();
	while (1)
	{
    
    	
		ScanKey ();	
		if (k5 == 0)						  //固定输出2V并显示在数码管上
		{
    
    
			SetDat_DAC (102.4);				  //5V对应255,2V对应102.4
			u_dat = 200;	
		}
		else if (k5 == 1)					  //输出的电压随Rb2的值变换而变化并显示在数码管上
		{
    
    									  
			ReadRb2_ADC ();
			u_dat = rb2 * 1.961;			  // 500 / 255 == 1.961
			//u_dat = rb2;
			SetDat_DAC(rb2);	
		}
		if (k7 == 0)
		{
    
    
			ShowSMG ();	
		}
		if (k6 == 0)
		{
    
    
			LEDRunning ();	
		}
		else if (k6 == 1)
		{
    
    
			SelectHC573(4);
			P0 = 0xff;	
		}
	}
}
//==========================================================

四、整个工程文件

链接:https://pan.baidu.com/s/1Wmk1ANx–34niOe230p9Lg
提取码:xo28

 直接打开这项目如果失败的话,可能是因为keil使用版本问题,我用的是keil3,出现问题的话,可以直接拷贝.c文件的内容,前面我也说了,我的实现过程我在一个.c文件中实现的,方便读者大大取用!

在这里插入图片描述

最后

有需要的小伙伴可以随时评论或者私信我,讨论学习过程中的问题,我会尽我所能提供一些帮助的


温馨提示: 关注我不容易让文章走丢哦!

蓝桥杯比赛 单片机组 历届省赛题目解答(代码加注释)剩余参见——https://blog.csdn.net/weixin_45386875/article/details/114136549

猜你喜欢

转载自blog.csdn.net/weixin_45386875/article/details/114208339