历史上的今天

今天是:2024年11月12日(星期二)

2021年11月12日 | 51单片机实现按住一个独立按键不松手的连续步进触发

发布者:TranquilDreamer 来源: eefocus关键字:51单片机  独立按键 手机看文章 扫描二维码
随时随地手机看文章

一、使用proteus绘制简单的电路图,用于后续仿真

二、编写程序


/********************************************************************************************************************

---- @Project: Independent-KEY

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200507

---- @ModifiedTime: 20200507

---- @Description: 两个独立按键S1和S2,S1键作为加键。S2键做为减键。每按一次S1键则被设置参数uiSetNumber自加1。如果按住S1键不松手超过1秒钟,被设置参数uiSetNumber以每0.25秒的时间间隔往上自加1,一直加到20为止。每按一次S5键则被设置参数uiSetNumber自减1。如果按住S2键不松手超过1秒钟,被设置参数uiSetNumber以每0.25秒的时间间隔往下自减1,一直减到0为止。当被设置参数uiSetNumber小于10的时候,LED灯灭;当大于或者等于10的时候,LED灯亮。

---- 单片机:AT89C52

********************************************************************************************************************/

#include "reg52.h"

/*——————宏定义——————*/

#define FOSC 11059200L

#define T1MS (65536-FOSC/12/1000)   /*1ms timer calculation method in 12Tmode*/

 

#define const_voice_short  80   /*蜂鸣器短叫的持续时间*/

 

#define const_key_time1  60    /*按键去抖动延时的时间*/

#define const_key_time2   60     /*按键去抖动延时的时间*/

 

#define const_time_0_25s  200    /*0.25秒钟的时间需要的定时中断次数*/

#define const_time_1s   800     /*1秒钟的时间需要的定时中断次数*/

 

/*——————变量函数定义及声明——————*/

/*定义按键S1*/

sbit Key_S1 = P0^0;

/*定义按键S2*/

sbit Key_S2 = P0^1;

/*定义蜂鸣器*/

sbit BUZZER = P2^7;

/*定义LED*/

sbit LED = P3^5;

 

unsigned char ucKeySec = 0;   /*被触发的按键编号*/

 

unsigned int  uiKeyTimeCnt1 = 0; /*按键去抖动延时计数器*/

unsigned char ucKeyLock1 = 0; /*按键触发后自锁的变量标志*/

unsigned char uiKeyCtntyCnt1=0; /*按键连续触发的间隔延时计数器*/

 

unsigned int  uiKeyTimeCnt2 = 0; /*按键去抖动延时计数器*/

unsigned char ucKeyLock2 = 0; /*按键触发后自锁的变量标志*/

unsigned char uiKeyCtntyCnt2=0; /*按键连续触发的间隔延时计数器*/

 

unsigned int  uiVoiceCnt = 0;  /*蜂鸣器鸣叫的持续时间计数器*/

 

unsigned int  uiSetNumber=0; /*设置的数据*/

 

/**

* @brief  定时器0初始化函数

* @param  无

* @retval 初始化T0

**/

void Init_T0(void)

{

TMOD = 0x01;                    /*set timer0 as mode1 (16-bit)*/

TL0 = T1MS;                     /*initial timer0 low byte*/

TH0 = T1MS >> 8;                /*initial timer0 high byte*/

}

/**

* @brief  外围初始化函数

* @param  无

* @retval 初始化外围

**/

void Init_Peripheral(void)

{

ET0 = 1;/*允许定时中断*/

TR0 = 1;/*启动定时中断*/

EA = 1;/*开总中断*/

 

}

 

/**

* @brief  初始化函数

* @param  无

* @retval 初始化单片机

**/

void Init(void)

{

Init_T0();

BUZZER = 1;

}

/**

* @brief  扫描按键函数

* @param  无

* @retval 独立按键扫描的详细过程:

* 第一步:平时没有按键被触发时,按键的自锁标志,去抖动延时计数器,以及时间间隔延时计数器一直被清零。

* 第二步:一旦有按键被按下,去抖动延时计数器开始在定时中断函数里累加,在还没累加到

*         阀值const_key_time1时,如果在这期间由于受外界干扰或者按键抖动,而使

*         IO口突然瞬间触发成高电平,这个时候马上把延时计数器uiKeyTimeCnt1

*         清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。

*         以后凡是用到开关感应器的时候,都可以用类似这样的方法去干扰。

* 第三步:如果按键按下的时间超过了阀值const_key_time1,则触发按键,把编号ucKeySec赋值。

*         同时,马上把自锁标志ucKeyLock1置位,防止按住按键不松手后一直触发。

* 第四步:如果此时触发了一次按键后,一直不松手,去抖动延时计时器继续累加,直到超过了1秒钟。进入连续触发模式的程序

* 第五步:在连续触发模式的程序中,连续累加延时计数器开始累加,每0.25秒就触发一次。

* 第六步:等按键松开后,自锁标志ucKeyLock1和两个延时计时器及时清零,为下一次自锁做准备。

**/

