单片机开发过程中,GPIO上升沿和下降沿检测应用的地方还是很多,但是怎么样编写这个功能模块,网上资料参差不齐,结合实际和参考PLC逻辑,自行编写了一套逻辑。

以下是全部代码:

头文件 EdgewaysJudge.h

/** EdgewaysJudge.h**  Created on: 2022年6月10日*      Author: duola_rain*/#ifndef APP_EDGEWAYSJUDGE_H_
#define APP_EDGEWAYSJUDGE_H_
#include "Type.h"#define PLS_SUM  100
#define PLF_SUM  100//定时 触点  经过值 设定值
#define STIMER_EMPTY  0
#define STIMER_VALID  1//ms
#define STIMER_BASETIME 10typedef  u16 (*StimerProcFunc)();
typedef s8 (*EdgeFunc)(u8 xOldValue,u8 xId);typedef struct
{bool ucPlsValue;bool ucPlfValue;bool rtResult;bool Result;
}Edgeways_t;typedef struct
{StimerProcFunc     ProcFunc;EdgeFunc pEdge;// 传入参数 0:上升沿检查  1:下降沿检查u32     uiArgParam;//时间间隔u32     uiTimerSet ;// 时间计数u32    uiTimerCnt;//定时器状态u32    ucTimerStatus;//超时标志u8    ucTimeOutFlag;//保持时间u32 ucKeepTime;//保持时间计数u32 ucKeepTimeCnt;// 循环周期,-1为无限循环u32    iCycle;
} Stimer ;#define MAX_TIMER 2extern void EdgewaysJudge_Init(void);
extern void AxStimerProc(void);
extern void AxStimerTaskManage(void);
extern bool AxCommonUtilCheck(u8 xId);
extern void AxCommonUtilClearn(u8 xId);
extern bool ISD2_isAxNege(void);
extern void ISD2_CLearn(void);
extern s32 AxStartStimer(u8 xId, StimerProcFunc  xProcFunc, u8 xTimeSet,u32 xArgParam, u32 KeepTime, s32  xCycle);#endif /* APP_EDGEWAYSJUDGE_H_ */

源码:

