冲击国赛争取保研
这是一个控制led的函数
#define uchar unsigned char
void LED_Disp(uchar dsLED)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET);//移位确定LED状态
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
然后lcd部分记住不需要配置cube直接导入就能用 sprintf要引入头文件stdio.h
这部分算是比较麻烦的,涉及单击、双击、长按。
这部分还需要用到定时器,此单片机的定时器如下
struct keys
{
uchar judge_sta;//判断到哪一步
bool key_sta;//按键按下为0
bool single_sta;//确认按键按下为1
};//此为.h文件中定义的结构体
struct keys key[4]={0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++)
{
switch(key[i].judge_sta)
{
case 0://判断按键第一次被按下,相当于消抖
{
if(key[i].key_sta==0)
key[i].judge_sta=1;//前往第二种状态
}
break;
case 1:
{
if(key[i].key_sta==0)//判断按键第二次被按下
{
key[i].judge_sta=2;//前往第三种状态
key[i].single_sta=1;//按键被单击标志,在main函数中用到时需将这个标志位清空
}
else
key[i].judge_sta=0;//回到第一种状态
}
break;
case 2:
{
if(key[i].key_sta==1)//判断按键被松开状态就重新会到1
{
key[i].judge_sta=0;//会到第一种状态
}
}
break;
}
}
}
}
期中包括了按键单击
struct keys
{
uchar judge_sta;//判断到哪一步
uint key_time;//判断按下时间
bool key_sta;//按键按下为0
bool single_sta;//确认按键按下为1
bool long_sta;//长按键
};//同样这里包含了.h文件
struct keys key[4]={0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++)
{
switch(key[i].judge_sta)
{
case 0://判断按键第一次被按下,相当于消抖
{
if(key[i].key_sta==0)
{
key[i].judge_sta=1;//前往第二种状态
key[i].key_time=0;//按键按下时间清零
}
}
break;
case 1:
{
if(key[i].key_sta==0)//判断按键第二次被按下
{
key[i].judge_sta=2;//前往第三种状态
}
else
key[i].judge_sta=0;//回到第一种状态
}
break;
case 2:
{
if(key[i].key_sta==1)//判断按键被松开状态就重新会到1
{
key[i].judge_sta=0;//回到第一种状态
if(key[i].key_time<70)//时间小于700ms就相当于短按键
key[i].single_sta=1;//按键被单击标志,在main函数中用到时需将这个标志位清空
}
else
{
key[i].key_time++;//按键没有松开时间就加
if(key[i].key_time>70)//时间大于700ms就相当于长按键
key[i].long_sta=1;
}
}
break;
}
}
}
}
这部分在csdn上找到的,还没测试过
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3) //判断中断信号是否来自定时器3
{
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); //读按键PB0现在的状态,如果被按下,PB0 = 0;如果没有被按下,PB0 = 1;
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i = 0;i < 4; i++ ) //确认是哪个或哪些按键被按下了
{
switch (key[i].judge_sta)
{
case 0:
{
if(key[i].key_sta==0) key[i].judge_sta = 1; //第一次判断是否按下
}
break;
case 1:
{
if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖
{
if(a == i && key[a].key_time < 70) //小于70,说明上次按下后到这次按下时间间隔小于0.7秒
{
key[i].double_key_flag = 1; //这是一次双击事件
}
else
{
key[i].key_flag = 1;
a = i; //记录这一次是上面按键被按下
}
key[i].judge_sta = 2;
}
else //否则就是抖动,本次不算按键被按下
key[i].judge_sta = 0;
}
break;
case 2:
{
if(key[i].key_sta==1) key[i].judge_sta = 0; //判断是否松手,松手后按键状态重置
key[i].key_time = 0;
}
break;
}
}
key[a].key_time++; //第一次被按下之后,开始计时
}
}
本文章使用limfx的vscode插件快速发布