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

目录

系列文章目录

文章目录

前言

一、程序设计题目介绍

二、cubemx主要配置

1.定时器配置

2.串口配置

3.LED,按键配置

三、程序模块代码编写

1.LED模块

2.按键模块

3.LCD模块

4.串口模块

5.其他函数模块

总结


系列文章目录

往期文章:

第十一届

http://t.csdnimg.cn/CI3JE

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

http://t.csdnimg.cn/oVkD3

http://t.csdnimg.cn/AoCLS



前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、程序设计题目介绍

二、cubemx主要配置

1.定时器配置

普通定时器TIM2,这里我是用作pwm的输出

普通定时器TIM3,这里我是用作计时0.1s

普通定时器TIM4,这里我是用来按键消抖的

(PS:下面的几张图片分别是TIM2,TIM3,TIM4的配置,这次没有全屏截图了,李姐一下哈

2.串口配置

串口这里需要注意的是一定要打开接收和发送的引脚,这里我用的是USART1,所以处理好PA9,PA10的引脚

3.LED,按键配置

三、程序模块代码编写

1.LED模块

#include "led.h"

//控制所有LED灯亮灭
void Contro_Led(unsigned char state)
{
	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, state);
													
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	
}

//控制单个LED灯的亮灭
void Contro_One_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综合使用函数:

void Display_led()
{
	if(is_correct==1)
	{
		
		//LED1亮5秒后熄灭
		count=0;
		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);
		Contro_One_Led(0x01,0);
		HAL_TIM_Base_Start_IT(&htim3);
	
	}
	
	else if(is_correct==0 && error_counts>=3)
	{
		//	LED2每隔0.1秒切换亮灭,保持5秒钟
		count=0;
		led2_sta=1;
		
		//这里同样是解决LCD,LED显示冲突的一个小处理
		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);
		Contro_One_Led(0x02,led2_sta);
		
		//从这里打开定时器3,避免时间上有误差
		HAL_TIM_Base_Start_IT(&htim3);
	}

}
//串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		RXbuff[BufIndex++]=Rxdat;
		HAL_UART_Receive_IT(&huart1, &Rxdat, 1);
	}

}

2.按键模块

/**************************定时器回调函数******************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM4)
	{
		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(unsigned char i=0;i<4;i++)
		{
			switch(keys[i].key_pro)
			{
				case 0:
					{
						if(keys[i].key_sta==0)
							keys[i].key_pro=1;
					}
					break;
				
				case 1:
					{
						if(keys[i].key_sta==0)
							keys[i].key_pro=2;
						else
							keys[i].key_pro=0;
					}
					break;
				
				case 2:
					{
						if(keys[i].key_sta==1)
							{
								keys[i].key_flg=1;
								keys[i].key_pro=0;
							}
						
					}
					break;	
			}
		}
	}
	
	if(htim->Instance==TIM3)
	{
		count++;
		//密码输入正确,LED1点亮5s后熄灭
		//改变PWM的输出频率,占空比
		if(is_correct==1 && count==50)
			{
				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);
				Contro_One_Led(0x01,1);
				htim2.Init.Prescaler = 80-1;
				htim2.Init.Period = 999;
				__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,500);
				duty=50;
				freq=1000;
				HAL_TIM_Base_Start_IT(&htim3);
				HAL_TIM_Base_Stop(&htim3);
			}
			
		//密码输入错误次数到三次以上,LED2在5s内每隔0.1s切换状态
		if(is_correct==0 && error_counts>=3)
		{
			if(count!=50)
			{
				//这里为了避免LED和LCD发生冲突,所以在LED亮灭前进行了处理
				//前面的更新文章里面有提到,需要的话可以去看看
				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);
				led2_sta=led2_sta^1;
				Contro_One_Led(0x02,led2_sta);
			}
			else
			{
				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);
				Contro_One_Led(0x02,1);
				
				//这里在5s之后关闭定时器,以防后面计时错误
				HAL_TIM_Base_Stop(&htim3);
			}
		}
	}
}

3.LCD模块

/**********************LCD模块********************/
// 密码输入界面显示
void Disp_Code_Enter()
{
	sprintf(st,"       PSD          ");
	LCD_DisplayStringLine(Line1,(u8*)st);
	if(code_1==-1)
	{
		sprintf(st,"    B1:@            ");
		LCD_DisplayStringLine(Line3,(u8*)st);
	}
	else
	{
		sprintf(st,"    B1:%d             ",code_1);
		LCD_DisplayStringLine(Line3,(u8*)st);
	}
	
	if(code_2==-1)
	{
		sprintf(st,"    B2:@            ");
		LCD_DisplayStringLine(Line4,(u8*)st);
	}
	else
	{
		sprintf(st,"    B2:%d             ",code_2);
		LCD_DisplayStringLine(Line4,(u8*)st);
	}
	
	if(code_3==-1)
	{
		sprintf(st,"    B3:@            ");
		LCD_DisplayStringLine(Line5,(u8*)st);
	}
	else
	{
		sprintf(st,"    B3:%d             ",code_3);
		LCD_DisplayStringLine(Line5,(u8*)st);
	}
}

