第十五届蓝桥杯嵌入式省赛真题解析

博主上午比赛完下午就开源

开源时间---2024年4月13日下午

前言:本人有一定的嵌入式基础做过不少的项目,拿过十几个省级奖项和一个国一

蓝桥杯嵌入式比赛是一个专业性较强的赛事,它主要考察参赛者在STM32微控制器编程和电子学科基础知识方面的能力。以下是对蓝桥杯嵌入式比赛的一些具体分析:

  1. 竞赛内容:蓝桥杯嵌入式组比赛采用STM32G431RBT6 (ARM Cortex M4)作为指定芯片。比赛内容包括客观题和基于硬件平台的程序设计与调试,其中客观题占比15%,程序设计与调试占比85%。
  2. 竞赛要求:参赛者需要具备扎实的C语言编程能力、模拟/数字电子技术基础、熟悉ARM Cortex M4硬件资源以及软件编程与调试知识。此外,熟悉相关软硬件环境和工具也是必不可少的。
  3. 备赛建议:对于准备参加比赛的学生来说,C语言是学习的基础,尤其是位运算和指针等重要概念需要熟练掌握。建议可以从51单片机入手,使用C语言编写代码,实现基本的灯光控制、串口通信等功能,这有助于培养对单片机编程的兴趣和实践能力。
  4. 难度与挑战:由于蓝桥杯嵌入式比赛涉及的内容较为专业和深入,因此对于大一或初学者来说可能存在一定的难度。但通过系统的学习和实践,可以逐步提升自己在嵌入式领域的技能。
  5. 赛事影响:蓝桥杯作为国内知名的IT类竞赛之一,其嵌入式组比赛对于参赛者的专业成长和就业有一定的积极影响。通过参加比赛,学生不仅能够检验自己的学习成果,还有机会获得奖项,增加个人履历的亮点。

蓝桥杯嵌入式比赛是一个对参赛者专业技能有较高要求的赛事,适合有一定基础的学生参加。通过比赛,学生可以提升自己的实际操作能力和解决实际问题的能力,为未来的学习和工作打下坚实的基础。

真题

视频环节

蓝桥杯十五届

省赛LCD菜单模块

  

主要业务代码:

LCD扫描代码

/*
这段代码是一个名为LCD_Scan的函数,用于在LCD屏幕上显示不同的信息。根据不同的条件,它会显示不同的数据和参数。

1. 如果Data_LCD为真,表示需要显示数据:
   - 显示"DATA"在第一行;
   - 如果A_1KHZ_flag为1,显示"A=%.2fKHz"在第三行,其中A_FLOAT是A的频率值;
   - 如果A_1KHZ_flag为0且freq_A_Out_flag为0,显示"A=%dHz"在第三行,其中A是A的频率值;
   - 如果B_1KHZ_flag为1,显示"B=%.2fKHz"在第四行,其中B_FLOAT是B的频率值;
   - 如果B_1KHZ_flag为0且freq_B_Out_flag为0,显示"B=%dHz"在第四行,其中B是B的频率值;
   - 如果freq_A_Out_flag为1,显示"A=NULL"在第三行;
   - 如果freq_B_Out_flag为1,显示"B=NULL"在第四行。

2. 如果Data_LCD_T为真,表示需要显示时间数据:
   - 显示"DATA"在第一行;
   - 如果A_T_ms_flag为1,显示"A=%.2fmS"在第三行,其中A_T_FLOAT是A的时间值;
   - 如果A_T_ms_flag为0且freq_B_Out_flag为0,显示"A=%.0fuS"在第三行,其中A_T是A的时间值;
   - 如果B_T_ms_flag为1,显示"B=%.2fmS"在第四行,其中B_T_FLOAT是B的时间值;
   - 如果B_T_ms_flag为0且freq_B_Out_flag为0,显示"B=%.0fuS"在第四行,其中B_T是B的时间值;
   - 如果freq_A_Out_flag为1,显示"A=NULL"在第三行;
   - 如果freq_B_Out_flag为1,显示"B=NULL"在第四行。

3. 如果argument_LCD为真,表示需要显示参数:
   - 显示"PARA"在第一行;
   - 显示"PD=%d"在第三行,其中P_D是参数D的值;
   - 显示"PH=%d"在第四行,其中P_H是参数H的值;
   - 显示"PX=%d"在第五行,其中P_X是参数X的值。

4. 如果Statistics_LCD为真,表示需要显示统计信息:
   - 显示"RECD"在第一行;
   - 显示"NHA=%d"在第五行,其中NHA是统计信息A的值;
   - 显示"NHB=%d"在第六行,其中NHB是统计信息B的值;
   - 如果NDA大于0,显示"NDA=%d"在第三行,其中NDA是统计信息C的值减1;
   - 如果NDB大于0,显示"NDB=%d"在第四行,其中NDB是统计信息D的值减1;
   - 如果NDA等于0,显示"NDA=%d"在第三行,其中NDA是统计信息C的值;
   - 如果NDB等于0,显示"NDB=%d"在第四行,其中NDB是统计信息D的值。
	 */
