STM32
直播中

苹果派派

11年用户 629经验值
私信 关注
[问答]

如何去实现STM32F103按键控制的设计呢

如何去实现STM32F103按键控制的设计呢?主要有哪几个步骤呢?

回帖(1)

王聪

2021-11-25 15:22:49
STM32F103按键控制
按键双击,长按有效,单击取消
在学习过程中需要完成稍微复杂一点的功能,按键又不想设计太多(主要节省成本)

在工程中主要有以下几个步骤
一、按键初始化
1、初始化按键IO引脚,这里配置的是上拉输入
2、编写单个按键检测程序(加延时消抖)
3、宏定义每个按键的状态值Key_State
4、编写判断是否有按键按下函数,并确定此按键的状态值
5、编写按键功能函数
二、定时器初始化
1、选择通用定时器
2、配置定时器时间,并开启中断
3、编写中断服务函数

//宏定义每个按键的状态值Key_State
#define KEY1_STATE_VALUE        (0x0001)
#define KEY2_STATE_VALUE        (0x0002)
#define KEY3_STATE_VALUE        (0x0004)
#define KEY4_STATE_VALUE        (0x0008)

#define KEY5_STATE_VALUE        (0x0010)
#define KEY6_STATE_VALUE        (0x0020)
#define KEY7_STATE_VALUE        (0x0040)
#define KEY8_STATE_VALUE        (0x0080)

#define KEY9_STATE_VALUE        (0x0100)
#define KEY10_STATE_VALUE        (0x0200)
#define KEY11_STATE_VALUE        (0x0400)
#define KEY12_STATE_VALUE        (0x0800)

//按键延时超时值
#define Key_Two_Click_Time                200 //200以内双击有效输出
#define Key_Long_Click_Time                300 //长按300及以上有效输出


uint16_t Key_State = 0;                 //按键状态值

uint8_t Key_Value = 0;                        //按键按下去的值
uint8_t Old_Key_Value = 0;                //上一次按键按下去的值

uint8_t Key_Ture_Value = 0;                //最终输出的值
uint8_t Old_Key_Ture_Value = 0;        //上一次最终输出的值

uint8_t Key_Down_Count_Flag = 0;//按键按下次数的值,用于判断是单击还是双击

uint8_t Key_Down_Flag = 0;                //按键按下标志位,防止一直按着导致按键次数一直增加

uint16_t Key_Click_Time = 0;        //按键次数为1时开始计时,其他状态为0



void Key_Init(void) //初始化12个按键引脚
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
               
        GPIO_InitStructure.GPIO_Pin = KYE10_GPIO_PIN|
                                                                  KYE8_GPIO_PIN|
                                                                  KYE7_GPIO_PIN|
                                                                  KYE6_GPIO_PIN|
                                                                  KYE5_GPIO_PIN|
                                                                  KYE4_GPIO_PIN|
                                                                  KYE3_GPIO_PIN|
                                                                  KYE1_GPIO_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);       
       
        GPIO_InitStructure.GPIO_Pin = KYE2_GPIO_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = KYE9_GPIO_PIN|
                                                                                                                                KYE11_GPIO_PIN|
                                                                                                                                KYE12_GPIO_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOC,&GPIO_InitStructure);       
}

/*
* 描述:  返回key1控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key1_State(void)
{
        if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}

/*
* 描述:  返回key2控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key2_State(void)
{
        if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}

/*
* 描述:  返回key3控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key3_State(void)
{
        if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}

/*
* 描述:  返回key4控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key4_State(void)
{
        if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}

/*
* 描述:  返回key5控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key5_State(void)
{
        if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
* 描述:  返回key6控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key6_State(void)
{
        if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
* 描述:  返回key7控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key7_State(void)
{
        if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}

/*
* 描述:  返回key8控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key8_State(void)
{
        if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}


/*
* 描述:  返回key9控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key9_State(void)
{
        if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
* 描述:  返回key10控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key10_State(void)
{
        if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
* 描述:  返回key11控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key11_State(void)
{
        if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
* 描述:  返回key12控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key12_State(void)
{
        if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
        {
                Delay_Ms(10);
                if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
                {
                        return 0;
                }       
        }
        return 1;
}
/*
*描述:                判断只有一个按键按下
*参数:                无
*返回值:        1:有按键按下,0:无按键按下
*/
uint8_t Key_Down_Num(void)
{
        if(0 == Get_Key1_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key1_State())
                {
                        Key_State |= KEY1_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY1_STATE_VALUE;
        }

///
        if(0 == Get_Key2_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key2_State())
                {
                        Key_State |= KEY2_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY2_STATE_VALUE;
        }

///
        if(0 == Get_Key3_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key3_State())
                {
                        Key_State |= KEY3_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY3_STATE_VALUE;
        }

///
        if(0 == Get_Key4_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key4_State())
                {
                        Key_State |= KEY4_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY4_STATE_VALUE;
        }

///
        if(0 == Get_Key5_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key5_State())
                {
                        Key_State |= KEY5_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY5_STATE_VALUE;
        }

///
        if(0 == Get_Key6_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key6_State())
                {
                        Key_State |= KEY6_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY6_STATE_VALUE;
        }

///
        if(0 == Get_Key7_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key7_State())
                {
                        Key_State |= KEY7_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY7_STATE_VALUE;
        }

///
        if(0 == Get_Key8_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key8_State())
                {
                        Key_State |= KEY8_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY8_STATE_VALUE;
        }

///
        if(0 == Get_Key9_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key9_State())
                {
                        Key_State |= KEY9_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY9_STATE_VALUE;
        }

///
        if(0 == Get_Key10_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key10_State())
                {
                        Key_State |= KEY10_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY10_STATE_VALUE;
        }

///
        if(0 == Get_Key11_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key11_State())
                {
                        Key_State |= KEY11_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY11_STATE_VALUE;
        }       
       
///
        if(0 == Get_Key12_State())
        {
                Delay_Ms(10);
                if(0 == Get_Key12_State())
                {
                        Key_State |= KEY12_STATE_VALUE;
                }
        }
        else
        {
                Key_State &= ~KEY12_STATE_VALUE;
        }       
///       
        Key_State &= 0x0fff;
        if(Key_State != 0)
        {
                return 1;
        }
        return 0;       
}

