一些项目需要一个微控制器来监控一组机械触点。这些触点可以是一个简单的开关、按钮或一组机械继电器触点。监测这些机械接口的问题在于它们往往非常嘈杂。图1示出了典型的机械接触界面以及接触闭合信号。



图1。产生电信号的机械接触接口

图1还显示了最初的电接触,然后是更大的“反弹”。这种反弹之后是脉冲的“喷射”,也称为接触颤振。为了可靠地检测机械接触状态,我们必须找到一种方法,将弹跳和颤动过滤成干净可靠的信号。

硬件解决方案
在我们继续讨论固件实现之前,至少提到一些解决触点闭合接口问题的硬件方法是有益的。所有的硬件实现通常都涉及某种级别的过滤或状态机/计数器。有一些现成的集成电路可以很好地消除机械输入的抖动。

马克西姆MAX6818:最初,Maxim似乎创建了去抖动电路,为微控制器应用程序提供手动复位按钮接口。然而,MAX6818有点贵。该设备的单个数量成本约为7.00美元,可更换八(8)个接触通道。MAX6818 debuncert IC的URL可在以下网站上找到:

www.maximitegrated.com/datasheet/index.mvp/id/1896t/al

ON半导体MC14490:ON Semiconductor制造六(6)通道开关去不确定性。这个部件最初是由摩托罗拉的IC部门在多年前制造的。我可以说,从个人经验来看,这个IC工作得非常好。它也可以被重新调整为一条漂亮的单比特延迟线。MC14490的单台成本约为3.20美元左右。这对于六通道部件来说还不错。MC14490 IC的URL如下所示:

www.onsemi.com/pub_link/Corteral/MC14490-D.PDF

离散解决方案
当然,总是有离散的硬件解决方案。此接口的硬件实现如所示图2:.

图2:以离散方式取消开关

在这种情况下,去抖动滤波器是与施密特触发器耦合的RC网络。高到低转换的RC时间常数为10毫秒。低到高转换的RC时间常数约为13毫秒。单极过滤和施密特触发器通常为触点闭合输入提供足够的过滤。当然,可以改变电容器或电阻器的值来增加或减少时间延迟和滤波。

图中所示电路的成本图2:主要与离散组件有关。这是因为74CH14施密特触发器的成本约为0.14美元。部件成本使得这成为一种非常有吸引力的解决方案,用于解除接触闭合输入的抖动。

离散解决方案的缺点是每个通道去抖动所需的部件数量。例如,如果您需要对六个通道进行去抖动,那么您只需要一个74HC14 IC。然而,您需要六(6)倍的分立部件(电阻器、电容器和二极管)。

成本汇总
表1显示每个硬件解决方案的成本摘要。集成解决方案的每个通道的粗略成本大约在每个通道0.50美元到0.88美元之间。离散解决方案的每个通道的粗略成本大约在每个通道0.12美元的范围内。

表1。每个硬件触点闭合接口解决方案的成本和说明摘要

离散解决方案显然是成本赢家。然而,当需要大量信道时,这可能是不合适的。这是由于需要大量的零件来影响离散解决方案。

钻头砰砰作响
硬件接口:当然,这是嵌入式圆桌会议,我们需要提出一种使用某种类型的固件技术来解除接口抖动的方法。软件去抖动接口的硬件实现如所示图3.

图3。将触点闭合输入接口连接到微控制器

图3示出了触点闭合件和微控制器端口引脚之间的几乎直接的接口。当然,我们增加了一个1千欧姆的缓冲电阻器和一些保护二极管来保护微控制器端口。可以看出,这种直接接口只需要很少的部件,而且在商品成本上也很容易(每个通道大约0.03到0.08美元)。

同样重要的是要注意,不应该进行直接接口,如中所示图3到内部中断。不将直接接口连接到中断的原因是,我们事先不知道聊天的速度有多快。它可以是微秒到毫秒,完全不可预测。简单地将触点闭合输入路由到端口引脚并使用定时器中断对其进行采样要好得多。

软件架构:直接滤波开关输入的方法是基于移位寄存器(单比特延迟线)和比较器。此架构显示在图4.