void LCD_Scan(void)
{
		char str[50];
		if(Data_LCD)
		{
				sprintf(str,"        DATA");
				LCD_DisplayStringLine_char(Line1,str);
			if(A_1KHZ_flag==1)
			{
				sprintf(str,"     A=%.2fKHz    ",A_FLOAT);
				LCD_DisplayStringLine_char(Line3,str);
			}
			else if(A_1KHZ_flag==0 && freq_A_Out_flag==0)
			{
				sprintf(str,"     A=%dHz    ",A);
				LCD_DisplayStringLine_char(Line3,str);
			}
			if(B_1KHZ_flag==1)
			{
				sprintf(str,"     B=%.2fKHz    ",B_FLOAT);
				LCD_DisplayStringLine_char(Line4,str);;
			
			}
			else if(B_1KHZ_flag==0 && freq_B_Out_flag==0)
			{
				sprintf(str,"     B=%dHz    ",B);
				LCD_DisplayStringLine_char(Line4,str);
			}
			if(freq_A_Out_flag==1)
			{
				sprintf(str,"     A=NULL   ");
				LCD_DisplayStringLine_char(Line3,str);
			}
			if(freq_B_Out_flag==1)
			{
				sprintf(str,"     B=NULL  ");
				LCD_DisplayStringLine_char(Line4,str);
			}
		}
		else if(Data_LCD_T) 
		{
			sprintf(str,"        DATA");
			LCD_DisplayStringLine_char(Line1,str);	
			if(A_T_ms_flag==1)
			{
			
				sprintf(str,"     A=%.2fmS    ",A_T_FLOAT);
				LCD_DisplayStringLine_char(Line3,str);
			}
			else if(A_T_ms_flag==0 && freq_B_Out_flag==0)
			{
				sprintf(str,"     A=%.0fuS    ",A_T);
				LCD_DisplayStringLine_char(Line3,str);
			}
			if(B_T_ms_flag==1)
			{
			sprintf(str,"     B=%.2fmS    ",B_T_FLOAT);
				LCD_DisplayStringLine_char(Line4,str);
			}
			else if(B_T_ms_flag==0 && freq_B_Out_flag==0) 
			{
				sprintf(str,"     B=%.0fuS    ",B_T);
				LCD_DisplayStringLine_char(Line4,str);
			}
			if(freq_A_Out_flag==1)
			{
				sprintf(str,"     A=NULL   ");
				LCD_DisplayStringLine_char(Line3,str);
			}
			if(freq_B_Out_flag==1)
			{
				sprintf(str,"     B=NULL  ");
				LCD_DisplayStringLine_char(Line4,str);
			}
		}
		else if(argument_LCD)
		{
			sprintf(str,"        PARA");
			LCD_DisplayStringLine_char(Line1,str);
			sprintf(str,"     PD=%d    ",P_D);
			LCD_DisplayStringLine_char(Line3,str);
			sprintf(str,"     PH=%d    ",P_H);
			LCD_DisplayStringLine_char(Line4,str);
			sprintf(str,"     PX=%d    ",P_X);
			LCD_DisplayStringLine_char(Line5,str);
		}
		else if(Statistics_LCD)
		{
		sprintf(str,"        RECD");
		LCD_DisplayStringLine_char(Line1,str);
		sprintf(str,"     NHA=%d ",NHA);
		LCD_DisplayStringLine_char(Line5,str);
		sprintf(str,"     NHB=%d ",NHB);
		LCD_DisplayStringLine_char(Line6,str);
		if(NDA>0)
		{
			sprintf(str,"     NDA=%d ",NDA-1);
			LCD_DisplayStringLine_char(Line3,str);
		}
		if(NDB>0)
		{
			sprintf(str,"     NDB=%d ",NDB-1);
			LCD_DisplayStringLine_char(Line4,str);
		}
		if(NDA==0)
		{
			sprintf(str,"     NDA=%d ",NDA);
			LCD_DisplayStringLine_char(Line3,str);
		}
		if(NDB==0)
		{
			sprintf(str,"     NDB=%d ",NDB);
			LCD_DisplayStringLine_char(Line4,str);
		}
		}
		
		
}

