历史上的今天
返回首页

历史上的今天

今天是:2024年12月27日(星期五)

正在发生

2019年12月27日 | STM8学习笔记---按键KEY

2019-12-27 来源:eefocus

用按键来控制LED灯的亮灭。按键接在PC4口,LED灯接在PD4口,LED灯由IO口高低电平控制亮灭,所以对于LED来说,IO口为输出口。按键是由外部电路来决定高低电平,假设按键未按下时默认为高电平,按键按下时为低电平。对于KEY来说,IO口为输入口,IO口要读取外部电平状态,根据电平状态来判断按键是否按下。


首先要设置IO口的状态。

在这里插入图片描述

端口方向寄存器, LED口要设置为输出模式, 所以PD4设置为1。按键KEY口要设置为输入模式,所以PC4设置为0。

在这里插入图片描述

端口控制寄存器,LED口需要输出高低电平,所以PD4口设置为1,推挽输出。

按键KEY口要读取外部电平,按键未按下时为高电平,按键按下时为低电平。所以PC4口设置为1,带上拉电阻输入,将IO口电平默认状态用上拉电阻拉为高电平。

在这里插入图片描述

LED口为输出模式,设置PD4口为1,输出最大速度10MHz。

按键KEY口为输出模式,设置PC4口为0,禁止外部中断。判断按键用查询方式,不需要开中断。

LED口初始化代码为:


#include "led.h"


void LED_GPIO_Init( void )

{

    PD_DDR |= ( 1 << 4 );        //PD4 输出 led

    PD_CR1 |= ( 1 << 4 );        //PD4 推挽输出

    PD_CR2 |= ( 1 << 4 );

}


控制LED亮灭要通过位操作来实现,所以要在头文件中对LED进行位定义。


#ifndef __LED_H

#define __LED_H

#include "iostm8s103F3.h"

#define  LED  PD_ODR_ODR4 //位定义 PD4定义为输出 LED

void LED_GPIO_Init(void);

#endif


用 LED 来表示PD4口的输出状态寄存器,这样在操作LED的时候就相当于操作PD口的输出寄存器 ODR4位。

在这里插入图片描述

按键口KEY的初始化代码为:


#include "key.h"


void KEY_GPIO_Init( void )

{

    PC_DDR &= ~( 1 << 4 );        //PC4 输入

    PC_CR1 |= ( 1 << 4 );         //带上拉电阻输入

    PC_CR2 &= ~( 1 << 4 );        //禁止外部中断

}


按键判断也要通过位操作实现,要在头文件中位定义。


#ifndef __KEY_H

#define __KEY_H

#include "iostm8s103F3.h"

#define  KEY  PC_IDR_IDR4 //位定义 PC4 定义为按键输入  

void KEY_GPIO_Init( void );

#endif


用 KEY 来表示PC4口的输入状态寄存器,这样在操作KEY的时候就相当于操作PC口的输入寄存器 IDR4位。

在这里插入图片描述

LED和按键KEY的初始化已经完成,下来开始写主函数。主函数要实现的功能主要是按键按下一次LED灯亮,按键再按下一次LED灯灭。也就是说按键 按下一次 LED灯的状态取反一次。主程序代码如下:


 while( 1 )

    {

        if( KEY == 0 )

        {

                LED = !LED;

        }

    }


按键按下为低电平,所以在循环中判断KEY的状态,若KEY为0,说明按键按下,此时将LED状态取反。将程序烧入单片机中测试,在按键的过程中发现有时候按键按下后LED灯的亮灭没发生变化,感觉是按键失灵了。用示波器看看按键IO口的波形。

在这里插入图片描述

通过波形可以看到,按键按下后,确实为低电平,但是在按键真正按下前出现了一个向下的脉冲。为什么会出现这个向下的脉冲呢?因为一般的按键内部结构是两个金属片,按键按下时两个金属片挨在一起形成通路,按键弹起时两个金属片分开形成断路。人用手指按键时,在按下的一瞬间手指可能会抖动,导致两个金属片短暂的接触后,又瞬间断开。然后手指将按键真正按下后,两个金属片稳定的接触在一起,形成一个稳定的低电平。


