第十四届蓝桥杯单片机省赛真题(巨简代码+超级详解)

02-29 阅读 0评论

文章目录

  • 前言
  • 一、陷阱分析
  • 二、代码相关定义、声明
    • 1.变量声明
    • 2.函数声明
    • 三、主要函数
      • 1.函数初始化 :关闭蜂鸣器、定时器初始化、设置时间、消除85℃影响、开启总中断
      • 2.按键扫描:长按松开清除数据,短按切换界面,加减参数
      • 3.数据采集与处理:有效性判断、禁止连续采集、3s返回界面、储存数据、比较最大值、求平均值
      • 4.数码管显示:无效字符、位不足补0、采集次数为0时要求位熄灭
      • 6.LED显示:点亮、熄灭、闪烁
      • 7.中断服务函数
      • 8.延时函数
      • 四、经验与感受 细节剖析(后续补充)
      • 五、链接
        • 1.第十四届蓝桥杯单片机省赛真题PDF
        • 2.第十三届蓝桥杯嵌入式国赛真题(基于HAL库的巨简代码+超级详解)
        • 3.第十三届蓝桥杯嵌入式省赛第一场真题(基于HAL库的巨简代码+超级详解)
        • 4.第十三届蓝桥杯嵌入式省赛第二场真题(基于HAL库的巨简代码+超级详解)
        • 5.第十二届蓝桥杯嵌入式省赛第一场真题(基于HAL库的巨简代码+超级详解)

          前言

          相关说明:

          第十四届蓝桥杯单片机省赛真题(巨简代码+超级详解),第十四届蓝桥杯单片机省赛真题(巨简代码+超级详解),词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,设置,比较,操作,第1张
          (图片来源网络,侵删)

          开发板:CT107D——IAP15F2K61S2

          开发环境: Keil5

          涉及题目:第十四届蓝桥杯单片机省赛真题

          第十四届蓝桥杯单片机省赛真题(巨简代码+超级详解)


          一、陷阱分析

          数码管忘记不足2位左侧补0;采集的湿度无效时,温湿度、采集次数、采集时间不统计,更不参与计算平均值;温度参数有边界条件;在时间回显子界面长按松开后才能清零,不松开不能清零,且采集时间、次数、平均值、最大值、储存的数据都需清零;采集湿度无效时,温度需正常显示,但不能储存;L4闪烁时,如果长按清零数据,此时无采集的温度,L4应停止闪烁;L6点亮时,如果长按清零数据,由于采集次数变为0,题目要求为≥2,L6应熄灭;触发采集后经历3s应返回原来的界面,不能返回到固定的任意界面,且3s不能内重复采集,按键操作无效;进入温湿度界面时,L1、L2应熄灭,L3点亮。


          二、代码相关定义、声明

          1.变量声明

          xdata unsigned long uwTick,cjTick,kTick;//单片机上电后每1ms uwTick+1,cjTick用于记录采集时间,kTick记录按键长按时间。
          xdata unsigned int Key_Slow_Down,Seg_Slow_Down,Led_Slow_Down;//减速变量,Led_Slow_Down也可用于led的0.1s闪烁
          xdata unsigned char seg_buf[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//数码管缓存数组,用于记录段选值
          xdata unsigned char wd,cjwd[255]={0},cjsd[255];//wd为当前采集的温度,后两个数组用来储存采集的数据
          unsigned char uled;//Led显示的参数
          unsigned char rtc[3]={13,03,05};//时间数组
          unsigned char cjsj[2]={0,0};//记录发生采集的时间
          unsigned char jiemian;//界面参数 0为时间界面 1为回显界面 2为参数界面
          unsigned char hxjm;//回显界面参数 0为温度回显界面 1为湿度回显界面 2为时间回显界面
          unsigned char flag;//采集标志位  0为未进行采集,按键操作无效 1为正在进行采集,按键操作无效
          unsigned char sjwx;//数据无效标志位 0为数据有效,将采集的温度湿度写入数组 1为数据无效,不进行操作
          unsigned char tmax,hmax,n;//分别为采集温度的最大值,采集湿度的最大值,采集次数
          unsigned char wdcs=30;//温度参数,初始化为30
          unsigned char gmdz;//AD光敏通道读取值
          unsigned int freq;//当前测量555信号发生器的频率
          unsigned int wd_sum,sd_sum;//已测所有温度(湿度)数据的总和
          float wdpj,sdpj;//已测所有温度(湿度)数据的平均值
          

          2.函数声明

          void Key_Proc();
          void Data_Proc();
          void Seg_Proc();
          void Led_Proc();
          

          三、主要函数

          1.函数初始化 :关闭蜂鸣器、定时器初始化、设置时间、消除85℃影响、开启总中断

          void main(void)
          {
          	close();//关闭蜂鸣器,熄灭数码管
          	Timer1Init();//定时器1初始化
          	EA = 1;//开启总中断
          	
          	Set_Rtc(rtc);//设置时间
            	Freqinit();//测频初始化
          	
          	rd_temperature();//消除85℃影响
          	Delay750ms();
          	
          	while(1)
          	{
          		Key_Proc();
          		Data_Proc();
          		Seg_Proc();
          		Led_Proc();
          	}
          }
          

          2.按键扫描:长按松开清除数据,短按切换界面,加减参数

          void Key_Proc(void)
          {
          	static unsigned char key_old;
          	unsigned char key_value, key_down,key_up;
          	unsigned char i;
          	
          	if(Key_Slow_Down) return;
          	Key_Slow_Down = 1;
          	
          	key_value = Key_Read();
          	key_down = key_value & (key_old ^ key_value);
          	key_up = ~key_value & (key_old ^ key_value);
          	key_old = key_value;
          	
          	if(flag==0)//采集标志位为0,处于未采集状态,按键操作有效
          	{
          		if(key_down)
          			kTick=uwTick;//有按键按下开始计时
          		
          		if(uwTick-kTick>2000)//长按超过2s
          		{
          			switch(key_up)//松开
          			{
          				case 9:
          						if((jiemian==1)&&(hxjm==2))//时间回显子界面
          						{
          							for(i=0;i
          								cjwd[i]=0;
          								cjsd[i]=0;
          							}
          							tmax=0;hmax=0;//最大值清零
          							wdpj=0;sdpj=0;//平均值清零
          							cjsj[0]=cjsj[1]=0;//采集时间清零
          							n=0;//采集次数清零
          						}
          				break;
          			}
          		}
          		else//短按
          		{
          			switch(key_up)
          			{
          				case 4:
          						if(++jiemian==3)//切换界面
          							jiemian=0;
          						if(jiemian==1)//时间界面切换到回显界面
          								hxjm=0;//处于温度回显子界面
          				break;
          						
          				case 5:
          						if(jiemian==1)//回显界面
          							if(++hxjm==3)//回显子界面切换
          								hxjm=0;
          				break;
          						
          				case 8:
          						if(jiemian==2)//参数界面
          							if(++wdcs==100)//钳制在99
          								wdcs=99;
          				break;
          						
          				case 9:
          						if(jiemian==2)//参数界面
          							if(--wdcs200)//钳制在0
          								wdcs=0;
          				break;
          			}
          		}
          	}
          }
          

          3.数据采集与处理:有效性判断、禁止连续采集、3s返回界面、储存数据、比较最大值、求平均值

          void Data_Proc(void)
          {
          	unsigned char i;
          	
          	if(Data_Slow_Down) return;
          	Data_Slow_Down = 1;
          	
          	Read_Rtc(rtc);//读取时间
          	gmdz=Pcf8591_Adc(0x41);//读取光敏通道值
          	
          	if((gmdz
          		flag=1;//采集标志位设1,处于采集状态,3秒内无法再触发采集
          		cjTick=uwTick;//开始计时
          		wd=rd_temperature()/16;//读取当前温度
          		if((freq=200)&&(freq
          			n++;//采集次数+1
          			cjsd[n]=(unsigned char)(80/1800.0*(freq-200)+10);//湿度换算并储存
          			cjwd[n]=wd;//储存温度
          			cjsj[0]=rtc[0];cjsj[1]=rtc[1];//储存触发时间
          			sjwx=0;//数据无效标志位设0
          		}
          		else//频率无效,湿度数据无效
          			sjwx=1;//数据无效标志位设1
          	}
          	if(uwTick-cjTick3000)//超过3秒
          		flag=0;//采集标志位设0,处于未采集状态,可以进行下一次采集
          	
          	for(i=1;i
          		if(cjwd[i]tmax)//比较出温度最大值
          			tmax=cjwd[i];
          		wd_sum+=cjwd[i];//求出温度数据总和
          		
          		if(cjsd[i]>hmax)//比较出湿度最大值
          			hmax=cjsd[i];
          		sd_sum+=cjsd[i];//求出湿度数据总和
          	}
          	wdpj=1.0*wd_sum/n;//求出温度平均值
          	sdpj=1.0*sd_sum/n;//求出湿度平均值
          	wd_sum=0;sd_sum=0;//数据总和清零,否则影响下一次计算
          }
          

          4.数码管显示:无效字符、位不足补0、采集次数为0时要求位熄灭

          void Seg_Proc(void)
          {
          	unsigned char seg_string[10];//储存显示的字符
          	
          	if(Seg_Slow_Down) return;
          	Seg_Slow_Down = 1;
          	
          	if(flag==1)//触发采集进入温湿度界面
          	{
          		if(sjwx)//数据无效
          			sprintf(seg_string,"E  %2d-AA",(unsigned int)wd);//显示暂存的当前温度和无效字符AA
          		else//数据有效
          			sprintf(seg_string,"E  %2d-%2d",(unsigned int)cjwd[n],(unsigned int)cjsd[n]);//显示储存的数据
          	}
          	else//时间界面、回显界面、参数界面
          	{
          		if(jiemian==0)//时间界面
          			sprintf(seg_string,"%02d-%02d-%02d",(unsigned int)rtc[0],(unsigned int)rtc[1],(unsigned int)rtc[2]);//不足2位左侧补0	
          		else if(jiemian==1)//回显界面
          		{
          			if(hxjm==0)//温度回显界面
          			{
          				if(n==0)//采集次数为0
          					sprintf(seg_string,"C       ");//除标识符外其他位熄灭
          				else//采集次数不为0
          					sprintf(seg_string,"C %2d-%4.1f",(unsigned int)tmax,wdpj);
          			}
          			else if(hxjm==1)//湿度回显界面
          			{
          				if(n==0)//采集次数为0
          					sprintf(seg_string,"H       ");//除标识符外其他位熄灭
          				else//采集次数不为0
          					sprintf(seg_string,"H %2d-%4.1f",(unsigned int)hmax,sdpj);
          			}
          			else//时间回显界面
          			{
          				if(n==0)//采集次数为0
          					sprintf(seg_string,"F%02d     ",(unsigned int)n);//时、间隔、分位置熄灭,采集次数不足2位左侧补0
          				else//采集次数不为0
          					sprintf(seg_string,"F%02d%02d-%02d",(unsigned int)n,(unsigned int)cjsj[0],(unsigned int)cjsj[1]);//采集次数不足2位左侧补0
          			}
          		}
          		else//参数界面
          			sprintf(seg_string,"P     %2d",(unsigned int)wdcs);
          	}
          	Seg_Tran(seg_string, seg_buf);
          }
          

          6.LED显示:点亮、熄灭、闪烁

          void Led_Proc(void)
          {
          	if(Led_Slow_Down) return;
          	Led_Slow_Down = 1;
          	
          	if((jiemian==0)&&(flag==0))//时间界面,且未进入温湿度界面
          		uled|=0x01;
          	else//其他界面
          		uled&=~0x01;
          	if((jiemian==1)&&(flag==0))//回显界面,且未进入温湿度界面
          		uled|=0x02;
          	else//其他界面
          		uled&=~0x02;
          	if(flag)//温湿度界面
          		uled|=0x04;
          	else//其他界面
          		uled&=~0x04;
          	
          	if(cjwd[n]>wdcs)//当前采集温度大于温度参数
          		uled^=0x08;//L4 0.1秒闪烁
          	else//不满足条件
          		uled&=~0x08;//L4熄灭
          	
          	if(sjwx)//湿度数据无效
          		uled|=0x10;
          	else//下一次湿度数据有效
          		uled&=~0x10;
          	
          	if(n>=2)//采集次数大于2时
          	{
          		if((cjwd[n]>cjwd[n-1])&&(cjsd[n]>cjsd[n-1]))//本次采集的温度、湿度相比上一次均升高
          			uled|=0x20;
          		else//不满足条件
          			uled&=~0x20;
          	}
          	else
          		uled&=~0x20;
          }
          

          7.中断服务函数

          void tm1_isr() interrupt 3
          {
          	static unsigned char pos;//位选变量
          	
          	uwTick++;//按ms++
          	
          	if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
          	if(++Data_Slow_Down == 200) Data_Slow_Down = 0;
          	if(++Seg_Slow_Down == 200) Seg_Slow_Down = 0;	
          	if(++Led_Slow_Down == 100) Led_Slow_Down = 0;
          		
          	if((uwTick%1000) == 0)//每1s进入一次
          	{
           		freq = ((TH0
          	unsigned char i, j, k;
          	_nop_();
          	_nop_();
          	i = 35;
          	j = 51;
          	k = 182;
          	do
          	{
          		do
          		{
          			while (--k);
          		} while (--j);
          	} while (--i);
          }
          

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]