第十三届蓝桥杯嵌入式省赛真题

目录

题目要求:  

所用到的引脚和外设:

软件设计:

主函数编写:

CubeMX配置:

PWM:​编辑

 USART:串口

PWM使用注意事项:

USART1:串口使用注意事项:

对while循环的两个函数进行分析:

KEY_scanf();函数:

Lcd_Dis();函数:

效果显示:


题目要求:  

c84d3567342d49568d2e3ba2e93a80d7.png

3285d1c98dfc41949a9575ef3a8ad776.png

0f8c8002d38d4154b0dc9b6a03eeff02.png

1ed9cf79f6b8453782bbeaa8947e201e.png

所用到的引脚和外设:

LCD:

串口通信:USART1:PA9、PA10

按键:PB0、PB1、PB2、PA0

PWM波:PA1

LED:PC8~15、PD2

软件设计:

主函数编写:

对LCD和按键经行定时扫描,一系类的函数都在定时扫描中进行。我的编程习惯呐,喜欢先将分模块写出来,然后根据逻辑将模块整合。

#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "lcd.h"

//中断暂存变量
unsigned char rxData;

uint8_t Default_Password[3]={1,2,3};//密码存储地

uint8_t affim_Key4=0;//统计按键次数的相关变量
uint8_t Led2_Fre=0;
_Bool LED2_Swap=0;

void SystemClock_Config(void);


int main(void)
{

  HAL_Init();


  SystemClock_Config();

	LCD_Init();
  MX_GPIO_Init();
  MX_TIM2_Init();
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);

	
  MX_USART1_UART_Init();
	HAL_UART_Receive_IT(&huart1,&rxData,1);
	
	
	mimajiemian();
	
	Led_Control(0x00);
	
  while (1)
  {
		KEY_scanf();
		
		Lcd_Dis();
  }

}

主函数当中就两个函数一个是按键一个是lcd显示,这套题需要注意的外设有PWM和串口。

CubeMX配置:

PWM:

 USART:串口

USART1引脚:PA9、PA10

打开串口中断,配置优先级;

 其余配置请参考我的下边这篇文章:

http://t.csdn.cn/p6tPThttp://t.csdn.cn/p6tPT

PWM使用注意事项:

注意:使用PWM的时候先对定时器进行初始化,

然后开启定时器PWM:HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);。

修改占空比使用:__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,DU);

占空比:Du/Fre         ;

修改频率使用:

		htim3.Init.Period = Fre; 
		HAL_TIM_Base_Init(&htim3);

USART1:串口使用注意事项:

注意:使用串口的时候先进行串口等配置的初始化,

然后如果要中断接收数据的话就需要:HAL_UART_Receive_IT(&huart1,&rxData,1);

打开中断接收,位置在初始化的下一句就行。

然后是中断回调函数的编写:将HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)在usart.c文件中重新调用一下,然后在该函数里边进行数据的接收。

对while循环的两个函数进行分析:

KEY_scanf();函数:

先转跳近函数的主体:

void KEY_scanf(void)
{
	if(uwTick-uwTick_KEY_Last<50) return ;
	uwTick_KEY_Last=uwTick;
	
	Key_N_Val=Key_Val();
	Key_Down=Key_N_Val & (Key_N_Val^Key_Last_Val);
	Key_Up=~Key_N_Val & (Key_N_Val^Key_Last_Val);
	Key_Last_Val=Key_N_Val;
	
	Key_control();
	
	//密码确认和led2闪烁
	mimaquer();
}

这部分代码是对按键进行定时扫描,然后进行一些和按键控制有关的函数里边,

Key_control();//该函数控制着按键1、2、3的加减,控制按键4的确认。

mimaquer();//该函数里边包含密码确认和led2的闪烁

void mimaquer(void)
{
	if(B4==1)//按键4的确认
	{
		B4=0;
		affim_Key4+=1;//输入密码累加计数
		if(B1==Default_Password[0]&&
			 B2==Default_Password[1]&&
	     B3==Default_Password[2])//密码确认
		{
		model=1;//显示模式
		Fre_2000hz_Control();//2000Hz控制
		affim_Key4=0;	     //如果密码正确输入次数累加清零
		}
		B1=10;               //B1显示 @
		B2=10;               //B2显示 @
		B3=10;               //B3显示 @
	}
	if(affim_Key4>=3)        //如果输入次数大于等于3
	{
		Led2_Fre+=1;//用于计时累加的
		if(Led2_Fre%2==0)//闪烁
		{
			LED2_Swap=(_Bool)(1-LED2_Swap);
			if(LED2_Swap==1)
			{
				Led_Control(0x02);
			}
			if(LED2_Swap==0)
			{
				Led_Control(0x00);
			}	
		}
		
		if(Led2_Fre>=90)//5s过后
		{
			Led2_Fre=0;
			affim_Key4=0;
			Led_Control(0x00);
		}
	}
	
}

Lcd_Dis();函数:

void Lcd_Dis(void)
{
	if(uwTick-uwTick_LCD_last<200) return ;
	uwTick_LCD_last=uwTick;
	
	
	if(model==0)//密码输入界面
	{
		mimajiemian();//密码输入界面显示
		
	}
	else//输出界面
	{ 
		Rbt+=1;
		if(Rbt<25) 
		{
			Out_interface();//输出界面显示
			Led_Control(0x01);//led控制
		}
		else
		{
			Rbt=0;
			model=0;
			Fre_1000hz_Control();//返回密码输入界面的频率
			Led_Control(0x00);
		}
		
	}
	

密码输入是从@开始到0~9的循环。我在这里规定了一个数组在第十位显示@,而按键按下的时候按键加一在数组里遍历。然后当遍历到第十位的时候等于0从头开始遍历。

char Cipher[11]={'0','1','2','3','4','5','6','7','8','9','@'};
void mimajiemian(void)
{
	
	LCD_SetTextColor(White);
	LCD_SetBackColor(Black);
	
	sprintf((char *)Lcd_dis,"                    ");
	LCD_DisplayStringLine(Line0,Lcd_dis);
	
	sprintf((char *)Lcd_dis,"       PSD          ");
	LCD_DisplayStringLine(Line1,Lcd_dis);

	sprintf((char *)Lcd_dis,"                    ");
	LCD_DisplayStringLine(Line2,Lcd_dis);
	
	sprintf((char *)Lcd_dis,"    B1:%c            ",Cipher[B1]);//注意
	LCD_DisplayStringLine(Line3,Lcd_dis);
	
	sprintf((char *)Lcd_dis,"    B2:%c            ", Cipher[B2]);
	LCD_DisplayStringLine(Line4,Lcd_dis);
	
	sprintf((char *)Lcd_dis,"    B3:%c            ",Cipher[B3]);
	LCD_DisplayStringLine(Line5,Lcd_dis);
	
	sprintf((char *)Lcd_dis,"                    ");
	LCD_DisplayStringLine(Line6,Lcd_dis);
	LCD_DisplayStringLine(Line7,Lcd_dis);
	LCD_DisplayStringLine(Line8,Lcd_dis);
	LCD_DisplayStringLine(Line9,Lcd_dis);

}

效果显示:

视频例程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值