频率测量以及参数合法性判断代码

void Capture_Init(void)
{
	HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_2);//开启输入捕获
	HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_1);//开启输入捕获
//	HAL_TIM_IC_Start_IT(&htim16, TIM_CHANNEL_1);//开启输入捕获
	HAL_TIM_IC_Start_IT(&htim8, TIM_CHANNEL_1);//开启输入捕获
}

//定时器2,3,8 主从触发模式输入捕获测量频率函数
float TIM_IC_Capture_GetFreq(TIM_HandleTypeDef *htim,uint32_t channel)
{
	uint32_t capture_value=0;
	float fre;
	capture_value = HAL_TIM_ReadCapturedValue(htim, channel);  //在捕获到上升沿时,会将CNT赋值给CCR 
	fre = 1000000/(capture_value+1);
	return fre;
}
	//定时器2,3,8 主从触发模式输入捕获测量占空比函数
float TIM_IC_Capture_GetDuty(TIM_HandleTypeDef *htim,uint32_t chan1,uint32_t chan2,TIM_HandleTypeDef *htim1)
{
	float Duty;
	uint16_t Autoreload=0;
	Autoreload=htim1->Instance->ARR+1;
	Duty=(HAL_TIM_ReadCapturedValue(htim, chan2)+1) * Autoreload / (HAL_TIM_ReadCapturedValue(htim,chan1) + 1);
	return Duty;
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	uint32_t capture_value=0;
	if(htim->Instance == TIM16)
	{
		//capture_value = TIM17->CCR1;
		capture_value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);  //在捕获到上升沿时,会将CNT赋值给CCR 
		TIM16->CNT = 0;
		fre = 1000000/(capture_value+1);
	}
	
}
void Capture_GetFreq(void)
{
    // 获取定时器8通道1的输入捕获频率,并存储到变量A中
    A = TIM_IC_Capture_GetFreq(&htim8, TIM_CHANNEL_1);
    // 获取定时器3通道1的输入捕获频率,并存储到变量B中
    B = TIM_IC_Capture_GetFreq(&htim3, TIM_CHANNEL_1);
    // 计算输出频率A和B,分别加上P_X
    freq_A_Out = A + P_X;
    freq_B_Out = B + P_X;
    // 将输出频率A和B转换为浮点数,并除以1000
    A_FLOAT = (float)freq_A_Out / 1000;
    B_FLOAT = (float)freq_B_Out / 1000;
    // 计算时间间隔A和B,分别为1/输出频率A和B乘以1000000
    A_T = (float)1 / freq_A_Out * 1000000;
    B_T = (float)1 / freq_B_Out * 1000000;
    // 将时间间隔A和B转换为毫秒,并除以1000
    A_T_FLOAT = (float)1 / freq_A_Out * 1000;
    B_T_FLOAT = (float)1 / freq_B_Out * 1000;
    // 根据NHA_flag的值,判断是否需要更新NHA的值
    if (NHA_flag == 0)
    {
        if (freq_A_Out > P_H)
        {
            NHA_flag = 1;
            NHA++;
        }
    }
    else
    {
        if ( freq_A_Out < P_H)
        {
            NHA_flag = 0;
        }
    }
    // 根据NHB_flag的值,判断是否需要更新NHB的值
    if (NHB_flag == 0)
    {
        if (freq_B_Out  > P_H)
        {
            NHB_flag = 1;
            NHB++;
        }
    }
    else
    {
        if (freq_B_Out   < P_H)
        {
            NHB_flag = 0;
        }
    }
    // 根据输出频率A和B的大小,设置相应的标志位
    if (freq_A_Out > 1000)
    {
        A_1KHZ_flag = 1;
    }
    else
    {
        if (freq_A_Out < 0)
        {
            freq_A_Out_flag = 1;
            A_1KHZ_flag = 0;
        }
        else
        {
            freq_A_Out_flag = 0;
            A_1KHZ_flag = 0;
        }
    }
    if (freq_B_Out > 1000)
    {
        B_1KHZ_flag = 1;
    }
    else
    {
        if (freq_B_Out < 0)
        {
            freq_B_Out_flag = 1;
            B_1KHZ_flag = 0;
        }
        else
        {
            freq_B_Out_flag = 0;
            B_1KHZ_flag = 0;
        }
    }
    // 根据时间间隔A和B的大小,设置相应的标志位
    if (A_T > 1000)
    {
        A_T_ms_flag = 1;
    }
    else
        A_T_ms_flag = 0;
    if (B_T > 1000)
    {
        B_T_ms_flag = 1;
    }
    else
        B_T_ms_flag = 0;
    // 根据P_D、P_H和P_X的值,进行范围限制
    if (P_D < 100 || P_D > 1000)
    {
        if (P_D < 100)
        {
            P_D = 100;
        }
        if (P_D > 1000)
        {
            P_D = 1000;
        }
    }
    if (P_H < 1000 || P_H > 10000)
    {
        if (P_H < 1000)
        {
            P_H = 1000;
        }
        if (P_H > 10000)
        {
            P_H = 10000;
        }
    }
    if (P_X < -1000 || P_X > 1000)
    {
        if (P_X < -1000)
        {
            P_X = -1000;
        }
        if (P_X > 1000)
        {
            P_X = 1000;
        }
    }
}

