关于Delay函数的思考

关于Delay函数的思考可能很多人对延时函数的使用并不排斥,但是我个人觉得这是非常不符合软件的本质的。软件的本质是将现实中的各种行为抽象。以现实中人的活动为例,人在同一时刻是可以实时响应很多事情的,而Delay函数的出现相当于给CPU上了刹车

大家好,又见面了,我是你们的朋友全栈君。

这几天一直在忙的一个项目中有一小部分是对机械按键的操作,在准备些BSP的时候突然想起来以前在大学
常用的处理方法就是按键消抖然后识别,待消抖最后弹起,并且所有的消抖程序段都是依靠延时程序实现。
可能很多人对该函数的使用并不排斥,但是我个人觉得这是非常不符合软件的本质的,并且也并不合理。
软件的本质是将现实中的各种行为抽象。以现实中人的活动为例,人在同一时刻是可以实时响应很多事情的,
而Delay函数的出现相当于将CPU进行软件暂停而对实时的任务拒之门外(中断除外),这在很多对任务的
执行时间有着严格要求的场合是难以忍受的。并且糟糕的是,系统任务越多,Delay函数的影响越大。那难
倒就没有了别的解决办法了吗?其实答案就在μ/COSii里。
在实时操作系统里有一个概念叫信号量,用来处理不同事件状态的查询或者对不同任务队同一资源的请求。
标志,该时间标志位在50微秒(暂定)的定时器中断中递增,当达到计时时间要求后就传递给响应的需要延
时的任务,然后该变量清零。
我们以按键的识别为例,在实际按键按下以后,需要等待按键可靠弹起,一般来说在一定时间内如果按键
借用操作系统的思路是用标志位进行间隔扫描状态,这样可以精确的判断按键的状态。详细示意图如下所示:

