增加数据操作接口IDataPort,弥补数据位钩子函数复杂的问题,测试通过

This commit is contained in:
nnhy 2015-09-22 03:29:03 +00:00
parent 711d578e68
commit 4597004de1
4 changed files with 173 additions and 25 deletions

View File

@ -1,5 +1,12 @@
#include "Button_GrayLevel.h"
#include "Button_GrayLevel.h"
#define BTN_DEBUG DEBUG
//#define BTN_DEBUG 0
#if BTN_DEBUG
#define btn_printf debug_printf
#else
#define btn_printf(format, ...)
#endif
InputPort* Button_GrayLevel::ACZero = NULL;
byte Button_GrayLevel::OnGrayLevel = 0xff; // 开灯时 led 灰度
@ -8,7 +15,9 @@ int Button_GrayLevel::ACZeroAdjTime=2300;
Button_GrayLevel::Button_GrayLevel()
{
#if DEBUG
Name = NULL;
#endif
Index = 0;
_Value = false;
@ -17,6 +26,9 @@ Button_GrayLevel::Button_GrayLevel()
_Handler = NULL;
_Param = NULL;
_tid = 0;
Next = 0xFF;
}
Button_GrayLevel::~Button_GrayLevel()
@ -95,6 +107,95 @@ void Button_GrayLevel::Register(EventHandler handler, void* param)
}
}
int Button_GrayLevel::Size() const { return 1; }
int Button_GrayLevel::Write(byte* data)
{
byte cmd = *data;
if(cmd == 0xFF) return Read(data);
btn_printf("控制0x%02X ", cmd);
switch(cmd)
{
case 1:
btn_printf("打开");
SetValue(true);
break;
case 0:
btn_printf("关闭");
SetValue(false);
break;
case 2:
btn_printf("反转");
SetValue(!GetValue());
break;
default:
break;
}
switch(cmd>>4)
{
// 普通指令
case 0:
// 关闭所有带有延迟效果的指令
Next = 0xFF;
break;
// 开关闪烁
case 1:
btn_printf("闪烁%d", cmd - 0x10);
SetValue(!GetValue());
Next = cmd;
StartAsync(cmd - 0x10);
break;
// 打开,延迟一段时间后关闭
case 2:
case 3:
case 4:
case 5:
btn_printf("延迟%d关闭", cmd - 0x20);
SetValue(true);
Next = 0;
StartAsync(cmd - 0x20);
break;
// 关闭,延迟一段时间后打开
case 6:
case 7:
case 8:
case 9:
btn_printf("延迟%d打开", cmd - 0x60);
SetValue(false);
Next = 1;
StartAsync(cmd - 0x60);
break;
}
#if DEBUG
//Name.Show(true);
btn_printf(" %s\r\n", Name);
#endif
return Read(data);
}
int Button_GrayLevel::Read(byte* data)
{
*data = _Value ? 1 : 0;
return 1;
}
static void CommandTask(void* param)
{
Button_GrayLevel* btn = (Button_GrayLevel*)param;
byte cmd = btn->Next;
//btn_printf("Next=%d \r\n", cmd);
if(cmd != 0xFF) btn->Write(&cmd);
}
void Button_GrayLevel::StartAsync(int second)
{
if(!_tid) _tid = Sys.AddTask(CommandTask, this, -1, -1, "定时开关");
Sys.SetTask(_tid, true, second * 1000000);
}
bool Button_GrayLevel::GetValue() { return _Value; }
bool CheckZero(InputPort* port)

View File