LED扫描代码

#define LED_ALL_MODE_ON  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET)
#define LED_ALL_MODE_OFF  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET)
#define LED1_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET)
#define LED1_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET)
#define LED2_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET)
#define LED2_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET)
#define LED3_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET)
#define LED3_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET)
#define LED4_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET)
#define LED4_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET)
#define LED5_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET)
#define LED5_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET)
#define LED6_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET)
#define LED6_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET)
#define LED7_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET)
#define LED7_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET)
#define LED8_ON HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET)
#define LED8_OFF HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET)
void Close_LED(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | 
														GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

void Close_LED_UESER(void)
{
	HAL_GPIO_WritePin(GPIOC,   GPIO_PIN_11 | 
														GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

void Open_LED(void)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

void LED_Scan(void)
{
    // 如果Data_LCD或Data_LCD_T为真,则关闭LED用户模式,打开LED1,然后打开LED
    if(Data_LCD||Data_LCD_T)
    {
        Close_LED_UESER();
        LED1_ON;
        Open_LED();
    }
    // 否则,关闭LED1,打开LED,然后关闭LED用户模式
    else
    {
        LED1_OFF;
        Open_LED();
        Close_LED_UESER();
    }
    // 如果freq_A_Out大于P_H,则关闭LED用户模式,打开LED2,然后打开LED
    if(freq_A_Out>P_H)
    {
        Close_LED_UESER();
        LED2_ON;
        Open_LED();
    }
    // 否则,关闭LED用户模式,关闭LED2,然后打开LED
    else
    {
        Close_LED_UESER();
        LED2_OFF;
        Open_LED();
    }
    // 如果freq_B_Out大于P_H,则关闭LED用户模式,打开LED3,然后打开LED
    if(freq_B_Out>P_H)
    {
        Close_LED_UESER();
        LED3_ON;
        Open_LED();
    }
    // 否则,关闭LED用户模式,关闭LED3,然后打开LED
    else
    {
        Close_LED_UESER();
        LED3_OFF;
        Open_LED();
    }
    // 如果flag_A_3或flag_B_3为真,则关闭LED用户模式,打开LED8,然后打开LED
    if(flag_A_3==1||flag_B_3==1)
    {
        Close_LED_UESER();
        LED8_ON;
        Open_LED();
    }
}

按键扫描代码

typedef enum
{
	KEY_Check,			//按键检测
	KEY_Press,			//按键按下
	KEY_Release,		//按键释放
	Key_Over,
}KEY_State;


uint16_t Num=0;
uint8_t KEY_Value=0;
KEY_State KeyState=KEY_Check; //定义结构体
uint8_t KEY_Flag = 0;
uint32_t KEY_Press_TIME=20;	

/*
uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0)
	{
		HAL_Delay(20);
		while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0);
		HAL_Delay(20);
		KeyNum = 1;
	}
	if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0)
	{
		HAL_Delay(20);
		while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 0);
		HAL_Delay(20);
		KeyNum = 2;
	}
	
	return KeyNum;
}
*/

void KeyScan(void)
{
	switch(KeyState)
	{
		case KEY_Check:
		{
			if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))KeyState=KEY_Press;
		}	
		break;
		case KEY_Press:
		{
			if(B1==GPIO_PIN_RESET)KEY_Value=1;
			else if(B2==GPIO_PIN_RESET)KEY_Value=2;
			else if(B3==GPIO_PIN_RESET)KEY_Value=3;
			else if(B4==GPIO_PIN_RESET)KEY_Value=4;	
			KeyState=KEY_Release;	
		}	
		break;
		case KEY_Release:
		{
			if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))
			{
				KEY_Press_TIME=KEY_Press_TIME+10;
			}
			else 
			{
				KeyState=KEY_Check;
				KEY_Flag=1;
			}
		}	
		break;
		default:break;		
	}
}
/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
	static uint8_t Key_Start_Time=0;
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	if(++Key_Start_Time==10)
	{
		Key_Start_Time=0;
		KeyScan();
	}
  /* USER CODE END SysTick_IRQn 1 */
}