![按键扫描示意图](https://img-blog.csdn.net/20150817223738086)

以下是编写的BSP程序(基于DSP C2000)

/*******************************************************************************
* * -------------------------
* Details to create profits
* * All rights reserved.
* Contact information:V1.0
* QQ:    836002276
* e-mail:      836002276@qq.com
*******************************************************************************/
/******************************************************************************
 * 本文件实现了Key.c文件中函数的定义和全局变量的定义
 * 1.0.0, 2015-07-4, Aaron       created
 ******************************************************************************/
#include"Key.h"

_KEY_EVENT     KEY_1;                //定义按键一结构体
/*******************************************************************
 * 函数描述:按键事件结构体初始化
 * 形参:按键事件结构体指针
 * 返回值:无
 * 调用者:应用层
 ******************************************************************
void Key_Event_Init(_KEY_EVENT *key_x)
{
 key_x->Key_Change_Time = 0;
 key_x->Key_Flag = 0;
 key_x->Key_Over_Flag = 0;
 key_x->Key_Date = 0;
 key_x->Key_Recover_Flag = 0;
 key_x->Key_Original_Mod = 0;
}
/*******************************************************************
 * 函数描述:按键扫描,实现了按键的按下识别和按键的有效弹起识别
 * 形参:按键事件结构体指针
 * 返回值:无
 * 调用者:应用层
 *******************************************************************
 void Key_Scan(_KEY_EVENT *key_x)
 {
 if(key_x->Key_Date^key_x->Key_Original_Mod)
 { 
   
 key_x->Key_Flag = 1;
 key_x->Key_Over_Flag = 0;
 key_x->Key_Change_Time = 0;
 }
 else
 { 
   
 if(key_x->Key_Change_Time%200 == 0)
 { 
   
 if(key_x->Key_Date = key_x->Key_Original_Mod)
 { 
   
 key_x->Key_Recover_Flag++;
 }
 }
 if(key_x->Key_Recover_Flag >=10)
 { 
   
 key_x->Key_Change_Time = 0;
 key_x->Key_Over_Flag = 0;
 key_x->Key_Recover_Flag = 0;
 }
 }
 }
 /*******************************************************************
 * 函数描述:上电时检测按键在没有按下时输入口的状态,主要目的是为了确定
 是下降沿检测还是上升沿检测
 * 形参:按键事件结构体指针
 * 返回值:无
 * 调用者:应用层
 *******************************************************************
 void  IO_First_Mod_Scan(_KEY_EVENT *key_x)
 {
 if(key_x->Key_Date == 0)
 { 
   
 key_x->Key_Original_Mod = 0;
 }
 else
 { 
   
 key_x->Key_Original_Mod = 1;
 }
 }
 /*******************************************************************
 * 函数描述:对时间计数器进行自加,超过1秒钟就清零
 * 形参:按键事件结构体指针
 * 返回值:无
 * 调用者:定时中断
 *******************************************************************
 void Key_Time_Sum(_KEY_EVENT *key_x)
 {
 key_x->Key_Change_Time++;
 if(key_x->Key_Change_Time >20000)
 { 
   
 key_x->Key_Change_Time = 0;
 }
 }
 /*******************************************************************
 * 函数描述:定时器中断函数
 * 形参:无
 * 返回值:无
 * 调用者:应用层
 *******************************************************************
 void Time_Isr(void)
 {
 Key_Time_Sum(KEY_1); 
 }
/*******************************************************************************
* * -------------------------
* Details to create profits
* * All rights reserved.
* Contact information:V1.0
* QQ:    836002276
* e-mail: sure220@gmail.com
*******************************************************************************/
/******************************************************************************
 * 本文件实现了Key.c文件中函数的声明和全局变量的声明
 * 1.0.0, 2015-07-4, Aaron       created
 ******************************************************************************/
#ifndef KEY_H_
#define KEY_H_

typedef struct{
 unsigned char Key_Flag;
 unsigned char Key_Over_Flag;
 unsigned int Key_Change_Time;
 unsigned char Key_Date;
 unsigned char Key_Recover_Flag;
 unsigned char Key_Original_Mod;
}_KEY_EVENT;

void Key_Event_Init(_KEY_EVENT *key_x);
void Key_Scan(_KEY_EVENT *key_x);A
void  IO_First_Mod_Scan(_KEY_EVENT *key_x);
void Key_Time_Sum(_KEY_EVENT *key_x);


#endif /*KEY_H_*/

中断程序在此略过,因为中断中关于按键的部分仅仅是调用Key_Time_Sum()函数进行时间变量的递增。在CPU上电后首先调用IO_First_Mod_Scan()函数用来设置按键的初始状态,然后再在主函数中调用Key_Scan()既可。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137210.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于revision 的cover letter

    关于revision 的cover letterhttp://emuch.net/html/201101/2741196.html 好,coverletter明白了。那SuggestedListofPotentialReferees如何处理呢?大家好,自己有篇elsevier的期刊在修改!不知道在提交修改稿的时候。大家的coverletter如何处理????因为系统要求专门的response

    2022年5月29日
    47
  • Myeclipse6.0.1注册码获取方法[通俗易懂]

    Myeclipse6.0.1注册码获取方法[通俗易懂]工具是:Myeclipse6.0.1获取zhucem

    2022年9月27日
    0
  • 计算机网络笔记Part1 概述「建议收藏」

    计算机网络笔记Part1 概述「建议收藏」概述1.速率相关性能指标速率定义:连接在计算机网络上的主机在数字信道上传送数据位数的速率单位:b/s,Kb/s,Mb/s,Tb/s,如果用字节表示,则是B/s,KB/s,MB/s,TB/s1Byte=8Bit带宽在计算机网络中,指的是网络设备所支持的最高速度,单位同速率,是理想条件下最高速率吞吐量指的是单位时间内通过某个网络的数据总量个人理解速率就是实际网速,带宽是理论网速(长城宽带警告),吞吐量是一个或多个设备的综合速率,比如说1000m宽带的路由器连着三部手机,每部手机都是10m

    2022年6月6日
    24
  • 如何解决Ubuntu 14.04编译make menuconfig时缺少’ncurses-devel’库[通俗易懂]

    如何解决Ubuntu 14.04编译make menuconfig时缺少’ncurses-devel’库[通俗易懂]今天在使用64位的Ubuntu14.04系统编译linux源码的makemenuconfig命令时,得到了一个错误的提示,说我没有安装相应的库:Unabletofindthencurseslibrariesortherequiredheaderfiles.’makemenuconfig’requiresthencurseslibraries.Instal…

    2022年6月2日
    37
  • vue 生成二维码 打印_代码生成二维码

    vue 生成二维码 打印_代码生成二维码npminstallqrcodejs2–save<template><div><divid=”qrCode”ref=”qrCodeDiv”></div></div></template><script>importQRCodefrom’qrcodejs2′;exportdefault{name:”qrCode”,data(){.

    2022年9月26日
    0
  • hibernate的hql语句批量删除

    hibernate的hql语句批量删除hibernate使用hql语句,根据条件进行批量删除操作;比如:1.给方法传递一个参数,我传递的是userid2.hql语句编写,根据userid进行删除(我使用了拼接userid的方式进行条件拼接)3.通过createQuery(hql),先到数据库查询满足条件的数据。然后通过executeUpdata()方法进行了批量更新删除操作;具体的代码如下:publicvoidemptycartItm(Integeruserid){//根据条件批量删除Stringhql=“delete

    2022年6月16日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号