void Key_Scan(void)

{

/*扫描S1*/

if(Key_S1 == 1) /*如果按键没有被按下(高电平),将一些标志位及时清零*/

{

ucKeyLock1 = 0;/*自锁标志位清0*/

uiKeyTimeCnt1 = 0;/*按键去抖动延时计数器清零*/

uiKeyCtntyCnt1 = 0; /*连续累加的时间间隔延时计数器清零*/

}

else if(ucKeyLock1 == 0) /*如果有按键按下,且是第一次按下*/

{

uiKeyTimeCnt1 ++;

if(uiKeyTimeCnt1 > const_key_time1)/*判定按下*/

{

uiKeyTimeCnt1 = 0;

ucKeyLock1 = 1;

ucKeySec = 1;    /*触发S1*/

}

}

else if(uiKeyTimeCnt1 < const_time_1s)/*按键已按下,按键去抖动延时计数器自增到1s*/

{

uiKeyTimeCnt1 ++;

}

else/*按住累加到1秒后仍然不放手,这个时候进入有节奏的连续触发*/

{

uiKeyCtntyCnt1 ++;/*连续触发延时计数器累加*/

if(uiKeyCtntyCnt1 > const_time_0_25s)/*按住没松手,每0.25秒就触发一次*/

{

uiKeyCtntyCnt1 = 0;

ucKeySec = 1;    /*触发S1*/

}

}

/*扫描S2*/

if(Key_S2 == 1) /*如果按键没有被按下(高电平),将一些标志位及时清零*/

{

ucKeyLock2 = 0;/*自锁标志位清0*/

uiKeyTimeCnt2 = 0;/*按键去抖动延时计数器清零*/

uiKeyCtntyCnt2 = 0; /*连续累加的时间间隔延时计数器清零*/

}

else if(ucKeyLock2 == 0) /*如果有按键按下,且是第一次按下*/

{

uiKeyTimeCnt2 ++;

if(uiKeyTimeCnt2 > const_key_time2)/*判定按下*/

{

uiKeyTimeCnt2 = 0;

ucKeyLock2 = 1;

ucKeySec = 2;    /*触发S2*/

}

}

else if(uiKeyTimeCnt2 < const_time_1s)/*按键已按下,按键去抖动延时计数器自增到1s*/

{

uiKeyTimeCnt2 ++;

}

else/*按住累加到1秒后仍然不放手,这个时候进入有节奏的连续触发*/

{

uiKeyCtntyCnt2 ++;/*连续触发延时计数器累加*/

if(uiKeyCtntyCnt2 > const_time_0_25s)/*按住没松手,每0.25秒就触发一次*/

{

uiKeyCtntyCnt2 = 0;

ucKeySec = 2;    /*触发S2*/

}

}

 

}

/**

* @brief  按键服务函数

* @param  无

* @retval 根据扫描得到的值,进行数据处理

**/

void key_Service(void)

{

switch(ucKeySec)

{

case 1: /*S1,连续加*/

uiSetNumber ++;/*被设置的参数连续往上加*/

if(uiSetNumber > 20)/*最大20*/

{

uiSetNumber = 20;

}

uiVoiceCnt = const_voice_short;  /*蜂鸣器短叫*/

ucKeySec = 0; /*响应按键服务处理程序后,按键编号清零,避免一致触发*/

break;

case 2: /*S2,连续减*/

uiSetNumber --;/*被设置的参数连续往下减*/

if(uiSetNumber > 20)/*最小0,0 - 1 = 0xff > 20*/

{

uiSetNumber = 0;

}

uiVoiceCnt = const_voice_short;  /*蜂鸣器短叫*/

ucKeySec = 0; /*响应按键服务处理程序后,按键编号清零,避免一致触发*/

break;

}

}

/**

* @brief  LED函数

* @param  无

* @retval 控制LED亮灭

**/

void Led_Run(void)  /*led灯的应用程序*/

{

   if(uiSetNumber < 10)  /*如果被设置的参数uiSetNumber小于10,LED灯则灭。否则亮。*/

   {

      LED = 0;  /*灭*/

   }

   else

   {

      LED = 1;  /*亮*/

   }

}

/**

* @brief  定时器0中断函数

* @param  无

* @retval 无

**/

void ISR_T0(void) interrupt 1

{

TF0 = 0;  /*清除中断标志*/

  TR0 = 0; /*关中断*/

/*扫描按键*/

Key_Scan();

if(0 != uiVoiceCnt)

{

uiVoiceCnt --;

BUZZER = 0;

}

else

{

BUZZER = 1;

}

TL0 = T1MS;                     /*initial timer0 low byte*/

TH0 = T1MS >> 8;                /*initial timer0 high byte*/

  TR0 = 1; /*开中断*/

}

/**

* @brief  延时函数

* @param  无

* @retval 无

**/

