天天看点

第十一届蓝桥杯(嵌入式)总决赛--哈总结

蓝桥杯(嵌入式)总决赛

  • 总结
    • 试题分析
    • 参赛感想
    • 代码分享

总结

试题分析

这一届国赛试题总体来说难度很小,和省赛的难度差不多。考到了LED,KEY,ADC,PWM的输入捕获和PWM的输出,和第八届国赛有点相似,所以试题挺简单,就看你的细节以及选择题做的怎么样了。原本想拿国一,可实力不允许呀,拿了国二👀

参赛感想

好不容易进了决赛,很遗憾北京没有去成/(ㄒoㄒ)/~~,拿了国二,成绩不算好,也还说得过去.原本以为今年国赛会挺难的,毕竟省赛很简单,结果国赛和省赛的难度差不多.程序上就靠细节拉分了,再就是看选择题谁猜得准了.别人我不知道,反正我的选择题猜了好几个😄,感觉选择题很难准备,考的范围比较大,让俺无从下手,所以俺就听天由命,猜对一个是一个🤭.考了五个小时,坐着硬硬的板凳,敲着脏脏键盘,仰着脖子,不好受呀,我的电脑还老提醒我更新,隔一个小时提醒一次🤮,我就只能让它再等一个小时,再等一个小时…不容易呀

代码分享

led.c文件

#include "led.h"
//LED初始化
void LED_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	/* GPIOD Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);
  /* Configure PD0 and PD2 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_All;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  LED_Control(0x00);
}

//LED控制函数
void LED_Control(u8 status)
{
   GPIOC->ODR=(~status)<<8;
   GPIOD->BSRR=GPIO_Pin_2;
   GPIOD->BRR=GPIO_Pin_2;
}
           

key.c文件

#include "key.h"
#include "main.h"
//初始化
void KEY_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	/* GPIOD Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE);
  /* Configure PD0 and PD2 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2|GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_8;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
extern  _KEY_ENUM  KEY_Short;//定义的枚举型变量,在main.h中展示
//按键的宏定义
#define  K1_Read   (GPIOA->IDR&GPIO_Pin_0)
#define  K2_Read   (GPIOA->IDR&GPIO_Pin_8)
#define  K3_Read   (GPIOB->IDR&GPIO_Pin_1)
#define  K4_Read   (GPIOB->IDR&GPIO_Pin_2)

//按键的读取
void KEY_Read(void)
{
	static u8 KEY_Clear=0;
	static FlagStatus KEY_Wait=RESET;
	static _KEY_ENUM KEY_Temp=KOFF;
	if(K1_Read==0||K2_Read==0||K3_Read==0||K4_Read==0)
	{
	  if(++KEY_Clear>=3)   //消抖处理
	  {
	    if(K1_Read==0)	KEY_Temp=K1;
		else  if(K2_Read==0)	KEY_Temp=K2;
		else  if(K3_Read==0)	KEY_Temp=K3;
		else  if(K4_Read==0)	KEY_Temp=K4;

		KEY_Wait=SET;
	  }
	}
	else
	{
	  KEY_Clear=0;
	  if(KEY_Wait!=RESET)
	  {
	  	KEY_Wait= RESET;
		KEY_Short=KEY_Temp;
		KEY_Temp=KOFF;
	  }
	}
}
           

tim2.c文件(PWM的输入捕获)

//初始化
void TIM_Input(void)
{
  TIM_ICInitTypeDef  TIM_ICInitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
  /* Enable the TIM3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* TIM3 channel 2 pin (PA.07) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  TIM_TimeBaseStructure.TIM_Period =0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
  TIM_Cmd(TIM2, ENABLE);
  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_CC3, ENABLE);
}

//中断服务函数
u8 OC2_Mode=0;
u32 OC2_H=0;
u32 OC2_HL=0;
u8 OC3_Mode=0;
u32 OC3_H=0;
u32 OC3_HL=0;

void TIM2_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
	switch(OC2_Mode)
	{
	 case 0:
	 {
	   OC2_H=0;
	   OC2_HL=0;
	   OC2_Mode=1;
	   TIM_SetCounter(TIM2,0x00);
	   TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling);
	   break;
	 }
	 case 1:
	 {
	   OC2_H=TIM_GetCounter(TIM2);
	   OC2_Mode=2;
	   TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
	   break;
	 }
	 case 2:
	 {
	   OC2_HL=TIM_GetCounter(TIM2);
	   OC2_Mode=3;
	   TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
	   break;
	 }
	 default:break;
	}
  }  
  if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
	switch(OC3_Mode)
	{
	 case 0:
	 {
	   OC3_H=0;
	   OC3_HL=0;
	   OC3_Mode=1;
	   TIM_SetCounter(TIM2,0x00);
	   TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);
	   break;
	 }
	 case 1:
	 {
	   OC3_H=TIM_GetCounter(TIM2);
	   OC3_Mode=2;
	   TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
	   break;
	 }
	 case 2:
	 {
	   OC3_HL=TIM_GetCounter(TIM2);
	   OC3_Mode=3;
	   TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
	   break;
	 }
	 default:break;
	}
  }
}
           

tim3.c文件(PWM的输出)

//我这里用的是比较输出,输出的占空比固定为50%
u32 TIM3_Fre=0;
u32 TIM3_Dut=0;
void TIM_Output(u32 Fre)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
   TIM_OCInitTypeDef  TIM_OCInitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);
  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /*GPIOB Configuration: TIM3 channel1, 2, 3 and 4 */
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  TIM3_Fre=1000000/Fre;
  TIM3_Dut=TIM3_Fre*50/100;
  TIM_TimeBaseStructure.TIM_Period = 0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = TIM3_Fre;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
  TIM_ARRPreloadConfig(TIM3, DISABLE);
  TIM_ITConfig(TIM3,  TIM_IT_CC2 , ENABLE);
  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);
}
//中断服务函数
u32 capture=0;
u8 TIM3_Flag=0;
void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    capture = TIM_GetCapture2(TIM3);
	if(TIM3_Flag)
	{
    	TIM_SetCompare2(TIM3, capture + TIM3_Dut);
	}
	else
	{
	    TIM_SetCompare2(TIM3, capture + TIM3_Fre - TIM3_Dut);
	}
	TIM3_Flag^=1;
  }
}
           

