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

  • GPIO设置
  • 按键检测
    • 1 连续按键检测短按长按
  • 关键代码

1 GPIO设置

????????????????STM8 I/O 口引脚配置表

Px_DDR Px_CR1 Px_CR2 I/O 方式 引脚状态
0 0 0 输入 悬浮输入
0 0 1 输入 上拉输入
0 1 0 输入 中断悬浮输入
0 1 1 输入 中断上拉输入
1 0 0 输出 开漏输出
1 1 0 输出 推挽输出
1 x 1 输出 输出(最快速度为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 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-12 16:04:28

STM8S---独立按键IO口设置及按下事件问题的相关文章

AVR第8课:独立按键

值得注意的是,独立按键的检测原理和消抖处理在51单片机中已经讲过了,这些东西都不会变.只是AVR单片机的IO口操作方式改变了.在AVR中,检测方式是:首先让将和独立按键相连接的IO口设置成输出高电平,接着将他们设置成输入模式,再然后检测这些IO口的值.电路图如下所示. 代码1:检测是哪一个按键被按下.这里不需要用到消抖动处理. #include<iom16v.h> #include<macros.h> #define uint unsigned int #define uchar

51单片机:独立按键与矩阵按键控制数码管

一,独立按键注意一下几点 >按下的时候,电压被拉低,所以IO口要传低电平( 0x0 ) >按下的时候要消除抖动 ( 延时10ms ),在判断,是否还是低电平,再做业务处理 下面这段程序,就是通过一个独立按键连接到p1口,控制静态数码管的 一段 进行亮和灭的切换. #include <reg52.h> sbit key_control = P1^0; sbit led = P0^0; typedef unsigned char u8; typedef unsigned int u16

单片机第7课:独立按键消抖程序

JP3连接P0口,数码管的VCC接+5V电源,JP5的8.1分别接P2.0和P2.1. #include<reg51.h> /* * 功能:独立按键消除抖动程序,按下KEY1,数值加1,按下KEY8,数值减去1 * */ #define uchar unsigned char #define uint unsigned int int num; uchar code table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80,

单片机小白学步系列(二十一) IO口:基本的LED和按键操作

本篇我们先介绍最基础的几个IO口操作.学完本篇,大家要能自己独立完成下面几个实验. 1.点亮LED 2.一个按键控制LED,按下灯亮,释放灯灭 3.两个按键控制一个LED,一个键开灯,一个键关灯 实验一 点亮LED的例子前面入门篇已经讲过了,程序写起来很简单,Keil编写程序并编译生成HEX文件,烧写进单片机的过程,也做了完整详细的介绍. 点亮LED利用了IO口输出操作.简单复习一下,最核心的两句代码是: sbit LED = P1^0; LED = 0; 第一句定义LED为sbit型变量,对应

巧妙的IO口按键扫描方法

在做项目的时候,我们经常要用到比较多的按键,而且IO资源紧张,于是我们就想方设法地在别的模块中节省IO口,好不容易挤出一两个IO口,却发现仍然不够用,实在没办法了就添加一个IC来扫键.一个IC虽然价格不高,但对于大批量生产而且产品利润低的厂家来说,这是一笔不菲的开支!那,我们能不能想到比较好的扫键方法:用最少的IO口,扫最多的键?可以吗?举个例:给出5个IO口,能扫多少键?有人说是2*3=6个,如图一: 对,大部分技术参考书都这么做,我们也经常这样做:用3个IO口作行扫描,2个IO作列检测(为方

cortex_m3_stm32嵌入式学习笔记(二):独立按键实验(IO输入)

上一个也就是第一个实验做的是关于LED的,属于IO口的输出使用,这一节实验是独立按键的使用,即IO 口的输入使用 ministm32 开发板上一共有3个独立按键,分别为 KEY0  KEY1 WK_UP 原理图如下: 注意: KEY0 KEY1 是低电平有效(即它们为低电平时代表按键按下)而 WK_UP 是高电平有效,为什么呢..很明显,这个问题要分析上面的原理图才能知道的,好吧本渣没学过数模电电路也就勉强70多分(半本书..还没学完),就硬着头皮来分析一下吧(对错可不保证啊..QAQ):很明显

STM32F103 PB口用作独立按键

前一段时间由于项目需要画了一个STM32F103的最小系统板,项目中需要很多硬件资源于是我将PB口作为独立按键输入口,板子打样回来后测试其他一切都还不错但在独立按键测试时出现了问题,测试时采用的是扫描方式,按键支持连续喝不连续两种方式,出现以下问题: 1.单次按键时没有任何反应 2.连续模式下PB3口控制下的LED一直闪烁,其他按键触发也不正常. 今天突然想起来解决这个问题,于是百度了许久才发现PB3与JTAG复用,于是关闭JTAG后解决了问题,现在和大家分享下希望对大家有用. 独立按键扫描方式

PIC16单片机设置不同IO口状态对功耗的影响

最近在做PIC单片机的低功耗,于是设置不同IO口状态测试了一下功耗情况,采用串联万用表的方式测量电流,单片机IO口为悬空状态,整个系统无外设驱动,测试采用的是PIC16F690单片机. 思路如下:系统上电后初始化所有的IO,然后进入调用系统函数SLEEP();进入休眠状态. 1. A.B.C端口全部为输入上拉:休眠后耗电500uA左右. 2. A.B.C端口全部为输入下拉:休眠后耗电500uA左右. 3. A.B.C端口全部为输出上拉:休眠后耗电2200uA左右. 4. A.B.C端口全部为输出

STM32系列单片机IO口模式设置

STM32单片机的每组IO口都有4个32位配置寄存器用于配置GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR和GPIOx_PUPDR,2个32位数据寄存器用于配置输入和输出寄存器GPIOx_IDR和GPIOx_ODR,1个32位置位复位寄存器GPIOx_BSRR,1个32位锁定寄存器GPIOx_LCKR和2个32位复用功能选择寄存器GPIOx_AFRH和GPIOx_AFRL. GPIO的输出状态可以配置为推挽或开漏加上上拉或下拉.输出数据既可以来自输出数据寄存器,