蓝桥杯嵌入式第十四届省赛程序设计题

目录

系列文章目录

文章目录

前言

一、题目

二、模块实现

1.LED+LCD

2.定时器+key

3.ADC+pwm+脉冲捕获

总结


系列文章目录

第十一届省赛

http://t.csdnimg.cn/JcQMH

第十三届省赛第一场

http://t.csdnimg.cn/cBrmc

第十三届省赛第二场

http://t.csdnimg.cn/XYVTg

第十五届4T模拟赛 加部分更新

http://t.csdnimg.cn/abvcg

http://t.csdnimg.cn/dXx9w


前言

本次记录的是蓝桥杯嵌入式第十四届省赛的程序设计题目。说实话,这次的题目,我费解了许久,因为在练习真题之前没有学习过脉冲捕获这个模块,所以这里是完完全全的小白,虽然很多人说很简单。接下来就一起进入我的打怪旅程吧


一、题目

二、模块实现

1.LED+LCD

/***************************************LED显示部分*******************************************/
//控制所有LED灯的亮灭
void Control_All_Led()
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8 
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

//控制单个LED灯的亮灭
void Control_Single_Led(unsigned char location,unsigned char state)
{
	 HAL_GPIO_WritePin(GPIOC, (location<<8), state);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

}

//为了避免LED和LCD显示冲突进行的处理
void Invoid_Complict()
{
		HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}


void Display_Led()
{
	Invoid_Complict();
	
	//LED1
	if(menu%3==0)
		Control_Single_Led(0x01,0);
	else
		Control_Single_Led(0x01,1);
		
	//LED2
		if(freq==4000 || freq==8000)
		{
			
			Control_Single_Led(0x02,1);
			//打开定时器	
		}
		else 
		{
			led2_sta^=1;
			Control_Single_Led(0x02,led2_sta);
		}
	//LED3
	if(status)
		Control_Single_Led(0x04,1);
	else
		Control_Single_Led(0x04,0);
}
/***************************************LCD显示部分*******************************************/

void Display_Menu()
{
	char str[30];
	
	//数据界面显示
	if(menu%3==0)
	{
		sprintf(str,"        DATA        ");
		LCD_DisplayStringLine(Line1,(u8*)str);
		if(mode==0)
		{
			sprintf(str,"     M=L           ");
			LCD_DisplayStringLine(Line3,(u8*)str);
			speed_l=(freq_l*2*3.14*r)/(100*k);
			sprintf(str,"     V=%.1f          ",speed_l);
			LCD_DisplayStringLine(Line5,(u8*)str);
		}
		else
		{
			sprintf(str,"     M=H           ");
			LCD_DisplayStringLine(Line3,(u8*)str);
			speed_h=(freq_h*2*3.14*r)/(100*k);
			sprintf(str,"     V=%.1f          ",speed_h);
			LCD_DisplayStringLine(Line5,(u8*)str);
		}
		
		sprintf(str,"     P=%.1f%%          ",duty);
		LCD_DisplayStringLine(Line4,(u8*)str);
		
		sprintf(str,"freq=%d  ",freq);
		LCD_DisplayStringLine(Line8,(u8*)str);
	}
	
	//参数界面显示
	else if(menu%3==1)
	{
		sprintf(str,"        PARA        ");
		LCD_DisplayStringLine(Line1,(u8*)str);
		sprintf(str,"     R=%d            ",r);
		LCD_DisplayStringLine(Line3,(u8*)str);
		sprintf(str,"     K=%d            ",k);
		LCD_DisplayStringLine(Line4,(u8*)str);
		sprintf(str,"                     ");
		LCD_DisplayStringLine(Line5,(u8*)str);
	}
	
	//统计界面显示
	else 
	{
		sprintf(str,"        RECD        ");
		LCD_DisplayStringLine(Line1,(u8*)str);
		sprintf(str,"     N=%d           ",n);
		LCD_DisplayStringLine(Line3,(u8*)str);
		sprintf(str,"     MH=%.1f             ",speed_high_max);
		LCD_DisplayStringLine(Line4,(u8*)str);
		sprintf(str,"     ML=%.1f             ",speed_low_max);
		LCD_DisplayStringLine(Line5,(u8*)str);
	}
}

2.定时器+key