// 参数界面显示
void Disp_Para()
{
	
	sprintf(st,"       STA          ");
	LCD_DisplayStringLine(Line1,(u8*)st);
	sprintf(st,"    F:%dHz             ",freq);
	LCD_DisplayStringLine(Line3,(u8*)st);
	sprintf(st,"    D:%d%%           ",duty);
	LCD_DisplayStringLine(Line4,(u8*)st);
	sprintf(st,"                    ");
	LCD_DisplayStringLine(Line5,(u8*)st);
}

//LCD综合使用函数
void Display_lcd(uint8_t menu)
{
		if(menu==0)
		Disp_Code_Enter();
	else
		Disp_Para();
}

4.串口模块

/************************串口模块****************************/
//串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		RXbuff[BufIndex++]=Rxdat;
		HAL_UART_Receive_IT(&huart1, &Rxdat, 1);
	}

}
//串口接收数据处理函数
void GetData_uart()
{		
		//判断是否收到数据
		if(BufIndex<=6)
			return ;
		
		//判断接收到数据是否符合要求
		if(RXbuff[0]-48==code_one && RXbuff[1]-48==code_two && RXbuff[2]-48==code_thr && RXbuff[3]=='-')
		{
			if(RXbuff[4]-48==code_one && RXbuff[5]-48==code_two && RXbuff[6]-48==code_thr)
				return ;
			else
				{
					code_one=RXbuff[4]-48;
					code_two=RXbuff[5]-48;
					code_thr=RXbuff[6]-48;
					BufIndex=0;
					sprintf(TXbuff,"success\r\n");
					HAL_UART_Transmit_IT(&huart1, (u8*)TXbuff, sizeof(TXbuff));
				}
		}
		else
			return ;
}

5.其他函数模块

void Key_Function()
{
	if(keys[0].key_flg==1)
	{
		//对密码第一位进行更新数值
		code_1++;
		if(code_1==10)
			code_1=0;
		
		keys[0].key_flg=0;
	}
	if(keys[1].key_flg==1)
	{
		//对密码第二位进行更新数值
		code_2++;
		if(code_2==10)
			code_2=0;
		
		keys[1].key_flg=0;
	}

	if(keys[2].key_flg==1)
	{
		//对密码第三位进行更新数值
		code_3++;
		if(code_3==10)
			code_3=0;
		
		keys[2].key_flg=0;
	}
	
	if(keys[3].key_flg==1)
	{
		//密码输入正确
		if(code_1==code_one && code_2==code_two && code_3==code_thr)
			{
				is_correct=1;
				error_counts=0;
				menu=1;
				
				//修改pwm输出频率,占空比
				htim2.Init.Prescaler = 40-1;
				htim2.Init.Period = 999;
				__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,100);
				duty=10;
				freq=2000;
				HAL_TIM_Base_Start_IT(&htim3);
				Display_led();
			}
		
		//密码输入错误
		else
		{
			is_correct=0;
			menu=0;
			error_counts++;
			code_1=code_2=code_3=-1;
			Display_led();
		}
		
		keys[3].key_flg=0;
	}
}

main.c中涉及的函数以及定义的变量:

void sys_init()
{
	//lcd初始化
	LCD_Init();
	LCD_Clear(Black);
  LCD_SetTextColor(White);
  LCD_SetBackColor(Black);
	
	//使能PWM输出
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
	
	//打开定时器TIM2
	HAL_TIM_Base_Start_IT(&htim4);
	
	//打开串口接收
	HAL_UART_Receive_IT(&huart1, &Rxdat, 1);
	//初始状态的界面
	Disp_Code_Enter();
	//LED初始化
	Contro_Led(1);
}



void sys_work()
{
	//串口接收处理
	GetData_uart();

	Display_lcd(menu);
	Key_Function();
}
/************************变量定义****************************/
//保存正确密码的变量
uint8_t code_one=1,code_two=2,code_thr=3;

//保存输入的密码
int8_t code_1=-1;
int8_t code_2=-1;
int8_t code_3=-1;

//保存频率,占空比的变量
uint16_t freq=1000;
uint8_t duty=50;

//保存当前显示的界面
//0--密码输入界面		1--参数显示界面
uint8_t menu=0;	

//记录密码输入错误次数
uint8_t error_counts=0;

//记录此次输入密码是否正确
//0---输入错误	1--输入正确
uint8_t is_correct;


//定时器计数
uint16_t count=0;

//LED2的状态
unsigned char led2_sta;


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_TIM3_Init();
  MX_TIM4_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	sys_init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		sys_work();
  }
  /* USER CODE END 3 */
}



总结

好啦,以上就是我对于实现第十三届省赛程序设计题的一些记录,希望可以帮助到看到的你们。

最后还是希望有不对的地方,可以告知一下我,十分感谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值