历史上的今天
返回首页

历史上的今天

今天是:2025年02月19日(星期三)

正在发生

2019年02月19日 | 51单片机按键检测和信号函数仿真

2019-02-19 来源:eefocus

在单片机中会遇到识别按键的问题,常用的独立按键电路如下图: 

 

这里写图片描述 


由于机械式触点开关具有弹性,会发生抖动,所以要进行消抖。有两种消抖方式:硬件消抖和软件消抖。 


硬件消抖电路: 

 

这里写图片描述 


软件消抖常采用延时消抖:按键被按下时,当检测到低电平时,延时一段时间,一般是5到10ms,然后再检测端口,若还是低电平,则表示检测到按键按下,按键弹起时同理可得。


独立按键的检测一般采用两种方法:中断检测和查询检测。 


按键连接P3^2引脚,检测按键按下和弹起的次数。


1.查询检测:可以直接在主程序中循环检测,也可以通过定时器,每隔20ms检测一次。下面是直接在循环中检测的。


主函数:


#include

#include


#define uint unsigned int 


sbit in0 = P3^2 ;  //输入信号引脚


uint Press_flag = 1 ; //按键按下标志

uint count = 0 ;   //按键次数


void delay_ms(uint ms)

{

    uint i , j ;

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

    {

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

        {

            _nop_() ;

        }

    }

}


void key()

{

       if(in0 == 0)  //检测到0

        {

            delay_ms(10) ;   // 延时消抖

            if(in0 == 0)    //再次检测到0

            {

                Press_flag = 0 ;  //代表按键被按下

            }

        }


        if(Press_flag == 0)    //如果按键被按下,再检测按键弹起

        {

            if(in0 == 1)

            {

                delay_ms(10) ;

                if(in0 == 1)

                {

                    count ++ ;    //表示按键按下并弹起的次数

                    Press_flag = 1 ;      //复位按键按下标志

                }

            }

        }


}


void main(void)

    while(1)

    {

          key() ;

    }

}


信号函数:



signal void test(unsigned int cc) 

{

    unsigned int i , j ;

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

    {

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

        {

            port3 &= ~(1<<2) ;

            swatch(0.002) ;

            port3 |= 1<<2 ;

            swatch(0.002);

        }

        port3 &= ~(1<<2) ;

        swatch(0.002) ;


        swatch(0.01) ;


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

        {

            port3 |= 1<<2 ;

            swatch(0.002) ;

            port3 &= ~(1<<2) ;

            swatch(0.002) ;

        }   


        port3 |= 1<<2 ;

        swatch(0.02) ;


        swatch(0.1) ;

    }

    _break_ = 1 ;

}


信号函数波形图: 


可以看到count的值为4 



2.中断检测


主程序:


#include

#include


#define uint unsigned int 


sbit in0 = P3^2 ;

uint count = 0 ;    

uint press_flag = 1 ;


void delay_ms(uint ms)

{

    uint i , j ;

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

    {

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

        {

            _nop_() ;

        }

    }

}



void Init_INT(void)

{

    EA = 1 ; //开总中断

    EX0 = 1 ; //开外部中断0

    IT0 =  1 ; //下降沿触发中断

}


void Int0 (void) interrupt 0

{

    EX0 = 0 ; //关闭外部中断0,防止频繁触发中断

    delay_ms(10) ;

    if(in0 == 0)

    {

        press_flag = 0 ;//按键按下标志

    }

    if(press_flag == 0 && in0 == 1)//检测按键弹起

    {

        delay_ms(10) ;

        if(in0 == 1)

        {

            count++ ;

            press_flag = 1 ;

        }

    }

    EX0 = 1 ;  //开启外部中断

}


void main(void)

{

    Init_INT() ; // 中断初始化


    while(1)

    {


    }

}

推荐阅读

史海拾趣

力芯微(ETEK)公司的发展小趣事

随着下游电子产品的更新换代和手机的快速普及,力芯微公司敏锐地捕捉到了这一市场机遇。公司及时调整研发方向,推出一系列低压低功耗的电源类产品,成功进入手机市场。这一转型不仅使公司实现了业务的多元化,也为公司带来了新的增长点。

Compact公司的发展小趣事

近年来,电子行业经历了多次技术变革和市场洗牌。面对这些挑战,Compact公司积极调整战略,加大研发投入,以适应市场变化。同时,公司还通过优化生产流程、降低成本等方式提高竞争力。在行业变革中,Compact公司不仅成功应对了挑战,还抓住了机遇,实现了跨越式发展。

Bce Sud公司的发展小趣事

随着公司规模的扩大和市场份额的提升,Bce Sud开始实施国际化战略。公司先后在多个国家和地区设立了研发中心和销售网络,进一步扩大了市场份额。通过与国际知名企业的合作与交流,Bce Sud不断提升自身的技术水平和国际竞争力。