定时器回调函数实现:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	//与按键一起使用
	if(htim->Instance==TIM3)
	{
		keys[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		keys[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		keys[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		keys[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		
		for(int i=0;i<4;i++)
		{
			switch(keys[i].key_pro)
			{
				case 0:
					{
						if(keys[i].key_sta==0)
						{
							keys[i].key_pro=1;
							keys[i].key_tim=0;
					}
				break;
				
				case 1:
					{
						if(keys[i].key_sta==0)
						{
							keys[i].key_pro=2;
							keys[i].key_tim++;
						}
						else
							keys[i].key_pro=0;
					}
				break;
				
				case 2:
					{
						if(keys[i].key_sta==1)
						{
							keys[i].key_pro=0;
							if(keys[i].key_tim<=70)
								keys[i].key_sflg=1;
						}
						else
						{
							keys[i].key_tim++;
							if(keys[i].key_tim>70)
								keys[i].key_lflg=1;
						}
					}
				break;
				
				}
			}
		}
	}
	
	if(htim->Instance==TIM4)
	{
		if(is_change_mode==0)
		{
			count_tim++;
			Change_Freq();
			Display_Led();
			if(count_tim==50)
				is_change_mode=1;
		}
	}
}

按键功能实现:

/*************************按键控制****************************/
void Key_Function()
{
	//切换显示界面
	if(keys[0].key_sflg==1)
	{
		menu++;
		keys[0].key_sflg=0;
		change_flag=1;
		Display_Led();
	}
	
	//"选择"按键
	if(keys[1].key_sflg==1)
	{
		//数据界面下
		if(menu%3==0)
		{
			if(is_change_mode)
			{
				mode=mode^1;
				n++;
				Display_Led();
				is_change_mode=0;	//不允许切换模式
				HAL_TIM_Base_Start_IT(&htim4);
				count_tim=0;
				led2_sta=0;
				Control_Single_Led(0x02,led2_sta);
			}
			
			
			
		}
		
		//参数界面下
		if(menu%3==1)
		{
			if(change_flag==1)
			{
				change_para=0;
				change_flag=0;
			}
			else
				change_para=change_para^1;
		}
		keys[1].key_sflg=0;
	}
	
	//加 按键
	if(keys[2].key_sflg==1)
	{
		if(change_para==0)
		{
			if(r==10)
				r=1;
			else
				r++;
		}
		else
		{
			if(k==10)
				k=1;
			else
				k++;
		}
		keys[2].key_sflg=0;
	}
	
	if(keys[3].key_sflg==1)
	{
		if(menu%3==1)
		{
			if(change_para==0)
		{
			if(r==1)
				r=10;
			else
				r--;
		}
		else
		{
			if(k==1)
				k=10;
			else
				k--;
		}
		}
		keys[3].key_sflg=0;
	}
	
	if(keys[3].key_lflg==1)
	{
		if(menu%3==0)
		{
			status=status^1;
			Display_Led();
		}
		keys[3].key_lflg=0;
		keys[3].key_tim=0;
	}
}
/********************************END******************************************/

3.ADC+pwm+脉冲捕获

/*************************ADC*********************************/
float Get_ADC()
{
	HAL_ADC_Start(&hadc2);
	int value;
	value=HAL_ADC_GetValue(&hadc2);
	HAL_ADC_Stop(&hadc2);
	return value*3.3/4096;
}

//电位器调节pwm输出信号占空比
void Pwm_Duty_Change()
{
	if(status)	//可以解锁
	{
		float volt=Get_ADC();
		if(volt<=1.0)
		{
			duty=10;
			__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,100);
		}
		else if(volt>=3.0)
		{
			duty=85;
			__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,850);
		}
		else
		{
			duty=(0.375*volt-0.275)*100;
			__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,(0.375*volt-0.275)*1000);
		}
	}
}
/********************************END******************************************/


//PA1输出信号的频率切换期间频率的均匀变化
void Change_Freq()
{
	if(mode==0)	//从高频到低频
	{
		if(freq!=4000)
		{
			freq=freq-100;	//每次降低100HZ
			__HAL_TIM_SetAutoreload(&htim2,4000000/(freq)-1);//设置自动重载数值
			__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,4000000/(freq)*(duty/100));	//保持占空比不变
		}
	}
	else			//从低频到高频
	{
		if(freq!=8000)
		{
			freq=freq+100;	//每次增加100HZ
			__HAL_TIM_SetAutoreload(&htim2,4000000/(freq)-1);//设置自动重载数值
			__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,4000000/(freq)*(duty/100));	//保持占空比不变
		}
	}

}

//PA7频率测量
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	uint16_t value=0;
	if(htim->Instance==TIM17)
	{
		value=__HAL_TIM_GET_COUNTER(&htim17);
		__HAL_TIM_SetCounter(&htim17,0);
		if(mode)
			freq_h=1000000/value;
		else
			freq_l=1000000/value;
		HAL_TIM_IC_Start_IT(&htim17,TIM_CHANNEL_1);
	}
}

void Get_Speed_Max()
{
	speed_h=(freq_h*2*3.14*r)/100/k;
	speed_l=(freq_l*2*3.14*r)/100/k;
	if(speed_h>speed_high_max)
		speed_high_max=speed_h;
	if(speed_l>speed_low_max)
		speed_low_max=speed_l;
}

总结

以上就是这次打怪过程中的一些主要函数,LED的基本亮灭函数可以去前面几篇文章里面查看,因为都是一样的,所以这里就偷下懒没加喽

这次的程序设计题目感觉比之前的要多一些细节,所以在完成的过程中可能情绪有点波动

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值