stm32f103——按键检测(轮询方式)

我们下面来讲一讲,GPIO在输入模式下检测按键是否被按下:

stm32f103——按键检测(轮询方式)_第1张图片

首先我们来看看按键按下时,K1处电压的变化情况是什么:

stm32f103——按键检测(轮询方式)_第2张图片

        我们看到,按键按下时,K1处的电压并不是立马就下降为0v,因为按键有机械的弹性形变,导致按键被按下时,会发生抖动。我们用GPIO来读取K1处的电压是否为0,如果为低电平,则表示按键被按下。被按下后,如果为高电平,则表示按键被抬起来了。

        但是,在这个按键抖动的过程中,电平有上升沿也有下降沿,电压有高电平也有低电平。所以,在这一段抖动的部分的时间段内,如果我们用GPIO去判断,由于电平忽高忽低,我们的程序就会识别出来,按键在被按下后马上就抬起来了。但是,实际上并不是这样。所以,我们需要跳过按键被按下时的前50ms,在K1处电压稳定时,再来对K1处电压进行判断。这个过程我们称为按键"消抖"。

读取PA0的按键值,编程步骤:
        1,打开时钟----GPIOA 
        2,初始化GPIOA
            ---GPIO_Pin_0
            ---上拉输入
        3,判断PA0是否为低电平
        4,如果为低电平,延时50ms,消除抖动
        5,再次判断PA0是否为低电平---结合第3步,判断是否为按键按下过程
        6,如果是为低电平,等待按键抬起----耗尽按键按下的时间
        7,确认按键按下,执行按键按下相应的操作

编程:

//按键按下后,LED灯的状态反转

void KEY_Config(void)
{
     GPIO_InitTypeDef  GPIO_InitStruct;
    // 1,打开时钟----GPIOA 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    // 2,初始化GPIOA
    GPIO_InitStruct.GPIO_Pin  =GPIO_Pin_0;                   //注意:在输入模式下,不用设置I/O口的速度
    GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IPU;        //按键检测时,选择上拉输入模式
    GPIO_Init( GPIOA,&GPIO_InitStruct);
    
}

uint8_t KEY_isPress(void)
{
    uint8_t ret=0;
    // 3,判断PA0是否为低电平
    if(0==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)){
        // 4,如果为低电平,延时50ms,消除抖动
        Systick_NmsDelay(50);
        // 5,再次判断PA0是否为低电平---结合第3步,判断是否为按键按下过程    
        if(0==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)){
            // 6,如果是为低电平,等待按键抬起----耗尽按键按下的时间
            while(0==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
                ;
            // 7,确认按键按下,执行按键按下相应的操作
            ret=1;
        }
    }
    return ret;
}

uint8_t ledflag=0;

int main(void)
{
    LED_Config();    
    RCC_ConfigTo72M();//将系统时钟配置成72MHZ 
    Systick_Config(72);
    KEY_Config();


    while(1){
        if(0==ledflag){
            LED_CTRL(LEDR,LED_CLOSE);
        }else{
            LED_CTRL(LEDR,LED_OPEN);
        }
        if( 1==KEY_isPress() ){
            ledflag=~ledflag;
        }
    }
}

这里提出一个问题:

stm32f103——按键检测(轮询方式)_第3张图片

         请问红框部分可以写成1==ledflag吗?反正只要按键按下,就会执行 ledflag=~ledflag,ledflag一开始为0,"~"(反)一下不就是1了吗?1的时候LED灯关闭。

        不行,因为ledflag虽然一开始是0,但是uint8_t 类型,uint8_t类型的0实际上是0000 0000(即0x00),所以~(0000 0000) = 1111 1111 (即:0xff)其不等于1,所以,此时LED灯不会关闭。

你可能感兴趣的:(stm32,arm,嵌入式硬件)