蓝桥杯嵌入式第12届模拟赛

蓝桥杯嵌入式第12届模拟赛

蓝桥杯嵌入式第12届模拟赛

 

按键模块

使用的是状态机消抖

#define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)

#define key_input ((KB1)|(KB2<<1)|(KB3<<2)|(KB4<<3)|0XF0)

#define KB1_PRESS 1
#define KB2_PRESS 2
#define KB3_PRESS 3
#define KB4_PRESS 4	 


uint8_t key_read(void)
{
	static int key_state = 0;
	unsigned char key_return = 0;
	
	switch(key_state)
	{
		case 0:
			if(key_input != 0xff) key_state = 1;
		break;
		case 1:
			if(key_input == 0xff)key_state = 0;
			else
			{
				switch(key_input)
				{
					case 0xfe:key_return = KB1_PRESS;break;
					case 0xfd:key_return = KB2_PRESS;break;
					case 0xfb:key_return = KB3_PRESS;break;
					case 0xf7:key_return = KB4_PRESS;break;
				}
				key_state = 2;
			}
		break;
		case 2:
			if(key_input == 0xff) key_state = 0;
		break;
	}
	return key_return;
}

主函数按键处理代码

if(key_flag)
		{
			key_flag=0;
			key_val = key_read();
			if(key_val == KB1_PRESS)
			{
				mode_flag++;
				if(mode_flag == 2) 
				{
					mode_flag = 0;
					if(Volmax < (Volmin + 5))
					{
						Volmax = temp_Volmax;
						Volmin = temp_Volmin;
					}
				}
				if(mode_flag == 1)
				{
					temp_Volmax = Volmax;
					temp_Volmin = Volmin;
				}
			}
			if(key_val == KB2_PRESS)
			{
				if(mode_flag == 1)
				{
					Volmax -=1;
					if(Volmax == -1) Volmax = 33;
				}
			}
			if(key_val == KB3_PRESS)
			{
				if(mode_flag == 1)
				{
					Volmin +=1;;
					if(Volmin == 34) Volmin = 0;
				}
			}
		}

由于float的问题,所以不能直接判断 Vmax==0.0f以及Vmin == 3.3f,所以这里选用了使用整型数,方便判断。

PWM输出模块

这里是通过PA0输出PWM波。将TIM2的CHANNEL2设置为PWM输出模式。

蓝桥杯嵌入式第12届模拟赛

void PWM_OUTPUT(unsigned char state)
{
	switch(state)
	{
		case 1:
			TIM2->ARR=9999;
			//TIM2->CCR2=5000;
			__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,5000);
			TIM2->EGR=TIM_EGR_UG;
			break;
		case 2:
			TIM2->ARR=999;
			//TIM2->CCR2=500;
			__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);
			TIM2->EGR=TIM_EGR_UG;
			break;
		case 3:
			TIM2->ARR=99;
			//TIM2->CCR2=50;
			__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);
			TIM2->EGR=TIM_EGR_UG;
			break;
			
	}
}

注释掉的部分和_HAL_TIM_SET_COMPARE();函数是一个效果。

定时器模块

使用TIM3作为通用定时器,调用回执函数,在定时器中断内设置adc读取间隔实践以及按键时间。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM3)
	{
		static int key_count = 0, adc_count = 0;
		key_count++;
		if(key_count==10)
		{
			key_count=0;
			key_flag=1;
		}
		if(Adc_flag == 0)
		{
			adc_count++;
			if(adc_count == 50)
			{
				adc_count = 0;
				adc_flag=1;
			}
		}
	}
}

LCD显示模块

通过mode_flag的不同值作为数据页面与设置页面的判断。

if(mode_flag == 0)
		{
			LCD_DisplayStringLine(Line1,data_str);
			sprintf((char *)show_str,"V:%.2fV             ",adc_ana_val);
			LCD_DisplayStringLine(Line3,show_str);
			sprintf((char *)show_str,"A:%d                ",Vol_State);
			LCD_DisplayStringLine(Line4,show_str);
		}
		else
		{
			LCD_DisplayStringLine(Line1,para_str);
			sprintf((char *)show_str,"Vmax:%d.%dV         ",Volmax/10,Volmax%10);
			LCD_DisplayStringLine(Line3,show_str);
			sprintf((char *)show_str,"Vmin:%d.%dV         ",Volmin/10,Volmin%10);
			LCD_DisplayStringLine(Line4,show_str);
		}

关于LED与LCD冲突的内容,可以看一下这篇文章。

void LEDx_ON(unsigned char led_pin)
{
	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, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7<<(led_pin),GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

https://blog.csdn.net/m0_46179894/article/details/108902700?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161659177816780261918478%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161659177816780261918478&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-1-108902700.first_rank_v2_pc_rank_v29_10&utm_term=LED%E4%B8%8ELCD%E5%86%B2%E7%AA%81

上一篇:沁恒微USB蓝牙单片机CH573F初步熟悉


下一篇:实验二 、中断实验