93 lines
1.8 KiB
C++
93 lines
1.8 KiB
C++
#include "Kernel\Sys.h"
|
|
#include "Device\Port.h"
|
|
|
|
#include "PulsePort.h"
|
|
|
|
PulsePort::PulsePort()
|
|
{
|
|
Port = nullptr;
|
|
Min = 0;
|
|
Max = 0;
|
|
Last = 0;
|
|
Time = 0; // 遮挡时间
|
|
Count = 0; // 触发次数
|
|
_task = 0;
|
|
}
|
|
|
|
PulsePort::~PulsePort()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
static void OnPressTask(void* param)
|
|
{
|
|
auto port = (PulsePort*)param;
|
|
port->Press(*port);
|
|
}
|
|
|
|
void PulsePort::Open()
|
|
{
|
|
if (Opened) return;
|
|
|
|
if (!Port) return;
|
|
|
|
// 如果使用了硬件事件,则这里使用任务来触发外部事件
|
|
if (Port->HardEvent) _task = Sys.AddTask(OnPressTask, this, -1, -1, "脉冲事件");
|
|
|
|
Port->HardEvent = true;
|
|
Port->Press.Bind(&PulsePort::OnPress, this);
|
|
Port->UsePress();
|
|
Port->Open();
|
|
|
|
Opened = true;
|
|
}
|
|
|
|
void PulsePort::Close()
|
|
{
|
|
if (!Opened) return;
|
|
|
|
Sys.RemoveTask(_task);
|
|
Port->Close();
|
|
|
|
Opened = false;
|
|
}
|
|
|
|
void PulsePort::OnPress(InputPort& port, bool down)
|
|
{
|
|
// 只有弹起来才计算
|
|
if (down) return;
|
|
|
|
// 首次触发不算遮挡时间
|
|
UInt64 now = Sys.Ms();
|
|
if (Last == 0)
|
|
{
|
|
Last = now;
|
|
return;
|
|
}
|
|
// 计算上一次脉冲以来的遮挡时间,两个有效脉冲的间隔
|
|
auto st = Last;
|
|
uint time = 0;
|
|
|
|
//过滤形状的光栅需要两个信号的时间差
|
|
if (Filter)
|
|
time = (uint)(now - st);
|
|
else
|
|
time = port.PressTime;
|
|
// 无论如何都更新最后一次时间,避免连续超长
|
|
Last = now;
|
|
// 两次脉冲的间隔必须在一个范围内才算作有效
|
|
if ((Min > 0 && time < Min) || (Max > 0 && time > Max)) return;
|
|
|
|
Start = now;
|
|
Time = time;
|
|
Count++;
|
|
if (time > 100)
|
|
{
|
|
debug_printf(" time %d, Port %02X Last=%d Count=%d\r\n", time, Port->_Pin, (int)Last, Count);
|
|
}
|
|
if (_task > 0)
|
|
Sys.SetTask(_task, true, 0);
|
|
else
|
|
Press(*this);
|
|
}
|