关于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()既可。

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • android 置灰不可点击,Android Studio 运行按钮灰色的完美解决方法「建议收藏」

    android 置灰不可点击,Android Studio 运行按钮灰色的完美解决方法「建议收藏」AndroidStudio运行按钮灰色的完美解决方法今天新建项目的时候突然发现编译后运行按钮为灰色。解决方案:第一步:点击图中的AddConfiguration,出来如下界面第二步:点+号,并选择AndroidApp选项出来下图所示界面第三步:在Module中下拉框中选择app如果在Module下拉框没有app这个选项点击搜索框,输入sync,从搜索结果中选择如下项:点击运行…

  • DeviceIoControl_deviceregist

    DeviceIoControl_deviceregistDeviceIoControl这个api我们用的不多,但是很重要,有时会帮助我们实现一些特别的需求,如获取硬件设备信息、与硬件设备通信(读写数据)等,对照msdn,下面我们详细解释一下这个api的用法(有什么错误再所难免,各位不吝指教啊)。DeviceIoControl是用来控

  • 数列极限定义详解「建议收藏」

    数列极限定义详解「建议收藏」数列极限的定义个人感觉不太好理解,我看了两天的教程才彻底明白数列极限的定义。在一般的教材里数列极限的定义为这说的比较抽象,我半天都理解不了N是怎么来的,n与N有什么区别,为什么要用去减a,这里我对自己的疑问做了个总结。首先是为什么要用去减a,两个数之间的接近程度可以用两个之差的绝对值来度量,差值越小,两个数就越接近(说法来源于《高等数学》同济大学)。两个数的接近程度小于任给的正数​…

  • cs与bs模式的优缺点_什么是cs什么是bs

    cs与bs模式的优缺点_什么是cs什么是bscs与bs模式关于CS(Client-Server)模式和BS(Browser-Server)模式的水很深,盆地自己也认为对此了解不够透彻,但作为手机客户端设计,如果不对CS、BS做一定程度的了解,是很容易出现一些方向性的错误、走一些弯路抑或在实现性价比上付出过多代价。本文偏向于基础知识,产品人员很多情况下不仅仅要了解表现、交互,还需要一定程度上了解可实现性、实现代价、实现形式、实现限制等…

  • ffmpeg hevc_ffmpeg视频解码

    ffmpeg hevc_ffmpeg视频解码本次目标:1)将容器中的音频码流和视频码流分离出来。2)针对mp4文件中的码流情况进行修复。解封装的基本过程:#include<stdio.h>#include”libavcodec/avcodec.h”#include”libavformat/avformat.h”//MPEG-TS文件解封装得到的码流可播放,MP4解封装得到的码流不可播放;//这与容器的封装方式有关。voiddemuxer(constchar*url){//初始化格式上下文

    2022年10月16日
  • webstorm 2021激活码【2021.8最新】

    (webstorm 2021激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

发表回复

您的电子邮箱地址不会被公开。

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