第十五届蓝桥杯单片机省赛程序题题目+心得,附可运行代码

本文详细解读了第十五届蓝桥杯单片机省赛中一道涉及NE555定时器和DA输出频率调节的程序题,重点介绍了如何处理负数调参和超限参数对输出的影响。
摘要由CSDN通过智能技术生成

   前言

        第十五届蓝桥杯单片机省赛刚刚结束,在比赛之前对这届单片机的程序题预计难度会很高,因为十四届的程序题难度彪高,又整合了许多模块,导致十四届没考的模块寥寥无几,本来预计会考超声波和串口,所幸没考,本次程序着重考察的是da输出和ne555定时器,围绕着ne555检测到的模拟电压输入频率做的一系列操作,难点在于一个需要对频率做一个调参操作,涉及到负数和正数的调节,还有一个就是根据超限参数,来调整da输出的倍率,总体难度不高,正常完成时间大概在3小时左右,下面上题目:

程序题

代码:

        对于这次题目的难点代码稍微解释一下,因为调参需要用到负数,并且要显示出来,所以定义了两个变量,到正数变量减到0,且按键再一次输入时,标志位置一且负数变量+100,当标志位为1时,对频率减去负数变量,且显示横杠加负数变量。然后就是根据超限频率调整DA输出,直接定义一个调整倍率的函数,switch超限参数的值,因为超限只能1k到9k,所以全部case出来,然后用计算器算出倍率,在定义一个浮点型的全局变量,根据超限的值调整这个浮点型变量的值,然后再成当前频率减500hz输出就行了。