程序中按键失灵的感觉就是这个短暂的向下脉冲造成的。当按键时手指发生抖动,在IO口出现了一个瞬间的低电平,这时候如果程序刚好捕捉到了这个低电平,就会被当做一个按键事件处理,这时将状态取反。当按键真正被按下时,又出现一个低电平,这时程序认为是新的按键事件发生,又对LED状态取反一次。相当于真正的按键只按下去一次,但是程序中捕捉到了两次按键。也就是说按键真正的按下了一次,但是程序中对灯的状态取反了两次。相当于LED状态没变。由于按键按下时间非常短,LED灯状态在中间发生变化的时间太短,人眼观察不到,所以感觉LED状态没变。那么如何避免在按键时出现抖动的情况呢,一种方法时在按键的时候一瞬间按下去,不要出现抖动情况。一种是硬件上换更好的按键,从硬件上避免抖动出现。但是这两种方法都不太现实,能不能用软件方法解决这个问题呢?


通过观察上面按键的波形可以发现,按键按下后低电平会持续很长时间,在程序判断的时候可以通过两次低电平来确认按键按下,这两次低电平判断中间要等待一段时间。比如说判断到一次低电平后,延时一段时间,在判断一次,若此时还是低电平说明是按键正真的按下了。于是程序修改为:


 while( 1 )

    {

        if( KEY == 0 )

        {

            delay_ms( 10 );

            if( KEY == 0 )

            {

                LED = !LED;

            }

        }

    }


按键按下后,延时10ms,然后再判断按键状态,若按键状态没变,说明按键是真的被按下。此时在对LED灯的状态取反。将将程序烧到单片机中测试,发现增加延时后,按键的识别率大大的增强了。

修改后的主程序为:


#include "iostm8s103F3.h"

#include "led.h"

#include "key.h"

void SysClkInit( void )

{

    CLK_SWR = 0xe1;       //HSI为主时钟源  16MHz CPU时钟频率

    CLK_CKDIVR = 0x00;    //CPU时钟0分频,系统时钟0分频

}

void delay_ms( unsigned int ms )

{

    unsigned int  i, j;

    while( ms != 0 )

    {

        for( i = 0; i < 61; i++ )

            for( j = 0; j < 50; j++ );

        ms--;

    }

}

void main( void )

{

    SysClkInit();                         //时钟初始化

    __asm( "sim" );                       //禁止中断

    LED_GPIO_Init();                      //LED 初始化

    KEY_GPIO_Init();                      //KEY初始化

    __asm( "rim" );                       //开启中断

    LED = 0;

    while( 1 )

    {

        if( KEY == 0 )

        {

            delay_ms( 10 );

            if( KEY == 0 )

            {

                LED = !LED;

            }

        }

    }

}


如果实际测试中按键还会失灵,根据实际情况可以增加或者减小两次按键判断中间的延时。


当然除了软件上增加延时外,也可以给按键口增加一个滤波电容,通过电容将按键时的小毛刺滤掉。

推荐阅读

史海拾趣

Dytran Instruments Inc公司的发展小趣事

2022年5月,英国思百吉集团(Spectris)以5.4亿美元的价格收购了Dytran。这次收购是思百吉集团进一步扩大其在传感器领域的布局的重要举措。作为思百吉集团旗下的子公司,Dytran将继续保持其独立性和品牌特色,同时借助思百吉的全球资源和市场渠道,加速其业务发展和市场拓展。

在被收购后,Dytran与思百吉旗下的其他品牌进行了业务整合。通过共享研发资源、优化供应链、拓展销售渠道等方式,Dytran实现了与思百吉旗下品牌的协同发展。这不仅提高了公司的运营效率和市场竞争力,还为客户提供了更加全面和优质的服务。

High Energy Corp公司的发展小趣事

1980年,Dytran由传感器行业的资深人士尼古拉斯·D.改变(Nicholas D. Change)创立。在此之前,尼古拉斯在纽约地区的一家开创性传感器制造商担任产品线经理,积累了丰富的行业经验。他看到了传感器市场的巨大潜力,于是决定成立自己的公司,将自己的设计和创新带入这个不断增长的领域。Dytran的名字来源于“动态”和“换能器”的结合,寓意着公司专注于动态测量和转换技术的研发。