Cal Test Electronics公司的发展小趣事

随着全球市场的不断变化和公司规模的扩大,Cal Test Electronics开始实施全球化战略。公司积极拓展海外市场,通过参加国际展会、建立海外销售渠道等方式,提高品牌知名度和市场份额。同时,公司还加强与国际同行的合作与交流,引进先进的技术和管理经验,不断提升自身的竞争力。这些努力使得Cal Test Electronics逐渐成为一个具有全球影响力的电子配件和测试产品制造商。


这些故事旨在展示Cal Test Electronics公司可能的发展轨迹和成就,但并非基于实际发生的事件。对于该公司的真实发展历程和故事,建议查阅相关官方资料或行业报告以获取更准确的信息。

Custom LeatherCraft Manufacturing Co Inc公司的发展小趣事

CLC起源于一个对高质量手工皮革制品有着无限热情的小型工坊。创始人是一位经验丰富的皮革工匠,他看到了电子工程师和户外工作者对耐用、实用的工具包的需求。于是,他开始了自己的创业之路,以“定制皮革工艺”为核心理念,承诺每一件产品都经过精心制作和严格质检。凭借这份承诺和精湛的技艺,CLC逐渐在市场中赢得了口碑。

Hamamatsu公司的发展小趣事

随着电子行业的迅速发展,工程师和技术人员需要携带的工具和设备也越来越多。CLC敏锐地捕捉到了这一变化,开始研发具有更多功能和口袋的工具包。同时,他们还引入了新的材料和技术,使产品更加轻便、耐用。这些创新设计不仅满足了客户的需求,还进一步巩固了CLC在市场上的地位。

问答坊 | AI 解惑

听人说居然有0.5元以下的单片机,你见到最便宜的是多少钱的?

今天看到坛子里有人说有5毛钱的单片机,类似闪灯IC等, 没有听说过,大家见到最便宜的单片机都多少钱?有什么功能,干什么用的呢?…

查看全部问答>

请教WinCE下加载位图的文件路径问题

在模拟器下实现加载位图,请问: 1、此时函数SHLoadDIBitmap(TEXT(\"\\\\*.bmp\"))中的路径该如何设置呢,或者是说我试图加载的位图应该存放于什么路径呢; 2:位图本身的大小有没有什么限制啊? 谢谢各位啦…

查看全部问答>

大家知道怎么样选购UPS电源吗?

很多人在购买UPS的时候没有考虑到UPS电源的很多因素,这样将会损坏到我们的服务器和需要保护的设备。首先要根据您的负载(也就是功率大小)来选定您的UPS电源,比如说您的服务器是750瓦的那么您要选购买1500VA或者是2000VA的UPS电源,为什麽不能选 ...…

查看全部问答>

关于若干个s7PLC DP 组网的问题

本人现在面临一个DP组网问题,想求教。现有3个CPU315-2DP,6个EM277,一个5621卡。我希望能一个CPU315-2DP-1通过DP带一个EM277, 另一个CPU315-2DP-2通过DP带3个EM277, 还有一个CPU315-2DP-3通过DP带2个EM277, 希望CP5621能和每个CPU315-2DP通讯,各C ...…

查看全部问答>

急,430F449的P1中断服务程序不能运行(附程序),请多指教

//下面是我的一段P1键盘中断测试程序,可是我好象进不了P1中断服务程序,请各位大侠多多指教 #include <msp430x44x.h> void inter (void); int num=0; void main(void) { WDTCTL=WDTPW+WDTHOLD; P1DIR&=~0X07; P1IES|=0X ...…

查看全部问答>

在skyeye1.2.4上编译并运行2.6.14内核

SkyEye是一个开源软件(OpenSourceSoftware)项目,中文名字是\"天目\"。SkyEye的目标是在通用的Linux和Windows平台上实现一个纯软件集成开发环境,模拟常见的嵌入式计算机系统(这里假定\"仿真\"和\"模拟\"的意思基本相同);可在SkyEye上运行μCL ...…

查看全部问答>

【转载】Linux中的通知链技术

转载自 http://blog.csdn.net/jjbear_ustc/archive/2009/12/22/5057009.aspx在Linux内核中,各个子系统之间有很强的相互关系,某些子系统可能对其它子系统产生的事件感兴趣。为了让某个子系统在发生某个事件时通知感兴趣的子系统,Linux内核引 ...…

查看全部问答>

求怎么样能快速看懂线路图

我是一个刚刚学习电子技术的初学者,每次看到原理图头都朦朦的,不知道从哪里看起,请教一下,谢谢…

查看全部问答>

宽带程控放大器

做个程控放大器通频带宽大于60MHz,增益大于60dB用什么芯片好??带宽增益积要非常的高??…

查看全部问答>