/*
*描述:                按键检测
*参数:                无
*返回值:        无
*/
void Key_Scanf(void)
{
        if(1 == Key_Down_Num())//判断是否有按键按下
        {
                Old_Key_Value = Key_Value; //每一次按下记录上一次按键的值
                switch(Key_State) //判断按键状态值
                {
                        case KEY1_STATE_VALUE:Key_Value = 1;break;
                        case KEY2_STATE_VALUE:Key_Value = 2;break;
                        case KEY3_STATE_VALUE:Key_Value = 3;break;
                        case KEY4_STATE_VALUE:Key_Value = 4;break;
                        case KEY5_STATE_VALUE:Key_Value = 5;break;
                        case KEY6_STATE_VALUE:Key_Value = 6;break;
                        case KEY7_STATE_VALUE:Key_Value = 7;break;
                        case KEY8_STATE_VALUE:Key_Value = 8;break;                                               
                        case KEY9_STATE_VALUE:Key_Value = 9;break;               
                        case KEY10_STATE_VALUE:Key_Value = 10;break;
                        case KEY11_STATE_VALUE:Key_Value = 11;break;
                        case KEY12_STATE_VALUE:Key_Value = 12;break;                       
                        default:Key_Value = 0;break;                       
                }               
                if(Key_Down_Flag == 1)
                {
                        Key_Down_Count_Flag++; //记录按键按下去的次数                       
                }
                Key_Down_Flag = 0;               
        }
        else
        {
                Key_Down_Flag = 1;
        }
       
}

/*
*描述:判断是否是有效键值
*参数:无
*返回值:无
*/
void GetKey_True_Touch(void)
{
        if(Key_Down_Count_Flag == 1) //按下1次
        {
                if(Key_Down_Flag == 0) //按键按下
                {
                        //定时器超过长按规定时间
                        if(Key_Click_Time >= Key_Long_Click_Time)
                        {
                                Key_Ture_Value = Key_Value;
                        }
                        else
                        {
                                Key_Ture_Value = 0;
                        }                       
                }
                else        ///按键松开
                {
                        //判断定时器时间是否超过规定时间
                        //如果超过规定时间,清零变量
                        if(Key_Click_Time > Key_Two_Click_Time)
                        {
                                Key_Ture_Value = 0;                                //输出值清零                               
                                Key_Click_Time = 0;                                //定时器时间清零
                                Key_Down_Count_Flag = 0;        //按键次数清零
                        }
                }       
        }
        else if(Key_Down_Count_Flag == 2)//按下2次
        {
                //如果两次按键值相等,说明双击的是同一个按键
                //如果两次按键值不相等,输出0;
                if(Old_Key_Value == Key_Value)
                {
                        Key_Ture_Value = Key_Value;
                }
                else
                {
                        Key_Ture_Value = 0;                                //输出值清零       
                }
                Key_Click_Time = 0;                                //定时器时间清零
                Key_Down_Count_Flag = 0;        //按键次数清零
                while(Key_Down_Num());    //等待按键松开
        }
       
}

//定时器配置//

void TIM2_Init(void)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;       
        NVIC_InitTypeDef                                 NVIC_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
       
       
        //配置周期为5ms
        TIM_TimeBaseInitStructure.TIM_Period = 4999;
        TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
        TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
       
        TIM_ARRPreloadConfig(TIM2,ENABLE);//在ARR上启用或禁用TIMx外设预加载寄存器。
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        TIM_Cmd(TIM2,ENABLE);
       
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
       
        NVIC_Init(&NVIC_InitStructure);
}       
//中断服务函数
void TIM2_IRQHandler(void)
{
        while(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update))
        {
                //按键单击,双击,长按监测
                if(Key_Down_Count_Flag == 1)
                {
                        Key_Click_Time++;
                        if(Key_Click_Time > Key_Long_Click_Time)
                        {
                                Key_Click_Time = Key_Long_Click_Time;
                        }                       
                }
                else
                {
                                Key_Click_Time = 0;
                }
                TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
        }       
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分