蓝桥嵌入式第八届省赛——模拟升降机 做题分享

目录

一、前言

二、思路——框架功能实现分析

1、按键使用条件

2、按键功能实现

3、定时器需要实现的功能

三、框架代码

1、伪代码

2、个人的工程代码

四、总结


一、前言

本篇文章仅分享思路,没有完整工程代码。希望分享的思路对你做这套题能有所帮助。

对于任何的题目,只需要找到最核心的“房子框架”,即最主要实现的功能,将其实现后,其他功能的模块就可像装修房子一样一点点加上去而不影响到基本的使用。

二、思路——框架功能实现分析

p代表当前平台数

1、按键使用条件

我们可以最先根据题意了解到,B1~B4,分别可以点亮LED1~LED4。

其次就是在当前平台下按键无效,以B1为例,可以设置为B1:if(p != 1){…}//表示在当前平台上无效

第三,要在最后一个按键按完后的1秒才开始运动。要如何判定这是最后一个按钮然后才开始继续1s的计时呢?是每个按钮按完以后的1s内不断的去判断有没有按钮被按下吗?这样做也是可以实现的,但它就比较繁琐了,每次都需要判断,时间复杂度高。不合适。

这部分可以转化一下思路,不需要依次去判断一个按钮按下后一秒内有没有其他按键按下,只需要每按下一个按钮就重新开始计时就可以,当计时器达到1s后便开始运行(run_flag=1,运行判断位。为什么要有运行判断位?看下面的第④)

电机运转期间按键无效,同样以B1为例,可以设置为B1:if(run_flag != 1){…}//表示如果点机运行则按键无效。

结合起来,每个按键的使用条件便完成了。

Bx:if(p != x && run_flag !=1){…}

2、按键功能实现

Bx:if(p != x && run_flag !=1){ 

         对应的Led亮。//但这只是表层的,现象的层面。我们还需要按键实现其他功能。

/*比如一开始说到的重新计时*/

         led_time=0;

         p_num[x]=1;//p_num[x],某平台按下标志符,用于判断后面还有无目标平台

}

3、定时器需要实现的功能

TIM{

         每次定时器扫描则让led_time++;

         If(led_time==1000){//达到1s后,则电机开始运行

        /*led_time达到多少是1s与时钟的设置有关,如果配置与我的不同,那就不一定是1000了*/

         ud_flag=1;//电机上下运动标志位

         led_time=0;//计时器置0,开始新一轮计时

}

}

三、框架代码

1、伪代码

进入运行状态

         发现目标平台

         运动函数{

                  上升or下降:发送pwm

                  到达第一个目标平台

                  lcd闪烁

                  开、关门,发送pwm

                  是否有下一个目标平台

                          有,继续【到达】

                  无

                          结束运动

         }

2、个人的运动模块工程代码

void up_down(void){
	if(ud_flag==1){
		if(p_num[0]==1 || p_num[1]==1 || p_num[2]==1 || p_num[3]==1){//只要有目标平台便进入此函数进行上升or下降的实现
			int i,j;
			/*上升下降均可封装成函数再使用(目的就一个字,美观)*/
			/*先实现上升,再是下降,符合题意当上下均有时先上后下*/
			/*上升*/
			for(i=0;i<4;i++){
				pwm_pa6=1;//pwm发送标志位设置。
				pwm_use();//pwm实现。
				run_flag=1;//运行状态开启,用于避免运行时按键有效
				if(p_num[i]==1 && i>(p-1)){//如果有目标平台,且目标平台在p上面
					int x =1+i-p;//判断距离目标平台有几层,以便判断上升or下降几次
					for(j=0;j<x;j++){//x次的上升,从下往上判断,符合题意与按键按下的顺序无关
						//6s的流水灯(右),表示上升
						rwater();
						p++;
						sprintf(test,"         %d   ",p);
						LCD_DisplayStringLine(Line5,(uint8_t *)test);
					}
					lcd_star();//到达目标平台后闪烁
					if(p_num[i]==p_num[p-1]){//到了当前平台还没给它所在的平台标志位归0时,判断它是否需要开门
						//开门
						open_door();
						//关门
						close_door();
					}
					p_num[i]=0;//用完之后标志为0
					p_led_num[i]=0;
					}
				else{//没有找到符合要求(如果有目标平台,且目标平台在p上面)的平台,跳过本次循环。其实不用也可以
					continue;
				}
					
			}
					
				/*下降*/
			for(i=3;i>=0;i--){
				run_flag=1;
				if(p_num[i]==1 && i<(p-1)){//如果有目标平台,且目标平台在p下面
					pwm_pa7=1;
					pwm_use();
					int y =p-i-1;
					for(j=0;j<y;j++){
						led_use();
						//6s的流水灯(左)
						lwater();
						p--;
						sprintf(test,"         %d   ",p);
						LCD_DisplayStringLine(Line5,(uint8_t *)test);
						}
						lcd_star();
						if(p_num[i]==p_num[p-1]){//到了当前平台还没给它所在的平台标志位归0时,判断它是否需要开门
				    		//开门
							open_door();
							//关门
							close_door();
						}
						p_num[i]=0;//用完之后标志为0
						p_led_num[i]=0;
					}
					else{
						continue;
					}
					
				}
			}
			else{//当没有目标平台时,退出电机运行,运行状态置0
				ud_flag=0;
				run_flag=0;
			}
		}
}

四、总结

本文章仅为思路分析,因此无工程代码。有兴趣的同学或者做这套题完全没有思路的可以参考,希望对你能有帮助。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值