【无标题】单片机上升沿和下降沿

单片机开发过程中,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 10

typedef  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 2

extern 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;
}
       

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值