在创业初期,Dytran就展现出了其技术实力。公司专注于压电加速度计的研发和生产,凭借其卓越的性能和稳定性,迅速在市场上崭露头角。此后,Dytran不断推出新的传感器产品,如称重传感器、压力传感器和脉冲锤等,逐渐在电子行业树立了其技术领先的形象。

Emerging Display Technolgies公司的发展小趣事

某新兴显示技术公司,将量子点技术应用于显示屏中,成功提升了显示效果和色彩表现。量子点技术通过精确控制发光材料的尺寸和组成,实现了更广的色域覆盖和更高的色彩准确性。这一技术的应用,使得显示屏在色彩还原、对比度等方面有了显著提升,为用户带来了更加真实、生动的视觉享受。

BROTHER公司的发展小趣事

在电子行业的发展过程中,技术创新始终是BROTHER公司的重要驱动力。公司注重研发投入,拥有一支高素质的研发团队,不断推出具有创新性和竞争力的新产品。同时,BROTHER还积极与高校、科研机构等合作,开展产学研合作,推动技术创新和产业升级。通过技术创新,BROTHER不仅提升了产品质量和性能,还降低了生产成本,提高了市场竞争力。

Bals Elektrotechnik GmbH & Co KG公司的发展小趣事

在1948年,Günter Bals在完成了建筑公司的学徒实习后,决定创立自己的运输公司。他凭借自己的勤奋和才智,很快建立起了一支由14辆卡车组成的运输队伍,并在德国本地开展货运代理业务。这一阶段的创业经历不仅锻炼了Bals的商业头脑,也为他日后在电子行业的发展积累了宝贵的资金和经验。

ENSIGN公司的发展小趣事

ENSIGN的前身Skylight于1998年在上海成立,专注于商业照明领域。随着市场需求的增长,公司于2003年正式更名为ENSIGN,并开始为零售店铺提供全面的商业照明解决方案。ENSIGN凭借其创新的设计和高质量的产品,逐渐在市场中树立了良好的口碑。

问答坊 | AI 解惑

IPTV探讨

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 新政策 新技术 新运营 新融合    IPTV是一场革命,它将电视和互联网的优势最大限度地结合在了一起,人们的生活方式将因此而改变。“预计到2008年,全球IPTV用户数将达4400万,市场规模将达82 ...…

查看全部问答>

[终结版]串口上位机

[注:之所以叫终结版,是因为现在没有多少时间再去做这个了,有新的任务了.谢谢指教] 写了一个上位机,是个简单的调试助手。快考试了,也没有时间再去弄VB了。现在把资料打包上来,里面有源程序,下位机的程序可以验证上位机的全部功能。安装好后, ...…

查看全部问答>

主流无线芯片性能汇总了下

ADF7021 SI4432  NRF905 RF903 CC1100 CC2500 CC1020 NRF2401 NRF24L01 无线数传芯片/模块…

查看全部问答>

小白跪问 现有ARM9开发板上的RS232口怎么改成RS485的?

我的老师那里有一块开发板,其中J6接口如下图所示: 标号    名称           功能                  说明 J6   &n ...…

查看全部问答>

关于讲解STM32V3.0库组成的文章

对初学者理解STM32最新文件系统会有帮助 如何从STM32F10xxx固件库V2.0.3升级到V3.0.0 [local]1[/local] 如何从STM32F10xxx固件库V2.0.3升级到V3.0.0.pdf (1.22 MB) 下载次数:1193 2010-8-12 16:49 ...…

查看全部问答>

MSP430 问题汇总 Ver 1.0

MSP-EXP430G2 LaunchPad FAQs1. Does the MSP-EXP430G2 support fuse blow?The MSP-EXP430G2 LaunchPad experimenter board onboard debugging interface lacks the JTAG security fuse-blow capability. To ensure firmware security on devices g ...…

查看全部问答>

三星的eMMC iNAND和DDR3 SDRAM跳楼价甩了

三星的eMMC iNAND(型号KLM2G1DEHE)大概还有50片左右,DDR3 SDRAM(型号K4B2G0846C)大概30片的样子都是BGA封装,冰点吐血价5元每片,照例上图 淘宝小店:http://shop34118588.taobao.com/…

查看全部问答>