```c
if(KEY_Flag==1) //按键  滴答定时器扫描按锿

	{
		KEY_Flag=0;
		// 根据按键值进行相应操作
		if(KEY_Value==1){
			// 如果argument_LCD_flag为0,P_D增加100
			if(argument_LCD_flag==0)
			{
				P_D+=100;
			}
			// 如果argument_LCD_flag为1,P_H增加100
			else if(argument_LCD_flag==1)
			{
				P_H+=100;
			}
			// 如果argument_LCD_flag为2,P_X增加100
			else if(argument_LCD_flag==2)
			{
				P_X+=100;
			}
		}
		else if(KEY_Value==2){
			// 如果argument_LCD_flag为0,P_D减少100
			if(argument_LCD_flag==0)
			{
				P_D-=100;
			}
			// 如果argument_LCD_flag为1,P_H减少100
			else if(argument_LCD_flag==1)
			{
				P_H-=100;
			}
			// 如果argument_LCD_flag为2,P_X减少100
			else if(argument_LCD_flag==2)
			{
				P_X-=100;
			}
		}
		else if(KEY_Value==3 && KEY_Press_TIME<=1000){
			// 如果Data_LCD为真,清屏并设置背景色、文本颜色等
			if(Data_LCD)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				Data_LCD_T=1;Data_LCD=0,argument_LCD=0,Statistics_LCD=0;
			}
			// 如果Data_LCD_T为真,清屏并设置背景色、文本颜色等
			else if(Data_LCD_T)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				Data_LCD_T=0;Data_LCD=1,argument_LCD=0,Statistics_LCD=0;
			}
			// 如果argument_LCD为真,argument_LCD_flag加1,如果超过2则重置为0
			else if(argument_LCD)
			{
				argument_LCD_flag++;
				if(argument_LCD_flag==3)
				{
					argument_LCD_flag=0;
				}
			}
		}
		else if(KEY_Value==3 && KEY_Press_TIME>1000){
			// 如果Statistics_LCD为真,重置NDA、NDB、NHA、NHB、flag_A_3、flag_B_3的值
			if(Statistics_LCD)
			{
				NDA=0;
				NDB=0;
				NHA=0;
				NHB=0;
				flag_A_3=0;
				flag_B_3=0;
			}
		}
		else if(KEY_Value==4){
			// 如果Data_LCD为真,清屏并设置背景色、文本颜色等
			if(Data_LCD)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				Data_LCD=0,argument_LCD=1,Statistics_LCD=0,Data_LCD_T=0;;
			}
			// 如果Data_LCD_T为真,清屏并设置背景色、文本颜色等
			else if(Data_LCD_T)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				Data_LCD=0,argument_LCD=1,Statistics_LCD=0,Data_LCD_T=0;;
			}
			// 如果argument_LCD为真,清屏并设置背景色、文本颜色等,将argument_LCD_flag设置为0,将Data_LCD、argument_LCD、Statistics_LCD设置为相应的值
			else if(argument_LCD)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				argument_LCD_flag=0;
				Data_LCD=0,argument_LCD=0,Statistics_LCD=1,Data_LCD_T=0;;
			}
			// 如果Statistics_LCD为真,清屏并设置背景色、文本颜色等,将Data_LCD、argument_LCD、Statistics_LCD设置为相应的值
			else if(Statistics_LCD)
			{
				LCD_Clear(Black);
				LCD_SetBackColor(Black);
				LCD_SetTextColor(White);
				Data_LCD=1,argument_LCD=0,Statistics_LCD=0,Data_LCD_T=0;;
			}
		}
        // 将KEY_Press_TIME设置为20
        KEY_Press_TIME=20;
    }
```

初始化代码