#include "reg52.h"
#include "intrins.h"
#include "iic.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
sfr P4 = 0xc0;
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P3^4;
sbit C2 = P3^5;
sbit C3 = P4^2;
sbit C4 = P4^4;
void Display();
code unsigned char Seg_Table[] = 
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};
uchar fiag0=1;
float beilv;
uchar LED=0xff;
uchar DA;
uchar t_m,t_h,t_s;
uchar cuowu=0;
uint f,dis_fyuanshi,dis_f,dis_fmax;
uchar fushu;
uint tiaozheng,chaoxian=2000,tiaozheng2;
uchar count1s,countkey,countLED;
uchar Ds1302_Write[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar Ds1302_Read[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar Time[3] = {0x05,0x03,0x13};
void Delayus(uchar j)
{
	while(j--);
}
void SelectHC573(uchar n)
{
	switch(n)
	{
		case 0:P2 = (P2&0x1f)|0x00;break;
		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;
	}
}
void ShowSMG(uchar pos,uchar dat)
{
	SelectHC573(6);
	P0 = 0x01<<pos;
	SelectHC573(7);
	P0 = dat;
	Delayus(500);
	P0 = 0xff;
}
uchar CountS4,CountS5;
void KeyScanf()
{
	R3=0;
	R1 = R2 = R4 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C4==0)//S5
	{
		countkey=0;while(countkey==0)Display();
		if(C4==0)
		{
			while(C4==0)Display();
			CountS5++;if(CountS5==2)CountS5=0;
		}
	}
	if(C3==0)//S9
	{
		countkey=0;while(countkey==0)Display();
		if(C3==0)
		{
			while(C3==0)Display();
			if((CountS4==1)&&(CountS5==0))
			{
				if(chaoxian!=1000)
				chaoxian-=1000;
			}
			if((CountS4==1)&&(CountS5==1))
			{
				if(tiaozheng!=0)
				{
					tiaozheng-=100;
				}
				else
				{
					fushu=1;
					if(tiaozheng2!=900)tiaozheng2+=100;
				}
				if((tiaozheng==0)&&(tiaozheng2==0))
				{
					fiag0 = 1;
				}
				else
				{
					fiag0 = 0;
				}
			}
		}
	}
	R4=0;
	R1 = R2 = R3 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C4==0)//S4
	{
		countkey=0;while(countkey==0)Display();
		if(C4==0)
		{
			while(C4==0)Display();
			CountS4++;if(CountS4==4)CountS4=0;
		}
	}
	if(C3==0)//S8
	{
		countkey=0;while(countkey==0)Display();
		if(C3==0)
		{
			while(C3==0)Display();
			if((CountS4==1)&&(CountS5==0))
			{
				if(chaoxian!=9000)chaoxian+=1000;
			}
			if((CountS4==1)&&(CountS5==1))
			{
				
				if(fushu==1)
				{
					if(tiaozheng2!=0)tiaozheng2-=100;
					if(tiaozheng2==0)
					{
						fushu=0;
					}
				}
				else
				{
					if(tiaozheng!=900)tiaozheng+=100;
				}
				if((tiaozheng==0)&&(tiaozheng2==0))
				{
					fiag0 = 1;
				}
				else
				{
					fiag0 = 0;
				}
			}
		}
	}
}
void InitSystem()
{
	P0 = 0x00;
	SelectHC573(5);
	SelectHC573(0);
}
void Inittimer()
{
	TMOD = 0x16;
	TH0 = 0xff;
	TL0 = 0xff;
	TH1 = (65535-10000)/256;
	TL1 = (65535-10000)%256;
	ET0 = 1;
	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
}
void ServiceT0() interrupt 1
{
	f++;
}
void ServiceT1() interrupt 3
{
	TH1 = (65535-10000)/256;
	TL1 = (65535-10000)%256;
	count1s++;
	countkey++;
	countLED++;if(countLED==40)countLED=0;
	
	if(count1s==100)
	{
		dis_fyuanshi = f;
		f=0;
		count1s = 0;
	}
}
void Ds1302_config()
{
	uchar i;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<3;i++)
	{
		Write_Ds1302_Byte(Ds1302_Write[i],Time[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void Read_Time()
{
	uchar i;
	for(i=0;i<3;i++)
	{
		Time[i] = Read_Ds1302_Byte (Ds1302_Read[i]);
	}
}
void DA_transport(uchar x)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(x);
	I2CWaitAck();
}
void Showf()
{
	ShowSMG(0,Seg_Table[15]);
	if(dis_f/10000!=0)
	{
		ShowSMG(3,Seg_Table[dis_f/10000]);
	}
		if(dis_f/1000!=0)
	{
		ShowSMG(4,Seg_Table[dis_f%10000/1000]);
	}
	if(dis_f/100!=0)
	{
		ShowSMG(5,Seg_Table[dis_f%1000/100]);
	}
	if(dis_f/10!=0)
	{
		ShowSMG(6,Seg_Table[dis_f%100/10]);
	}
	ShowSMG(7,Seg_Table[dis_f%10]);
}
void ShowTime()
{
	ShowSMG(0,Seg_Table[Time[2]/16]);
	ShowSMG(1,Seg_Table[Time[2]%16]);
	ShowSMG(2,0xbf);
	ShowSMG(3,Seg_Table[Time[1]/16]);
	ShowSMG(4,Seg_Table[Time[1]%16]);
	ShowSMG(5,0xbf);
	ShowSMG(6,Seg_Table[Time[0]/16]);
	ShowSMG(7,Seg_Table[Time[0]%16]);
}
void Showchaoxian()
{
	ShowSMG(0,0x8c);
	ShowSMG(1,Seg_Table[1]);
	ShowSMG(4,Seg_Table[chaoxian/1000]);
	ShowSMG(5,Seg_Table[chaoxian%1000/100]);
	ShowSMG(6,Seg_Table[chaoxian%100/10]);
	ShowSMG(7,Seg_Table[chaoxian%10]);
}
void ShowTiaozheng()
{
	ShowSMG(0,0x8c);
	ShowSMG(1,Seg_Table[2]);
	if(fiag0==0)
	{
		if(fushu==0)
		{
			ShowSMG(5,Seg_Table[tiaozheng/100]);
			ShowSMG(6,Seg_Table[tiaozheng%100/10]);
			ShowSMG(7,Seg_Table[tiaozheng%10]);
		}
		else
		{
			ShowSMG(4,0xbf);
			ShowSMG(5,Seg_Table[tiaozheng2/100]);
			ShowSMG(6,Seg_Table[tiaozheng2%100/10]);
			ShowSMG(7,Seg_Table[tiaozheng2%10]);
		}
	}
	else
	{
		ShowSMG(7,Seg_Table[0]);
	}
}
void Showcuowu()
{
	ShowSMG(0,Seg_Table[15]);
	ShowSMG(6,0xc7);
	ShowSMG(7,0xc7);
}
void Showfmax()
{
	ShowSMG(0,0x89);
	ShowSMG(1,Seg_Table[15]);
	if(dis_fmax/10000!=0)
	{
		ShowSMG(3,Seg_Table[dis_fmax/10000]);
	}
		if(dis_fmax/1000!=0)
	{
		ShowSMG(4,Seg_Table[dis_fmax%10000/1000]);
	}
	if(dis_fmax/100!=0)
	{
		ShowSMG(5,Seg_Table[dis_fmax%1000/100]);
	}
	if(dis_fmax/10!=0)
	{
		ShowSMG(6,Seg_Table[dis_fmax%100/10]);
	}
	ShowSMG(7,Seg_Table[dis_fmax%10]);
}
void ShowTimemax()
{
	ShowSMG(0,0x89);
	ShowSMG(1,Seg_Table[10]);
	ShowSMG(2,Seg_Table[t_h/16]);
	ShowSMG(3,Seg_Table[t_h%16]);
	ShowSMG(4,Seg_Table[t_m/16]);
	ShowSMG(5,Seg_Table[t_m%16]);
	ShowSMG(6,Seg_Table[t_s/16]);
	ShowSMG(7,Seg_Table[t_s%16]);
}
void Display()
{
	switch(CountS4)
	{
		case 0:
			switch (cuowu)
			{
				case 0:Showf();break;
				case 1:Showcuowu();break;
			}
			CountS5=0;
			break;
		case 1:
			switch(CountS5)
			{
				case 0:Showchaoxian();break;
				case 1:ShowTiaozheng();break;
			}
			break;
		case 2:ShowTime();CountS5=0;break;
			case 3 :
				switch(CountS5)
			{
				case 0:Showfmax();break;
				case 1:ShowTimemax();break;
			}
			break;
	}
}
void Ctrlf()
{
	switch(fushu)
	{
		case 0:dis_f = dis_fyuanshi+tiaozheng;break;
		case 1:
		if(dis_fyuanshi<tiaozheng2)	
		{
			cuowu = 1;
		}
		else
		{
			cuowu = 0;
			dis_f = dis_fyuanshi-tiaozheng2;
		}
		break;
	}
	if(dis_f>dis_fmax)
	{
		dis_fmax=dis_f;
		t_h=Time[2];
		t_m=Time[1];
		t_s=Time[0];
	}
}
void Ctrlbeilv()
{
	switch(chaoxian)
	{
		case 1000:beilv=1;break;
		case 2000:beilv=0.33;break;
		case 3000:beilv=0.2;break;
		case 4000:beilv=0.14;break;
		case 5000:beilv=0.11;break;
		case 6000:beilv=0.09;break;
		case 7000:beilv=0.076;break;
		case 8000:beilv=0.066;break;
		case 9000:beilv=0.058;break;
	}
}
void CtrlDA()
{
	uint dianya;
	
		if((dis_f<=chaoxian)&&(dis_f>500))
		{
			dianya = 100+((dis_f-500)*beilv);
		}
		if(dis_f<=500)
		{
			dianya = 100;
		}
		if(dis_f>=chaoxian)
		{
			dianya =500;
		}
	
	if(cuowu==1)
	{
		dianya = 0;
	}
	DA = dianya*0.51;
	DA_transport(DA);
}
void CtrlLED()
{
	if(CountS4==0)
	{
		if(countLED>=20)
		{
			LED = LED&0xfe;
		}
		if(countLED<20)
		{
			LED = LED|0x01;
		}
	}
	else
	{
		LED = LED|0x01;
	}
	if((dis_f>chaoxian)||(cuowu==1))
	{
		if(cuowu==1)
		{
			LED = LED&0xfd;
		}
		else
		{
			if(countLED>=20)
			{
				LED = LED&0xfd;
			}
			if(countLED<20)
			{
				LED = LED|0x02;
			}
		}
	}
	else
	{
		LED = LED|0x02;
	}
	SelectHC573(0);
	P0 = 0xff;
	SelectHC573(4);
	P0 = LED;
	SelectHC573(0);
	P0 = 0xff;
}
void main()
{
	InitSystem();
	Ds1302_config();
	Inittimer();
	while(1)
	{
		KeyScanf();
		CtrlLED();
		Read_Time();
		Ctrlf();
		Ctrlbeilv();
		CtrlDA();
		Display();
	}
}

  • 25
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值