图4。用于断开触点闭合输入的软件控制方案

图4显示了通过计时器服务监视的1和0的序列。然后将该采样数据移位到移位寄存器中,并将所得的移位值与比较器值进行比较。如果比较器值为全1或全0,则输出状态将相应地变为1或0。如果比较值与全1或全零序列不匹配,比较器的输出将保持最后状态。

软件debuncert
属性和方法:和往常一样,手头的第一个任务将是定义switch-debuuncer接口文件。和往常一样,这是以C头文件的形式出现的。在这里,我们定义了主接口对象以及设置和控制设备控制块(DCB)。清单1显示了我们的防反弹控制接口的头文件。

清单1。触点闭合控制器驱动程序和接口

结构dbSwS;/*主对象*/typedef int的前向引用(*DBSW_hwGetF)(结构体dbSwS*);/*硬件获取*/**************************************************************//*交换机去不确定性设备控制块*/**********************************************/typedef struct dbSw_dcbS{int m_id;/*某些唯一句柄*/int m_defaultState;/*开关NO/NC状态*/unsigned int m_filtMask;/*过滤器/debounce掩码*/DBSW_hwGetF sw_readF;/*读取硬件函数*/}DBSW_dcbS;/******************************************************//*开关debuncert控制对象*/******************************************************/typedef struct dbSwS{dbSw_dcbS dcb;/*生成此*/unsigned int m_filter的dcb副本;/*开关筛选器字*/int m_state;/*当前开关状态*/}dbSwS#ifdef __cplusplus extern“C”{#endif void dbSwS_init(dbSwS*_this,const dbSw_dcbS*dcb);void dbSwS_update(dbSwS*_thiss);int dbSwS_hwRead(dbSwS*_thise);int dbSwS_stateGet(const dbSwS*_thes);#ifdef

设备控制块(DCB)
接口设备控制块由四(4)个字段组成。以下是对每个字段及其使用方式的简要描述。

整数m_id
这是一些唯一的整数标识符。在某些情况下,我们可能希望通过某种独特的句柄来识别对象。此字段表示对象ID或句柄的占位符。

int默认状态(m_)
这是触点未激活时的“正常”状态。一般来说,由于大多数触点处于低激活状态,因此此状态的值将为逻辑高或一(1)。然而,在某些情况下,情况并非如此(正逻辑),并且非活动状态将为逻辑低或零(0)。

无符号整数m_filtMask
此字段表示延迟线或移位寄存器内的位数。对于定义的每个比特,我们需要设置一个一(1)。例如,四(4)位移位寄存器将由滤波器掩码值0xF表示。八位移位寄存器将由0xFF的滤波器掩码值表示。

数据库sw_hwGetF sw_readF
此字段表示低级PORT读取函数指针。将PORT读取接口实现为函数指针。这允许我们将依赖硬件的实现定义为初始化过程的一部分。这样做使我们能够使驱动程序独立于硬件实现。

去不确定性控制对象
这是流程受到影响的对象。这个对象中总共有三个字段。以下是控制对象中字段的简要说明。

数据库开关_dcbS数据库
这是设备控制块(DCB),用于放置去抖动控制器的设置和配置信息。上一节中描述的DCP。

无符号整数m_filter
这是主延迟线。对于32位处理器,此字段将为32位宽。因此,最大移位器长度将是32位。换档器的实际大小由m_过滤任务如DCB部分所述的值。

整数m_state
这是当前的后过滤状态。通常,此状态可以具有一(1)或零(0)的值。该值表示过滤后的、去抖动的接触状态。

驱动程序方法
开关去不确定性总共有四种方法。中简要介绍了驱动程序的方法表2.

表2。开关去不确定性方法说明

数据库SwS_udpate
通常情况下,debuncert开关更新方法将由某些周期性定时器服务调用。这个方法是所有过滤和模式实现的地方。清单2显示了更新过滤模式的实现。

清单2。交换机去不确定性模式的实现

void dbSwS_update(dbSwS*_this){int my_swResult=dbSwS_hwRead(_this){_this->m_state=0;}}