uint32_t ADC_Value[2];  // [0]为R37的模拟忿,[1]为R38的模拟忿
extern Uart_Tpye_t Uart1;  // 外部定义的UART类型变量Uart1
uint32_t fre_PWM, fre_555, Duty;  // PWM频率、555定时器频率和占空比
uint32_t P_H = 5000, P_D = 1000;  // 设置P_H和P_D的初始值
int P_X = 0;  // 初始化P_X变量
int freq_A_Out, freq_B_Out;  // 定义频率输出变量A和B
uint8_t Data_LCD = 1, argument_LCD = 0, Statistics_LCD = 0, Data_LCD_T = 0;  // LCD显示数据和参数变量
extern uint32_t A, B, NDA, NDB, NHA, NHB;  // 外部定义的A、B、NDA、NDB、NHA、NHB变量
extern float A_FLOAT, B_FLOAT, A_T, B_T;  // 外部定义的浮点型A、B、A_T、B_T变量
extern uint8_t flag_A_3, flag_B_3;  // 外部定义的标志位变量flag_A_3和flag_B_3
uint8_t A_1KHZ_flag, B_1KHZ_flag, A_T_ms_flag, B_T_ms_flag, freq_A_Out_flag, freq_B_Out_flag, NHA_flag, NHB_flag, argument_LCD_flag, NDA_flag, NDB_flag;  // 各种标志位变量


    Capture_Init();  //输入捕获初始匿
	TIM_init();   //定时器初始化
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
//	LCD_Test();
	HAL_ADC_Start_DMA(&hadc2,&ADC_Value[0],1);  //以DMA的方式开启ADC2转换
	HAL_ADC_Start_DMA(&hadc1,&ADC_Value[1],1);  //以DMA的方式开启ADC1转换
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打开串口空闲中断 
	HAL_UART_Receive_DMA(&huart1, Uart1.RxBuf, RX_MAXLEN); //串口DMA接收数据

定时器扫描频率代码,3秒一个周期

uint8_t flag_A_3,flag_B_3; // 定义标志位变量
uint32_t count; // 定义计数变量
uint32_t max_A,min_A=100000,max_B,min_B=100000,m_A_OUT,m_B_OUT; // 定义最大值、最小值和差值变量
extern uint32_t A,B,NDA,NDB,NHA,NHB; // 声明外部变量
extern int freq_A_Out,freq_B_Out; // 声明外部变量
extern uint32_t  P_H,P_D; // 声明外部变量
extern int P_X; // 声明外部变量
extern uint8_t A_1KHZ_flag,B_1KHZ_flag,A_T_ms_flag,B_T_ms_flag,freq_A_Out_flag,freq_B_Out_flag,NHA_flag,NHB_flag,NDA_flag,NDB_flag; // 声明外部变量

void TIM_init(void) // 定时器初始化函数
{
	HAL_TIM_Base_Start_IT(&htim6); // 启动定时器中断
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // 定时器中断回调函数
{
	if(htim->Instance==TIM6) // 判断是否为TIM6定时器
	{
		if(NDA==4||NDB==4) // 如果NDA或NDB等于4
		{
			flag_A_3=1; // 设置标志位A_3为1
			flag_B_3=1; // 设置标志位B_3为1
			
		}
			count++; // 计数加1
			
			if(freq_A_Out>max_A) // 如果freq_A_Out大于max_A
				max_A=freq_A_Out; // 更新max_A的值
			if(freq_A_Out<min_A) // 如果freq_A_Out小于min_A
				min_A=freq_A_Out; // 更新min_A的值
			if(freq_B_Out>max_B) // 如果freq_B_Out大于max_B
				max_B=freq_B_Out; // 更新max_B的值
			if(freq_A_Out<min_B) // 如果freq_A_Out小于min_B
				min_B=freq_A_Out; // 更新min_B的值
			if(count>=300) // 如果计数大于等于300
			{
				count=0; // 重置计数
				m_A_OUT=max_A-min_A; // 计算差值A
				m_B_OUT=max_B-min_B; // 计算差值B
				if(m_A_OUT>P_D) // 如果差值A大于P_D
				{
					NDA++; // NDA加1
				}
				if(m_B_OUT>P_D) // 如果差值B大于P_D
				{
					NDB++; // NDB加1
				}
				max_A=0;min_A=100000; // 重置最大值和最小值A
				max_B=0;min_B=100000; // 重置最大值和最小值B
				m_A_OUT=0; // 重置差值A
				m_B_OUT=0; // 重置差值B
			}
		
	}

}

工程分享:赛后默写出来的代码,掺杂了其他工程的模版

链接:https://pan.baidu.com/s/1O_WNCx6nhrGHHvsGbxvzqA 
提取码:4135


  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一月千帆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值