×
嵌入式 > 技术百科 > 详情

STM8S---独立按键IO口设置及按下事件问题

发布时间:2020-06-18 发布时间:
|

1 GPIO设置

                STM8 I/O 口引脚配置表

Px_DDRPx_CR1Px_CR2I/O 方式引脚状态
000输入悬浮输入
001输入上拉输入
010输入中断悬浮输入
011输入中断上拉输入
100输出开漏输出
110输出推挽输出
1x1输出输出(最快速度为10MHZ)

对STM8S的IO配置,我们只需要操作五个寄存器就行了:

  • 输出数据寄存器 (ODR)

  • 输入数据寄存器 (IDR)

  • 数据方向寄存器 (DDR)

  • 控制寄存器1(CR1)

  • 控制寄存器2(CR2)

2 按键检测

  在做独立按键检测的时候,设置成上拉输入不能实现功能,设置成中断悬浮输入就可以了。 
  两次短按键之间的时间间隔大约在300ms~600ms之间。一次短按键按下的时间大约在14ms~26ms之间;

2.1 连续按键检测(短按+长按)

定时器TIM1 + 按键 = 连续按键检测(短按键+长按键) 
两个标记:

  • 短按+长按—flag0

  • 短按后时间在规定范围之内—flag1

如果两个标记都满足,则开/关电源;每次按键都启动按键计时;

当两次按键的时间间隔在300ms~600ms之间的时候,怎么得到第一次(短按)和第二次(长按)按键之间的时间呢? 
  如果判断了是短按,则开启计时,同时将第一次短按flag置一,超过600ms停止计时并清零,等待第二次的按键;有了第二次的按键之后,在短按置一flag条件中中断计时,判断是否在规定范围之内的时间间隔,是则将flag1置一;并接下来判断该按键是长按还是短按,如果是长按,则将flag0置一,满足flag0、flag1均置一,则是连续按键。

3 关键代码


/*

return = 

    0   :   No Key Press

    1   :   Single Key Press

    2   :   将长按作为一次单独按键,并执行Single Key Press功能   

    3   :   Double Key Press

*/

unsigned int Key_Scan(void)

{

    unsigned int count = 0;


    if(0 == KEY)

    {

        Delay(2);

        if(0 == KEY)

        {

            if(1 == keytimesFlag)

            {

                afterOnceShortPressFlag = 0;

                if((afterOnceShortPressCount <=30) 

                    && (afterOnceShortPressCount > 15))

                {

                    isSetTimeFlag = 1;

                }

                else isSetTimeFlag = 0;

            }

            keyFlag = 1;

            while(!KEY);

            keyFlag = 0;

            count = keyCount;

            keyCount = 0;

        }

        else

        {

            count = 0;

        }

    }


    if(count >= 200)

    {

        if(1 == isSetTimeFlag)

        {

            isSetTimeFlag = 0;

            keytimesFlag = 0;

            return 3;

        }

        else 

        {

            keytimesFlag = 0;

            return 2;           

        }

    }

    else if(count >= 4)

    {

        afterOnceShortPressFlag = 1;

        afterOnceShortPressCount = 0;

        keytimesFlag = 1;

        return 1;

    }

    else return 0;

}


在定时周期为10ms的定时器中断函数里:

@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)

{   

    TIM1_SR1 &=~(0x01);    

    if(1 == keyFlag)

    {

        ++keyCount;

    }

    else ;

    if(1 == afterOnceShortPressFlag)

    {

        ++afterOnceShortPressCount;

        if(afterOnceShortPressCount > 80)

        {

            afterOnceShortPressFlag = 0;

            afterOnceShortPressCount = 0;

            keytimesFlag = 0;

        }

    }

    else ;

}



 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil5(MDK5)在调试(debug)过程中遇到的问题