代码模拟电平触发方式(C++)

在电子电路基础中,触发方式有几种,包括高电平触发,低电平触发,上升沿触发,下降沿触发。在本文中将使用代码实现这几种方式。
其中 message/messager.hpp 中使用的消息传递方式,在另一篇文章中有所介绍。https://blog.csdn.net/xiaonuo911teamo/article/details/112044036

应用场景

  1. 想要以一种规律,触发一个事件,并且这种规律最终可以转化为上述的触发方式。
  2. 本身接收的就是实时传感器信息,通过某种转换,可以转化为上述的触发方式。

使用方式

下面的几部分代码,并不表示在一个函数中,主要是为了表现使用的简洁。

	// 前置声明
	enum TriggerType{
   
    	TRUE,	// 高电平触发
    	FALSE,  // 低电平触发
    	UP,		// 上升沿触发
    	DOWN,	// 下降沿触发
    	UPDOWN	// 跳变触发,即上升沿下降沿都触发
	};

	// ...

	// 设置一个错误检查动作,当出现2次上升沿,视为一次错误,执行报错提示。
	register_diag_action("ERROR_DETECTOR", [=](){
   
    	printf("find a error!\n");
	}, UP, 2);	

	// ...

	// 输送脉冲, 假设循环200次为一个脉冲周期
	// 如此,我们便可以将state认为是电平信号,进行监控了
	// 按照上面的设置,当出现从false变成true的时候,就会触发一次。
	while (1) {
   
		static int32_t count = 100;
		static bool state = false;
    	if (count == 0) {
   
        	count = 100;
        	state = !state;
    	}
    	count--;
    	if (count % 10 == 0)
        	DIRECT() << "fire_diag_condition "<< state;
    	Diagnose::fire_diag_condition("ERROR_DETECTOR", state);
    }

源码

// diagnose.hpp
#pragma once

#include <message/messager.hpp>
#include <regex>

enum TriggerType{
   
    TRUE,
    FALSE,
    UP,
    DOWN,
    UPDOWN
};

class Diagnose{
   
public:
    template<class T>
    static void register_diag_action(const std::string& name,
                              std::function<void(const T&)> func,
                              TriggerType trigger_type = TRUE, int trigger_times = 1){
   
        auto& trigger_times_map = get_trigger_times_map<T>();
        auto& condition_map = get_condition_map<T>();
        auto& last_condition_map = get_last_condition_map<T>();
        static int trigger_times_id = 0;
        trigger_times_id++;
        int trigger_times_id_captured = trigger_times_id;

        auto trigger_func = [=, &trigger_times_map](const T& data, bool is_change){
   
            auto& func_trigger_times = trigger_times_map[trigger_times_id_captured];
            if (is_change){
   
                func_trigger_times = 0;
            }
            if (++func_trigger_times >= trigger_times){
   
                func(data);
                func_trigger_times = 0;
            }
        };

        Messager::subcribe<bool, T>(name + "__diag", [=, &condition_map, &last_condition_map](bool condition, const T& data){
   

            auto& last_condition = condition_map[name];
            bool is_changed_true_false = last_condition ^ condition;
            bool has_last_last_condition = last_condition_map.find(name) != last_condition_map.end();
            bool is_changed_up_down = false;
            if (has_last_last_condition){
   
                is_changed_up_down = !last_condition_map[name] ^ last_condition;
            }

            switch (trigger_type) {
   
                case TRUE:
                    if (condition){
   
                        trigger_func(data, is_changed_true_false);
                    }
                    break;
                case FALSE:
                    if (!condition){
   
                        trigger_func(data, is_changed_true_false);
                    }
                    break;
                case UP:
                    if (!last_condition && condition){
   
                       trigger_func(data, is_changed_up_down);
                    }
                    break;
                case DOWN:
                    if (last_condition && !condition){
   
                        trigger_func(data, is_changed_up_down);
                    }
                    break;
                case UPDOWN:
                    if (last_condition ^ condition){
   
                        trigger_func(data, is_changed_up_down);
                    }
                    break;
                default:;
            }
        });
    }

    static void register_diag_action(const std::string& name,
                              std::function<void()> func,
                                     TriggerType trigger_type = TRUE, int trigger_times = 1){
   
        register_diag_action<bool>(name, [func](const bool&){
   
            func();
        }, trigger_type, trigger_times);
    }

    template<class T>
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值