蓝桥杯训练

uwTick

滴答定时器 可以获取单片机当前时间

led进阶

//进阶1
    u8 led_pro=0x08;//当前led4一直长亮
	led_pro=(led_pro&0xfe)|0x01;//使led1点亮
	led_pro=(led_pro&0xfd)|0x00;//使led2熄灭
	LED_Disp(led_pro);
	HAL_Delay(100);
	led_pro=(led_pro&0xfd)|0x02;//使led2点亮
	led_pro=(led_pro&0xfe)|0x00;//使led2熄灭
	LED_Disp(led_pro);
	HAL_Delay(100);
//进阶2
//num表示需要操作的灯,sta表示亮灭状态
//led_sta表示当前灯的状态
void led_chg(u8 num,u8 sta)
{
	u8 pos=0x01<<(num-1);
	LED_Disp((led_sta&~pos)|(pos*sta));
}

按键进阶短按键

struct keys key[5]={0,0};

u8 key_read(void)
{
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
	else return 0;
}
void key_serv(void)
{
	u8 key_sta=key_read();
	if(key_sta!=0)
	{
		key[key_sta].age++;
		if(key[key_sta].age>1)
		key[key_sta].flag=1;
	}
	else
	{
		for(int i=0;i<5;i++)
		{
			key[key_sta].age=0;
		}
	}
	
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)
	{
		key_serv();
	}
}

按键进阶长按1

struct keys key[5]={0,0};

u8 key_read(void)//按键读取
{
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;//按键1被按下
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;//按键2被按下
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;//按键3被按下
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;//按键4被按下 
	else return 0;//未有按键按下
}
void key_serv(void)//按键标志位读取
{
	u8 key_sta=key_read();//读取
	if(key_sta!=0)//如果按键被按下 
	{
		key[key_sta].age++;//10ms内按下一次加1
		if(key[key_sta].age>1)key[key_sta].press=1;//表示按下的状态
		
	}
	else//按键松开可以将标志位清空
	{
		for(int i=0;i<5;i++)
		{
			if(key[i].press==1&&key[i].long_flag==0)
				key[i].short_flag=1;//表示按键被按下且不是长按键状态
			key[i].age=0;
			key[i].press=0;
			key[i].long_flag=0;
		}
	}
	if(key[key_sta].age>=70)//标志位超过700ms就可以表示按键真正被按下 
			key[key_sta].long_flag=1;//按键被按下标志,此按键需在按键使用的时不需清空
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)
	{
		key_serv();//需在定时器中断中使用
	}
}

按键进阶长按2

struct keys key[5]={0,0};

u8 key_read(void)//按键读取
{
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;//按键1被按下
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;//按键2被按下
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;//按键3被按下
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;//按键4被按下 
	else return 0;//未有按键按下
}
void key_serv(void)//按键标志位读取
{
	u8 key_sta=key_read();//读取
	if(key_sta!=0)//如果按键被按下 
	{
		key[key_sta].age++;//10ms内按下一次加1
		if(key[key_sta].age>1)key[key_sta].press=1;//表示按下的状态
		
	}
	else//按键松开可以将标志位清空
	{
		for(int i=0;i<5;i++)
		{
            if(key[i].age>=70)//标志位超过700ms就可以表示按键真正被按下 
			    key[i].long_flag=1;//按键被按下标志,此按键需在按键使用的时不需清空
			if(key[i].press==1&&key[i].long_flag==0)
				key[i].short_flag=1;//表示按键被按下且不是长按键状态
			key[i].age=0;
			key[i].press=0;
		}
	}
	
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)
	{
		key_serv();//需在定时器中断中使用
	}
}

按键进阶双击

void key_serv(void)//按键标志位读取
{
	u8 key_sta=key_read();//读取
	if(key_sta!=0)//如果按键被按下 
	{
		key[key_sta].age++;//10ms内按下一次加1
		if(key[key_sta].age>1)key[key_sta].press=1;//表示按下的状态
		
	}
	else//按键松开可以将标志位清空
	{
		for(int i=0;i<5;i++)
		{
			if(key[i].age>=70)//标志位超过700ms就可以表示按键真正被按下 
			    key[i].long_flag=1;//按键被按下标志,
			if(key[i].double_ageEN==1&&key[i].press==1)//表示按键双击
			{
				key[i].double_flag=1;
				key[i].press=0;
				key[i].double_ageEN=0;
			}
			if(key[i].press==1&&key[i].long_flag==0)//表示按键按下并第一次松开
				key[i].double_ageEN=1;
			if(key[i].double_ageEN==1)//按键松开并计时
				key[i].double_age++;
			if(key[i].double_ageEN==1&&key[i].double_age>20)//按键单击,超过200ms按键没有被再次按下表示单击
			{
				key[i].short_flag=1;
				key[i].double_age=0;
				key[i].double_ageEN=0;
			}
			key[i].age=0;
			key[i].press=0;
		}
	}
}

本文章使用limfx的vscode插件快速发布