第十三届蓝桥杯嵌入式省赛程序设计详细题解

03-06 1700阅读 0评论

第十三届蓝桥杯嵌入式省赛题目相对于第十二届较为简单,没有那么多串口的数据处理以及判断!

第十三届蓝桥杯嵌入式省赛程序设计详细题解,第十三届蓝桥杯嵌入式省赛程序设计详细题解,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,方法,第1张
(图片来源网络,侵删)

第十三届省赛主要是制作一个可由串口设置密码的密码锁。本实验中,我们将用到LED模块、按键模块、串口模块、定时器的PWM模块以及官方会提供源码的LCD模块。

文末有小编写的代码

一、CubeMX配置

1.使能外部高速时钟:

第十三届蓝桥杯嵌入式省赛程序设计详细题解

2.配置时钟树:

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛程序设计详细题解

4.GPIO输入

第十三届蓝桥杯嵌入式省赛程序设计详细题解

5. TIM定时器

5.1 TIM2输出PWM脉冲

第十三届蓝桥杯嵌入式省赛程序设计详细题解

设置默认Pluse为50,即占空比为50%

第十三届蓝桥杯嵌入式省赛程序设计详细题解

5.2 TIM4实现定时5s

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛程序设计详细题解

5.3 TIM3定时器实现微妙(us)延迟

第十三届蓝桥杯嵌入式省赛程序设计详细题解

6.USART(通信)

USART串口接收数据,我使用两种方法实现,大家选取其中一种即可!

1.定长接收数据

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛程序设计详细题解

2,不定长接收数据+DMA方式

此种方法的核心是空闲中断!

第十三届蓝桥杯嵌入式省赛程序设计详细题解

二、代码实现

2.1 main函数实现

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
  LCD_Init();
  LCD_Clear(Black);
  LCD_SetBackColor(Black);
  LCD_SetTextColor(White);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
	led(1,0);
	led(2,0);
	led(3,0);
	led(4,0);
	led(5,0);
	led(6,0);
	led(7,0);
	led(8,0);
    HAL_UART_Receive_IT(&huart1, buff, 7);
	HAL_TIM_Base_Start_IT(&htim4);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	  Key_handle();
	  lcd();
	  if(key4_count>=3&&led_flag==0)
	  {
		led(2,1);
		delay_us(50000);
		delay_us(50000);
		led(2,0);
		delay_us(50000);
		delay_us(50000);
	  }
  }
  /* USER CODE END 3 */
}

2.2 lcd函数实现

void lcd()
{
	if(pass_flag==1)
	{
		show_output();	
		if(systick-PWMTick>5000)
		{
			led(1,0);
			pwm1();
			first='@';
			first_flag=-1;
			second='@';
			second_flag=-1;
			third='@';
			third_flag=-1;
		
			pass_flag=0;
			LCD_Clear(Black);
		}	
	}
	if(pass_flag==0)
	{
		show_input();		
	}
}
void show_input()
{
	LCD_DisplayStringLine(Line1,"       PSD             ");
	sprintf(B1,"    B1:%c",first);
	LCD_DisplayStringLine(Line3,B1);
	sprintf(B2,"    B2:%c",second);
	LCD_DisplayStringLine(Line4,B2);
	sprintf(B3,"    B3:%c",third);
	LCD_DisplayStringLine(Line5,B3);
}
char pl[50];
char zkb[50];
int c_pl;
int c_ARR;
int c_zkb;
int c_pluse;
void show_output()
{
	LCD_DisplayStringLine(Line1,"       STA             ");
	c_ARR=__HAL_TIM_GET_AUTORELOAD(&htim2);
	c_pl=100000/(c_ARR+1);
	sprintf(pl,"    F:%dHz",c_pl);
	LCD_DisplayStringLine(Line3,pl);
	
	c_pluse=__HAL_TIM_GET_COMPARE(&htim2,TIM_CHANNEL_2);
	c_zkb=c_pluse*100/(c_ARR+1);
	sprintf(zkb,"    S:%d%%",c_zkb);
	LCD_DisplayStringLine(Line4,zkb);
}

2.3 按键扫描功能实现

