增加交流电过零检测专属类

This commit is contained in:
大石头X2 2017-02-28 22:08:46 +08:00
parent f0f9ce8491
commit 4ef42d15a4
5 changed files with 127 additions and 9 deletions

95
App/ACZero.cpp Normal file
View File

@ -0,0 +1,95 @@
#include "Kernel\Sys.h"
#include "Device\Port.h"
#include "ACZero.h"
static void ACZeroTask(void *param);
ACZero::ACZero()
{
Time = 0;
AdjustTime = 2;
_taskid = 0;
}
ACZero::~ACZero()
{
if (Port.Opened) Close();
Sys.RemoveTask(_taskid);
}
void ACZero::Set(Pin pin)
{
if (pin == P0) return;
Port.Set(pin);
}
void ACZeroTask(void *param)
{
auto port = (ACZero*)param;
if (port)
{
debug_printf("定时检查交流电过零\r\n");
// 需要检测是否有交流电,否则关闭
port->Check();
}
}
bool ACZero::Open()
{
if (!Port.Open()) return false;
debug_printf("过零检测引脚探测: ");
if (Check())
{
debug_printf("已连接交流电!\r\n");
}
else
{
debug_printf("未连接交流电!\r\n");
Port.Close();
return false;
}
_taskid = Sys.AddTask(ACZeroTask, this, 1000, 10000, "过零检测");
return true;
}
void ACZero::Close()
{
Port.Close();
}
bool ACZero::Check()
{
// 检测下降沿 先去掉低电平 whileio==false
int retry = 200;
while (Port == false && retry-- > 0) Sys.Delay(100);
if (retry <= 0) return false;
// 喂狗
Sys.Sleep(1);
// 当检测到 高电平结束 就是下降沿的到来
retry = 200;
while (Port == true && retry-- > 0) Sys.Delay(100);
if (retry <= 0) return false;
// 计算10ms为基数的当前延迟
int ms = (int)(Sys.Ms() / 10);
// 折算为需要等待的时间
ms = 10 - ms;
// 加上对齐纠正时间
ms += AdjustTime;
ms %= 10;
// 计算加权平均数
Time = (Time + ms) / 2;
return true;
}

27
App/ACZero.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __ACZero_H__
#define __ACZero_H__
#include "Device\Port.h"
// 交流过零检测
class ACZero
{
public:
InputPort Port; // 交流过零检测引脚
int Time; // 10ms为基数的零点延迟时间。应用层需要等待该时间才能等到下一个零点
int AdjustTime; // 过零检测时间补偿。默认2ms
ACZero();
~ACZero();
void Set(Pin pin);
bool Open();
void Close();
bool Check();
private:
uint _taskid;
};
#endif

View File

@ -6,17 +6,11 @@
#include "Message\DataStore.h"
// 面板按钮
// 这里必须使用_packed关键字生成对齐的代码否则_Value只占一个字节导致后面的成员进行内存操作时错乱
//__packed class Button
// 干脆把_Value挪到最后解决问题
class Button : public ByteDataPort
{
private:
//static void OnPress(InputPort* port, bool down, void* param);
void OnPress(InputPort& port, bool down);
//EventHandler _Handler;
//void* _Param;
public:
cstring Name; // 按钮名称
int Index; // 索引号,方便在众多按钮中标识按钮
@ -37,8 +31,6 @@ public:
bool GetValue();
void SetValue(bool value);
//void Register(EventHandler handler, void* param = nullptr);
virtual int OnWrite(byte data);
virtual byte OnRead();

View File

@ -11,6 +11,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\App\ACZero.cpp" />
<ClCompile Include="..\App\Alarm.cpp" />
<ClCompile Include="..\App\BlinkPort.cpp" />
<ClCompile Include="..\App\Button.cpp" />

View File

@ -542,5 +542,8 @@
<ClCompile Include="..\Net\HttpClient.cpp">
<Filter>Net</Filter>
</ClCompile>
<ClCompile Include="..\App\ACZero.cpp">
<Filter>App</Filter>
</ClCompile>
</ItemGroup>
</Project>