@ -1,14 +1,16 @@
#ifndef __BUTTON_GRAY_LEVEL_H__
#ifndef __BUTTON_GRAY_LEVEL_H__
#define __BUTTON_GRAY_LEVEL_H__
#include "Sys.h"
#include "Port.h"
#include "Timer.h"
#include "Message\DataStore.h"
// 面板按钮
// 这里必须使用_packed关键字生成对齐的代码否则_Value只占一个字节导致后面的成员进行内存操作时错乱
//__packed class Button
// 干脆把_Value挪到最后解决问题
class Button_GrayLevel
class Button_GrayLevel : public IDataPort
{
private:
static void OnPress(Pin pin, bool down, void* param);
@ -26,7 +28,9 @@ private:
public:
int Index; // 索引号,方便在众多按钮中标识按钮
#if DEBUG
string Name; // 按钮名称
#endif
InputPort Key; // 输入按键
OutputPort Relay; // 继电器
@ -47,6 +51,14 @@ public:
void RenewGrayLevel();
void Register(EventHandler handler, void* param = NULL);
virtual int Size() const;
virtual int Write(byte* data);
virtual int Read(byte* data);
byte Next; // 开关延迟后的下一个状态
uint _tid;
void StartAsync(int second);
// 过零检测
private:
static int ACZeroAdjTime; // 过零检测时间补偿 默认 2300
@ -56,7 +68,6 @@ public:
static bool SetACZeroPin(Pin aczero); // 设置过零检测引脚
static void SetACZeroAdjTime(int us){ ACZeroAdjTime = us; }; // 设置 过零检测补偿时间
};
#endif

View File

@ -1,7 +1,7 @@
#include "DataStore.h"
// 初始化
DataStore::DataStore()
DataStore::DataStore() : Areas(0)
{
Strict = true;
}
@ -45,11 +45,23 @@ int DataStore::Read(uint offset, ByteArray& bs)
bool DataStore::OnHook(uint offset, uint size, int mode)
{
for(int i=0; i<ArrayLength(Areas); i++)
for(int i=0; i<Areas.Length(); i++)
{
Area& ar = Areas[i];
if(ar.Offset == 0 && ar.Size == 0) break;
if(ar.Size == 0) break;
// 数据操作口只认可完整的当前区域
if(ar.Port && offset <= ar.Offset && offset + size >= ar.Offset + ar.Size)
{
if(mode == 1)
{
if(ar.Port->Write(&Data[ar.Offset]) <= 0) return false;
}
else if(mode == 0 || mode == 2)
{
if(ar.Port->Read(&Data[ar.Offset]) <= 0) return false;
}
}
if(ar.Hook && ar.Contain(offset, size))
{
if(!ar.Hook(offset, size, mode)) return false;
@ -66,20 +78,31 @@ bool DataStore::OnHook(uint offset, uint size, int mode)
void DataStore::Register(uint offset, uint size, Handler hook)
{
// 找一个空位
int i=0;
/*int i=0;
for(i=0; i<ArrayLength(Areas); i++)
{
if(Areas[i].Offset == 0 && Areas[i].Size == 0) break;
if(Areas[i].Size == 0) break;
}
if(i >= ArrayLength(Areas))
{
debug_printf("数据存储区的读写钩子函数已满\r\n");
return;
}
}*/
Areas[i].Offset = offset;
Areas[i].Size = size;
Areas[i].Hook = hook;
Area& ar = Areas.Push();
ar.Offset = offset;
ar.Size = size;
ar.Hook = hook;
}
void DataStore::Register(uint offset, IDataPort& port)
{
Area& ar = Areas.Push();
ar.Offset = offset;
ar.Size = port.Size();
ar.Port = &port;
}
DataStore::Area::Area()

View File

@ -4,6 +4,8 @@
#include "Sys.h"
#include "Stream.h"
class IDataPort;
// 数据存储适配器
class DataStore
{
@ -22,6 +24,7 @@ public:
typedef bool (*Handler)(uint offset, uint size, int mode);
// 注册某一块区域的读写钩子函数
void Register(uint offset, uint size, Handler hook);
void Register(uint offset, IDataPort& port);
private:
class Area
@ -31,14 +34,24 @@ private:
uint Size;
Handler Hook;
IDataPort* Port;
Area();
bool Contain(uint offset, uint size);
};
Area Areas[0x10];
Array<Area, 0x08> Areas;
bool OnHook(uint offset, uint size, int mode);
};
// 数据操作接口。提供字节数据的读写能力
class IDataPort
{
public:
virtual int Size() const = 0;
virtual int Write(byte* data) = 0;
virtual int Read(byte* data) = 0;
};
#endif