#include "string.h"
#include "EdgewaysJudge.h"
#include "Global.h"//typedef void (*DataChgeFunc)(void);
// vale
Edgeways_t Edgeways[MAX_TIMER];
typedef s8 (*EdgewaysJudgeFunc)(u8 xOldValue,u8 xId);
EdgewaysJudgeFunc JudgeFunc[2];//extern
extern u16 DI_ReadISD2(void);
static s8 AxPoseEdgeFuc(u8 xOldValue,u8 xId);
static s8 AxNegeEdgeFuc(u8 xOldValue,u8 xId);void EdgewaysJudge_Init(void)
{JudgeFunc[0] = AxPoseEdgeFuc;JudgeFunc[1] = AxNegeEdgeFuc;memset(Edgeways,0,sizeof(Edgeways));AxStartStimer(0, DI_ReadISD2, 1, 0, 500 , -1);
}bool ISD2_isAxNege(void)
{return  AxCommonUtilCheck(0);
}void ISD2_CLearn(void)
{AxCommonUtilClearn(0);
}//上升沿
static s8 AxPoseEdgeFuc(u8 xOldValue,u8 xId)
{u8 cPls;s8 ret = -1;if((xId < MAX_TIMER)&&(xOldValue^Edgeways[xId].ucPlsValue)){cPls =xOldValue&(xOldValue^Edgeways[xId].ucPlsValue);Edgeways[xId].ucPlsValue = xOldValue;Edgeways[xId].rtResult = cPls;ret = cPls;}return  ret;
}//下降沿
static s8 AxNegeEdgeFuc(u8 xOldValue,u8 xId)
{u8 cPlf;s8 ret = -1;if((xId < MAX_TIMER)&&(!xOldValue^Edgeways[xId].ucPlfValue)){cPlf = !xOldValue&(!xOldValue^Edgeways[xId].ucPlfValue);Edgeways[xId].ucPlfValue = !xOldValue;Edgeways[xId].rtResult = cPlf;ret = cPlf;}return ret;
}static Stimer  tStimerBuf[MAX_TIMER];s32 AxStartStimer(u8 xId, StimerProcFunc  xProcFunc, u8 xTimeSet,u32 xArgParam, u32 KeepTime, s32  xCycle)
{u16 tmpVale;StimerProcFunc cFunc;if (xId >= MAX_TIMER){return -1;}if (STIMER_EMPTY == tStimerBuf[xId].ucTimerStatus){tStimerBuf[xId].ucTimerStatus = STIMER_VALID;tStimerBuf[xId].uiTimerCnt = 0;tStimerBuf[xId].ucTimeOutFlag = 0;tStimerBuf[xId].uiTimerSet = xTimeSet;tStimerBuf[xId].ProcFunc = xProcFunc;tStimerBuf[xId].uiArgParam = xArgParam;tStimerBuf[xId].ucKeepTime = KeepTime;tStimerBuf[xId]. iCycle = xCycle;cFunc = tStimerBuf[xId].ProcFunc;if ( cFunc != 0){tmpVale =  (*cFunc)(tStimerBuf[xId].uiArgParam);}switch(tStimerBuf[xId].uiArgParam){case 0:Edgeways[xId].ucPlsValue = tmpVale;break;case 1:Edgeways[xId].ucPlfValue = !tmpVale;break;}return 1;}return -1;
}void AxStopStimer(u8 xId)
{if (xId >= MAX_TIMER) return;if (STIMER_VALID == tStimerBuf[xId].ucTimerStatus){tStimerBuf[xId].ucTimerStatus = STIMER_EMPTY;tStimerBuf[xId].uiTimerCnt = 0;tStimerBuf[xId]. iCycle = 0;tStimerBuf[xId].ucTimeOutFlag = 0;tStimerBuf[xId].uiTimerSet = 0;}
}//1ms
void AxStimerProc(void)
{int i;for (i = 0; i < MAX_TIMER; i++){if (STIMER_VALID == tStimerBuf[i].ucTimerStatus){if (tStimerBuf[i].uiTimerCnt < tStimerBuf[i].uiTimerSet){tStimerBuf[i].uiTimerCnt++;}else{tStimerBuf[i].ucTimeOutFlag = 1;}}}
}//1ms
void AxStimerTaskManage(void)
{u32 i;u16 tmpVale;StimerProcFunc cFunc;for (i = 0; i < MAX_TIMER; i++){if (STIMER_VALID == tStimerBuf[i].ucTimerStatus){if (tStimerBuf[i].ucTimeOutFlag){cFunc = tStimerBuf[i].ProcFunc;if ( cFunc != 0){tmpVale =  (*cFunc)(tStimerBuf[i].uiArgParam);}if(tStimerBuf[i].ucKeepTimeCnt <=  tStimerBuf[i].ucKeepTime){switch(tStimerBuf[i].uiArgParam){case 0:(*JudgeFunc[0])(tmpVale,i);break;case 1:(*JudgeFunc[1])(tmpVale,i);break;}if(Edgeways[i].rtResult){tStimerBuf[i].ucKeepTimeCnt ++;}else{tStimerBuf[i].ucKeepTimeCnt = 0;Edgeways[i].Result =  Edgeways[i].rtResult;}}else{else{tStimerBuf[i].ucKeepTimeCnt = 0;Edgeways[i].Result =  Edgeways[i].rtResult;}if (0 == tStimerBuf[i].iCycle){AxStopStimer(i);}if (tStimerBuf[i].iCycle > 0){tStimerBuf[i].iCycle--;}}}}
}void AxCommonUtilClearn(u8 xId)
{Edgeways[xId].rtResult = 0;Edgeways[xId].Result = 0;
}bool AxCommonUtilCheck(u8 xId)
{return Edgeways[xId].Result > 0? true : false;
}

【无标题】单片机上升沿和下降沿相关推荐

  1. 上升沿_输入输出的上升沿和下降沿是怎么来的,一起看看

    高电平.低电平.上升沿和下降沿的区别 数字电路中,电平从低电平(逻辑信号为0)变为高电平(逻辑信号为1)的那一瞬间叫作上升沿,电平从高电平(逻辑信号为1)变为低电平(逻辑信号为0)的那一瞬间叫作下降沿 ...

  2. 【无标题】Ds1302驱动代码编写并在Lcd1602液晶显示

    目录 Ds1302实时时钟芯片简介 一.Ds1302寄存器介绍 二.SPI总线通讯时序与Ds1302时序 1.SPI总线时序 2.Ds1302时序解析以及控制代码 总结 Ds1302实时时钟芯片简介 ...

  3. [C#小技巧]如何捕捉上升沿和下降沿

    上升沿和下降沿在我们开发上位机时使用率非常高,常见于消息触发.脉冲归档等.但是在C#中没有类似PLC中的上升沿.下降沿那样的指令,需要我们自己编码来实现. 首先我们创建一个用于生成上升沿和下降沿的类, ...

  4. 关于WM_NCHITTEST消息(移动无标题对话框多个)

    我为了移动一个无标题栏的窗体,使用了WM_NCHITTEST消息,这个消息大概如下: 通常,我们拖动对话框窗口的标题栏来移动窗口,但有时候,我们想通过鼠标在客户区上拖动来移动窗口. 一个容易想到的方案 ...

  5. mysql输入命令1002无标题_Linux下远程连接MySQL数据库的方法

    步骤 1.在服务器端开启远程访问 首先进入mysql数据库,然后输入下面两个命令: grant all privileges on *.* to 'root'@'%' identified by 'p ...

  6. C# 系统应用之无标题窗体移动的两种方法

    在做项目界面设计中,常常为了美观需要设置窗体属性"FormBorderStyle"(窗体边框和标题栏外观)为None无标题窗口.此时隐藏标题的窗口怎样实现移动呢?我根据自己的项目从 ...

  7. Android 置Activity全屏和无标题

    今天,实在没有什么好些写的内容,所以在网上找了很久,才决定写这个博客.比较简单,还是想保持写博客的习惯. 一.在代码里设置全屏. Activity设置全屏和无标题栏,要用到andorid.view.W ...

  8. 问:关于上升沿和下降沿触发的讨论

    问:关于上升沿和下降沿触发的讨论 答:发现一些同仁提出上升沿和下降沿计数的问题,工作中也碰到一些同事问及此问题.现在我把我多年 来一直采用的办法奉上,但愿对初学者有所帮助.  以一个最简单的计数器为例 ...

  9. ActionBarActivity设置全屏无标题

    新建的Activity继承自ActionBarActivity,设置全屏无标题本来非常easy的事,可是没想到app居然无缘无故的挂,要么就是白屏一片,要么就是黑屏.坑了我一个多小时.!! 原因是Ac ...

最新文章

  1. tomcat的三种部署方式
  2. 订餐系统之自动确认淘点点订单
  3. 被限高消费后,王思聪又有新动作:新增对外投资...
  4. 结构体08:结构体案例2
  5. 使用XAML和SharpMap渲染一幅地图
  6. 求职与简历功能上线测试
  7. 微信小程序demo测试实践
  8. VMware安装CentOS 7.0 Fail to start media check on /dev/sr0
  9. R语言 —— 包(package)的下载和使用
  10. 矩阵标准型的系数是特征值吗_「线性代数」根据特征值,将二次型化为标准形、规范形...
  11. 如何用计算机名查看共享打印机,如何查找网络共享打印机
  12. 形式逻辑(04)选言判断 和 推理
  13. 以前手机应用java咖啡_作为编程语言的“java”怎么就成了咖啡的代称?
  14. 打电话降噪蓝牙耳机推荐,适合通勤使用的降噪蓝牙耳机分享
  15. IOS5短信拦截怎么实现?
  16. java基础代码,适合0基础学习者
  17. 软件测试 | 生命周期
  18. 四十九、HBase介绍
  19. python贪心算法最短路径_dijkstra算法(贪心算法)——解决最短路径问题
  20. Graphite.v8.SP1.R4.Build.848 1CD (2D的CAD制图工具)

热门文章

  1. 使用Java、Servlet 生成二维码
  2. ARM微架构与程序编写
  3. 无氧运动的时候长期做大重量和小重量有什么区别
  4. JOISC 2020 补题记录
  5. 全网最佳IoT命令行超级工具箱|帮你轻松解决百万物联网设备测试和联调穆书伟
  6. SwiftUI 和 Combine 的学习:一
  7. 手机边充电边玩,消耗的电量是来自电池还是充电器呢?
  8. 电赛获奖计算机专业有用吗,计电学院获奖喜报
  9. 蓝牙耳机什么牌子好?500内好用的蓝牙耳机推荐
  10. SPFA 算法详解( 强大图解,不会都难!) (转)