main.h文件(一些结构体.枚举类型变量的定义)

typedef enum
{
  K1=1,
  K2=2,
  K3=3,
  K4=4,
  KOFF=0,
}_KEY_ENUM;//按键

typedef struct
{
 float AO1;
 float AO2;
 u32 PULS1;
 u32 PULS2;
}_DATA_Struct;//主界面显示的数据

typedef struct
{
u8 VD;
u8 FD;
u8 VD1;
u8 FD1;
}_LED_Struct;//报警的灯
           

adc.c文件

//初始化
void ADCx2_Init(void)
{
  ADC_InitTypeDef ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
  /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channel14 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_55Cycles5);
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE); 
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));
  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));     
}

//
u32 Get_ADC(u8 channel)
{
  u32 temp;
  ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_55Cycles5);	
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
  ADC_ClearFlag(ADC1,ADC_FLAG_EOC);	
  temp=ADC1->DR;
  ADC_SoftwareStartConvCmd(ADC1, DISABLE);
  return temp;
}
//简单的一个均值滤波
u32 Filt_Num(u8 channel)
{
  u8 i;
  u32 sum=0;
  for(i=0;i<10;i++)
  {
  	sum+=Get_ADC(channel);
  }
  return sum/10;
}
           

main.c文件(逻辑地实现)

u32 TimingDelay = 0;
u8 string[20];
_KEY_ENUM  KEY_Short=KOFF;
_DATA_Struct DATA_Val={0.0,0.0,2000,1000,};
_LED_Struct LED_Show={1,2,1,2};
FlagStatus LCD_Sow_Flag=RESET;  //zhu jie mian
FlagStatus _10ms_EN=RESET;
FlagStatus _100ms_EN=RESET;
FlagStatus _500ms_EN=RESET;
FlagStatus _800ms_EN=RESET;
u32 Pin7_Fre;
u8 count=0;
u8 status=0;
u8 LED_Status=0x00;
extern u8 OC2_Mode;
extern u32 OC2_H;
extern u32 OC2_HL;
extern u8 OC3_Mode;
extern u32 OC3_H;
extern u32 OC3_HL;
//相关函数的声明
void Delay_Ms(u32 nTime);
void LCD_Pro(void);
void Get_Volt(void);
void KEY_Pro(void);