应用
我已经包含了一个演示如何使用这个驱动程序的应用程序。该应用程序适用于四(4)位操纵杆和一个ENTER(输入)按钮。应用程序的主要接口列在数据库Sw_mgr.h头文件。清单3显示了基本操纵杆应用程序的头文件。

#include“dbSw_driver.h”/**************************************************************//*操纵手柄有五(5)种不同的开关状态#define STICKF_UP 0x00000001#define STICK F_RIGHT 0x00000002#define STICK_F_DOWN 0x00000004#define TICK_F_LEFT 0x00000008#define StickF_ENTER 0x00000010 typedef enum swidE{SWID_UP=0,SWID_RIGHT=1,SWID_DOWN=2,SWID_LEFT=3,SWID_ENTER=4,SWID_MAX}swidE;/**************************************************************//*以下是应用程序回调的函数类型。此*//*回调在以下过程中调用:*//*/*1。检测到任何状态变化*//*2。回调函数指针不为NULL*/*/*此函数的原型如下:*/*/*void my_Callback_fn(const unsigned curr,const unsunsigned prev);*//*/*其中:*//*无符号curr;'当前开关状态'*//*unsigned prev;'上一个开关状态'*/**//*注意:*//**//*回调函数是在中断上下文中调用的!!!*/**//***********************************typedef void(*DBSWMGR_callback)(无符号常量,无符号常量);/**************************************************************//*以下是应用程序特定的数据库开关控制器对象*/**************************************************************/typedef结构dbSwMgr_ctlS{unsigned d_mask;/*一些开关位掩码*/dbSwS m_sw;/*单个开关元素*/}dbSwMgr_ctlS;/***************************以下是主交换机管理器/debouncert容器*/**************************************************************/typedef struct dbSwMgrS{int m_id;/*某些唯一标识符*/DBSWMGR_callback fn_callback;/*应用程序特定回调函数*/DBSWMGR_ctlS ctl[SWID_MAX];/*五(5)个交换机控制元素*/unsigned int m_state;/*当前位状态*/}数据库软件管理器#ifdef __cplusplus extern“C”{#endif dbSwMgrS*dbSwMgr_getInstance(void);void dbSwMgr_init(dbSwMgr_callback callback_fn);void dbSwMgr_updateISR(void));unsigned dbSwMgr_stateGet(void); /************************************************************************/ /* 以下内容必须由开发人员提供*/****************************************************/void dbSwMgr_myCallbackFn(const unsigned curr,const unsunsigned prev)#ifdef__cplusplus}#endif

在这种情况下,USER想要一个回调,该回调在检测到成功的状态更改后执行。此人并不介意在中断上下文中调用callback。此回调在操纵杆界面的先前状态和当前状态中传递。回调由fn_callback字段数据库软件管理器记录

初始化受到中的代码的影响数据库软件管理器_信息.c文件打开此文件,您将看到一个宏:

#定义DBSW_HIT_MASK 0x0000000F

此宏将移位寄存器的长度指定为四(4)位。当然,您可以将移位寄存器大小增加到32位以内的任何长度。例如,如果您希望有一个六(6)位延迟线,那么您应该按如下方式重新定义此宏:

#定义DBSW_HIT_MASK 0x0000003F

此外数据库软件管理器_信息.c文件的低级别PORT读取接口已被清除。您需要将代码添加到这些接口中,以使其在应用程序中工作。由于我不知道实际的硬件会是什么,我已经把这些接口去掉了。

那么,如何过滤联系人闭合输入呢?您是否使用完整的硬件解决方案?您是否使用仅限固件的解决方案?或者,你的解决方案是两者的混合?我在这里展示了移位寄存器/软件单比特延迟线的方法。我见过其他使用计数器的方法。在我看来,反制方法同样有效。

肯·瓦达是AuriumTechnologies的总裁和所有者,AuriumTechnology是一家位于加州硅谷的独立产品设计和咨询公司。Ken拥有超过25年的高科技产品和系统的架构和设计经验,包括用于收费公路和桥梁的ASTRAK车辆传感系统。他的专业包括工业自动化、生物技术和高速光网络。Ken拥有四项专利。你可以在联系他。