int Keynum()
{
	int key=0;
	if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0)
	{
		HAL_Delay(5);
		if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0)
		{
			key=1;
			  LCD_Clear(Black);
		}
		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0);
	}
	
	if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0)
	{
		HAL_Delay(5);
		if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0)
		{
			key=2;
			  LCD_Clear(Black);
		}
		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0);
	}
	
	if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0)
	{
		HAL_Delay(5);
		if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0)
		{
			key=3;
			  LCD_Clear(Black);
		}
		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0);
	}
	
	if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0)
	{
		HAL_Delay(5);
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0)
		{
			key=4;
			 LCD_Clear(Black);
		}
		while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0);
	}
	
	return key;
}
char first='@';
int first_flag=-1;
char second='@';
int second_flag=-1;
char third='@';
int third_flag=-1;
char pass1='1';
char pass2='2';
char pass3='3';
int pass_flag=0;
int lcd_flag=0;
int ledTick=0;
void Key_handle()
{
	int keynum=Keynum();
	if(keynum==1)
	{
			first_flag++;
			switch(first_flag%10)
			{
				case 0:first='0';break;
				case 1:first='1';break;
				case 2:first='2';break;
				case 3:first='3';break;
				case 4:first='4';break;
				case 5:first='5';break;
				case 6:first='6';break;
				case 7:first='7';break;
				case 8:first='8';break;
				case 9:first='9';break;
			}
	}
	
	if(keynum==2)
	{
			second_flag++;
			switch(second_flag%10)
			{
				case 0:second='0';break;
				case 1:second='1';break;
				case 2:second='2';break;
				case 3:second='3';break;
				case 4:second='4';break;
				case 5:second='5';break;
				case 6:second='6';break;
				case 7:second='7';break;
				case 8:second='8';break;
				case 9:second='9';break;
			}
	}
	
	
	if(keynum==3)
	{
			third_flag++;
			switch(third_flag%10)
			{
				case 0:third='0';break;
				case 1:third='1';break;
				case 2:third='2';break;
				case 3:third='3';break;
				case 4:third='4';break;
				case 5:third='5';break;
				case 6:third='6';break;
				case 7:third='7';break;
				case 8:third='8';break;
				case 9:third='9';break;
			}
	}
	if(keynum==4)
	{
		led_flag=0;
		key4_count++;
		if(pass1==first&&pass2==second&&pass3==third)
		{
			key4_count=0;
			pass_flag=1;
			pwm2();
			led(1,1);
			//定时器中断在回调函数中清屏函数不起作用
//			__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_UPDATE);
//		    HAL_TIM_Base_Start_IT(&htim1);
			PWMTick=systick;		
		}
		else
		{
			pass_flag=0;
			first='@';
			first_flag=-1;
			second='@';
			second_flag=-1;
			third='@';
			third_flag=-1;
		}
		
		if(key4_count>=3)
		{
			__HAL_TIM_CLEAR_FLAG(&htim4,TIM_FLAG_UPDATE);
		    HAL_TIM_Base_Start_IT(&htim4);
		}
	}
}

2.4 PWM脉冲转换

void pwm2()
{
	__HAL_TIM_SET_AUTORELOAD(&htim2,50-1);
	__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,5);
}
//方波
void pwm1()
{
	__HAL_TIM_SET_AUTORELOAD(&htim2,100-1);
	__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);
}

2.5 某种状态持续5s的两种操作方法

1.利用系统滴答计时器

本实验中 实现输出2KHz 10%占空比的脉冲信号,持续5秒钟,切换为 1KHz 方波信号输出的功能 使用的是系统滴答计时器。

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛程序设计详细题解

2.TIM定时器定时5s

本实验中实现 指示灯 LD2 以 0.1秒为间隔亮、灭闪烁报警,5 秒后熄灭的功能使用的是TIM4定时器定时5s。

第十三届蓝桥杯嵌入式省赛程序设计详细题解

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM4)
	{
			led_flag=1;
			HAL_TIM_Base_Stop_IT(&htim4);	
	}
}

2.6 延迟100ms

delay_us函数实现定时微妙(us)

void delay_us(int delay)
{
	HAL_TIM_Base_Start(&htim3);        // 启动定时器
 	 __HAL_TIM_SET_COUNTER(&htim3, 0);  // 重置计数器
  	while (__HAL_TIM_GET_COUNTER(&htim3)  

delay_us(50000)代表延迟50000us即50ms,但因为定时器最大计数值为65535,如果delay_us(100000)就超过了定时器最大计数值,所以可以采取delay_us(50000)两次来实现100ms定时!

第十三届蓝桥杯嵌入式省赛程序设计详细题解

2.7 USART串口与修改密码

USART串口接收数据,我使用两种方法实现,大家选取其中一种即可!

1.接收固定长度数据

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(buff[0]==pass1&&buff[1]==pass2&&buff[2]&&buff[3]=='-'&&judge()==1)
	{
		pass1=buff[4];
		pass2=buff[5];
		pass3=buff[6];
		HAL_UART_Transmit(&huart1,(unsigned char *)"Success\r\n", 9, 50);
	}
	else
	{
		HAL_UART_Transmit(&huart1,(unsigned char *)"error\r\n", 7, 50);
	}
	HAL_UART_Receive_IT(&huart1, buff, 7);
}
int judge()
{
	for(int i=0;i
		if((buff[i]
			return 1;
		}
	}
}

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

发表评论

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

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

目录[+]