//Main Body
int main(void)
{	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SysTick_Config(SystemCoreClock/1000);
	Delay_Ms(200);	
	STM3210B_LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	LED_init();
	ADCx2_Init();
	KEY_Init();
	TIM_Input();
	count=count+1;	
	while(1)
	{
	   if(_10ms_EN!=RESET)
	   {
	   KEY_Pro();
	      _10ms_EN=RESET;
	   }
	   if(_100ms_EN!=RESET)
	   {
	   LCD_Pro();
	   Get_Volt();
	      _100ms_EN=RESET;
		  LED_Control(LED_Status);
	   }
	   if(count==1)
	   {
	      Pin7_Fre=DATA_Val.PULS1;
		  count++;
	   }
	   if(_800ms_EN!=RESET)
	   {
		  if(status==0)
		   {
		      Pin7_Fre=DATA_Val.PULS1;
		   }
		   else if(status==1)
		   {
		      Pin7_Fre=DATA_Val.PULS2;
		   }
	       _800ms_EN=RESET;
		   TIM_Output(Pin7_Fre);
	   }
	}
}
//LCD显示函数
void LCD_Pro(void)
{
	if(LCD_Sow_Flag==RESET)
	{
	  LCD_DisplayStringLine(Line1,(u8*)"    DATA            ");
		sprintf((char*)string,"    V1:%2.1fV         ",DATA_Val.AO1);
		LCD_DisplayStringLine(Line3,string);
		sprintf((char*)string,"    V2:%2.1fV         ",DATA_Val.AO2);
		LCD_DisplayStringLine(Line4,string);
		if(_500ms_EN!=RESET)
		{
		    _500ms_EN=RESET	;
			if(OC2_Mode==3)
			{
				DATA_Val.PULS1=1000000/OC2_HL;
				sprintf((char*)string,"    F1:%dHz           ",DATA_Val.PULS1);
				LCD_DisplayStringLine(Line5,string);
				OC2_Mode=0;
			}
			if(OC3_Mode==3)
			{
				DATA_Val.PULS2=1000000/OC3_HL;
				sprintf((char*)string,"    F2:%dHz           ",DATA_Val.PULS2);
				LCD_DisplayStringLine(Line6,string);
				OC3_Mode=0;
			}
			if(DATA_Val.PULS1>DATA_Val.PULS2)
			 {
			  	 LED_Status|=0x01<<(LED_Show.FD1-1);
			 }
			  else
				 LED_Status&=~(0x01<<(LED_Show.FD1-1));
		}	
	}
	else if(LCD_Sow_Flag!=RESET)
	{
	  LCD_DisplayStringLine(Line1,(u8*)"    PARA            ");
		sprintf((char*)string,"    VD:LD%d          ",LED_Show.VD);
		LCD_DisplayStringLine(Line3,string);
		sprintf((char*)string,"    FD:LD%d          ",LED_Show.FD);
		LCD_DisplayStringLine(Line4,string);
		LCD_DisplayStringLine(Line5,(u8*)"                    ");
		LCD_DisplayStringLine(Line6,(u8*)"                    ");
	}
}
//获取两个通道的电压值
void Get_Volt(void)
{
  DATA_Val.AO1=Filt_Num(4)*3.3/4095.0;
  DATA_Val.AO2=Filt_Num(5)*3.3/4095.0;

  if(DATA_Val.AO1>DATA_Val.AO2)
  {
  	 LED_Status|=0x01<<(LED_Show.VD1-1);
  }
  else
	 LED_Status&=~(0x01<<(LED_Show.VD1-1));
}

//案件处理函数
void KEY_Pro(void)
{
  KEY_Read();
  switch(KEY_Short)
  {
   case KOFF:break;
   case K1:
   {
    KEY_Short=KOFF;
   	if(LCD_Sow_Flag==RESET)
	{
		LCD_Sow_Flag=SET;
	} 
	else if(LCD_Sow_Flag!=RESET)
	{
		LED_Status=0x00;
	    LCD_Sow_Flag=RESET;
		LED_Show.VD1=LED_Show.VD;
		LED_Show.FD1=LED_Show.FD;
	}
   	break;
   }
   case K2:
   {
    KEY_Short=KOFF; 
	 if(LCD_Sow_Flag!=RESET)
	 {   	    
	    if(LED_Show.VD==8)
		{
			if(LED_Show.FD!=1)
			 LED_Show.VD=1;
			else
			 LED_Show.VD=2;
		}
		else if(LED_Show.VD==7)
		{
			if(LED_Show.FD!=8)
			 LED_Show.VD=LED_Show.VD+1;
			 else
			 LED_Show.VD=1; 
		}
		else if(LED_Show.VD<7)
		{
		 if((LED_Show.VD+1)!=LED_Show.FD)
		 LED_Show.VD=LED_Show.VD+1;
		 else
		 LED_Show.VD=LED_Show.VD+2;
		}
	}
   	break;
   }
  case K3:
   {
    KEY_Short=KOFF; 
	 if(LCD_Sow_Flag!=RESET)
	{
	    if(LED_Show.FD==8)
		{
			if(LED_Show.VD!=1)
			 LED_Show.FD=1;
			else
			 LED_Show.FD=2;
		}
		else if(LED_Show.FD==7)
		{
			if(LED_Show.VD!=8)
			 LED_Show.FD=LED_Show.FD+1;
			 else
			 LED_Show.FD=1; 
		}
		else if(LED_Show.FD<7)
		{
		if((LED_Show.FD+1)!=LED_Show.VD)
		 LED_Show.FD=LED_Show.FD+1;
		 else
		 LED_Show.FD=LED_Show.FD+2;
		}
	}
   	break;
   }
  case K4:
  {
  KEY_Short=KOFF;
   if(status==0)
   {
	  status=1;
   }
   else	 if(status==1)
   {
   	  status=0	;
   }
   break;
  }
  }
}
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}
//滴答定时器
void SysTick_Handler(void)
{
  static u32 _10ms_Flag=0,_100ms_Flag=0,_500ms_Flag=0,_800ms_Flag=0;
	_10ms_Flag++;
	_100ms_Flag++;
    _500ms_Flag++;
	_800ms_Flag++;
	if(_800ms_Flag>=1000)
	{
	 _800ms_Flag=0;
	 _800ms_EN=SET;
	}
	if(_10ms_Flag>=10)
	{
	   _10ms_Flag=0;
	   _10ms_EN=SET;
	}
	if(_100ms_Flag>=100)
	{
	   _100ms_Flag=0;
	   _100ms_EN=SET;
	}
	if(_500ms_Flag>=500)
	{
	   _500ms_Flag=0;
	   _500ms_EN=SET;
	}
	TimingDelay--;
}
           

继续阅读