void Delay_Long(unsigned int uiDelayLong)

{

   unsigned int i;

   unsigned int j;

   for(i=0;i   {

      for(j=0;j<500;j++)  /*内嵌循环的空指令数量*/

          {

             ; /*一个分号相当于执行一条空语句*/

          }

   }

}

/*——————主函数——————*/

/**

* @brief  主函数

* @param  无

* @retval 实现LED灯闪烁

**/

void main()

{

/*单片机初始化*/

Init();

/*延时,延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定*/

Delay_Long(100);

/*单片机外围初始化*/

Init_Peripheral();

while(1)

{

/*按键服务函数*/

key_Service();

/*LED函数*/

Led_Run();

}

}

 

三、仿真实现

关键字:51单片机  独立按键 引用地址:51单片机实现按住一个独立按键不松手的连续步进触发

上一篇:51单片机实现按住一个独立按键不松手的加速匀速触发
下一篇:最后一页

推荐阅读

  日前,中国汽车工业协会信息发布会在京召开,中国电动汽车充电基础设施促进联盟信息部仝宗旗主任发布了2018年10月全国电动汽车充电基础设施推广运行情况。   1.公共充电基础设施运行情况   公共充电基础设施增速放缓:截至2018年9月,联盟内成员单位总计上报公共类充电桩28.5万台,其中交流充电桩18.3万台、直流充电桩10.1万台、交直流一体充电...
main.c如下:#include "iom16v.h"#include "ds1302.h"#include "macros.h"#include "lcd12864.h" #define xtal 1uchar disp_time[33]="2008年11月27日 21:49:00 星期日";uchar week[14] = "一二三四五六天";/*----------键盘相关声明-------------------------------------*/#define key (PINA & BIT(0)) //功能键#define key...
11月12日消息,在今天举报的2020全球移动宽带论坛上,华为副董事长胡厚崑发表了《跨越商业裂谷 共创5G新价值的》的主题演讲。他表示,5G网络部署进入快车道,谈到5G的发展,中国是一道最亮丽的风景线。胡厚崑表示,目前国内各大运营商已经拥有60万个5G基站,5G部署覆盖超过300个城市,一年多的时间中国5G连接数达到1.6亿。“毫无疑问,中国拥有全世界最...
广告摘要声明广告撰文 | 张浩程随着进入厂家的增多,移动机器人赛道愈发拥挤。如果说未来几年之内移动机器人厂商的取胜之道在哪里,优艾智合给出的答案是:基于自研的移动机器人产品,面向客户场景打造针对性的一体化智能升级解决方案。创建于2017年的优艾智合是一家技术驱动型企业,自创立之初就确定了自身的目标,基于自身在SLAM算法上的深厚积累,致...

史海拾趣

问答坊 | AI 解惑

HT1380串行时钟芯片

HT1380串行时钟芯片一般来说,HT系列的芯片在串行口的应用一直以来就是很好的在单片机 这个领域,串行时钟一直占着很重要的位置…

查看全部问答∨

毕业设计资料---气体检测

毕业设计资料---气体检测…

查看全部问答∨

Introduction to NI VeriStand

Introduction to NI VeriStand…

查看全部问答∨

奇怪了,请大家看下做标记的那几行代码

请大家看下下面打问号几行代码,抛开其功能不说,真的是奇怪了,我都看了又看,头都大了,就是不知道为什么,请朋友们指点下 #include<reg52.h>                     &nbs ...…

查看全部问答∨

显示驱动字体问题

各位,我的LCD屏换了片选脚后,凡是在打出字的部分,都有白色方框,这是什么问题,据说是什么透明度,什么没把数据写进去之类的原因,大家可否告诉我吗?…

查看全部问答∨

si4010有没有人用过,求探讨

si4010有没有人用过,求探讨,开发软件,调试软件,烧录工具等等…

查看全部问答∨

STM32的驱动库好用吗?效率高吗?优化的吗?准备上STM32

    N多年没买过开发板了,也没用过仿真器了。都是用软件编译调试好,直接ISP,然后通过串口命令开启调试信息的输出。    昨天买了块STM32F103全功能型开发板,他们的办事效率真低(深圳到广州通常当 ...…

查看全部问答∨

最适用于图像处理的TI公司DSP

请问用哪款TI的DSP板做图像处理比较好,要可以和Matlab连接使用,且可通过Real Time Work Shop工具箱自动生成代码,要是版本新一些就更好了 最近需要买一块板子,请大家多多给建议啊 谢谢…

查看全部问答∨

求IAR Embedded Workbench for MCS-51 完整版

各位高手,小弟求IAR Embedded Workbench for MCS-51完整版,有哪位高人有,能否分享一下。我的邮箱jinghongchen@126.com…

查看全部问答∨

猎头招聘

世界500强招聘压力传感器SAE,如有兴趣可发简历至:aerie.song@seek-jobs.com.cn 要求:至少五年以上相关工作经验,英文流利。…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved