增加数据操作接口IDataPort,弥补数据位钩子函数复杂的问题,测试通过
This commit is contained in:
parent
711d578e68
commit
4597004de1
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue