修正port轮询事件

This commit is contained in:
cdy 2017-02-11 16:54:29 +08:00
parent e598963980
commit 9aacf9d6e7
2 changed files with 99 additions and 91 deletions

View File

@ -13,10 +13,10 @@ static bool Port_Reserve(Pin pin, bool flag);
#ifdef REGION_Port #ifdef REGION_Port
Port::Port() Port::Port()
{ {
_Pin = P0; _Pin = P0;
Opened = false; Opened = false;
Index = 0; Index = 0;
State = nullptr; State = nullptr;
} }
#ifndef TINY #ifndef TINY
@ -28,15 +28,15 @@ Port::~Port()
String& Port::ToStr(String& str) const String& Port::ToStr(String& str) const
{ {
str += 'P'; str += 'P';
if(_Pin == P0) if (_Pin == P0)
{ {
str += '0'; str += '0';
} }
else else
{ {
str += (char)('A' + (_Pin >> 4)); str += (char)('A' + (_Pin >> 4));
str += (byte)(_Pin & 0x0F); str += (byte)(_Pin & 0x0F);
} }
return str; return str;
} }
@ -45,35 +45,35 @@ String& Port::ToStr(String& str) const
Port& Port::Set(Pin pin) Port& Port::Set(Pin pin)
{ {
// 如果引脚不变,则不做处理 // 如果引脚不变,则不做处理
if(pin == _Pin) return *this; if (pin == _Pin) return *this;
#ifndef TINY #ifndef TINY
// 释放已有引脚的保护 // 释放已有引脚的保护
if(_Pin != P0) Close(); if (_Pin != P0) Close();
#endif #endif
_Pin = pin; _Pin = pin;
return *this; return *this;
} }
bool Port::Empty() const bool Port::Empty() const
{ {
if(_Pin != P0) return false; if (_Pin != P0) return false;
return true; return true;
} }
void Port::Clear() void Port::Clear()
{ {
_Pin = P0; _Pin = P0;
} }
// 确定配置,确认用对象内部的参数进行初始化 // 确定配置,确认用对象内部的参数进行初始化
bool Port::Open() bool Port::Open()
{ {
if(_Pin == P0) return false; if (_Pin == P0) return false;
if(Opened) return true; if (Opened) return true;
TS("Port::Open"); TS("Port::Open");
@ -94,8 +94,8 @@ bool Port::Open()
void Port::Close() void Port::Close()
{ {
if(!Opened) return; if (!Opened) return;
if(_Pin == P0) return; if (_Pin == P0) return;
OnClose(); OnClose();
@ -123,36 +123,37 @@ WEAK void Port::AFConfig(GPIO_AF GPIO_AF) const {}
#if DEBUG #if DEBUG
// 引脚保留位,记录每个引脚是否已经被保留,禁止别的模块使用 // 引脚保留位,记录每个引脚是否已经被保留,禁止别的模块使用
// !!!注意不能全零否则可能会被当作zeroinit而不是copy导致得不到初始化 // !!!注意不能全零否则可能会被当作zeroinit而不是copy导致得不到初始化
static ushort Reserved[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF}; static ushort Reserved[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF };
// 保护引脚,别的功能要使用时将会报错。返回是否保护成功 // 保护引脚,别的功能要使用时将会报错。返回是否保护成功
bool Port_Reserve(Pin pin, bool flag) bool Port_Reserve(Pin pin, bool flag)
{ {
debug_printf("::"); debug_printf("::");
int port = pin >> 4, bit = 1 << (pin & 0x0F); int port = pin >> 4, bit = 1 << (pin & 0x0F);
if (flag) { if (flag) {
if (Reserved[port] & bit) { if (Reserved[port] & bit) {
// 增加针脚已经被保护的提示很多地方调用ReservePin而不写日志得到False后直接抛异常 // 增加针脚已经被保护的提示很多地方调用ReservePin而不写日志得到False后直接抛异常
debug_printf("P%c%d 已被打开", _PIN_NAME(pin)); debug_printf("P%c%d 已被打开", _PIN_NAME(pin));
return false; // already reserved return false; // already reserved
} }
Reserved[port] |= bit; Reserved[port] |= bit;
debug_printf("打开 P%c%d", _PIN_NAME(pin)); debug_printf("打开 P%c%d", _PIN_NAME(pin));
} else { }
Reserved[port] &= ~bit; else {
Reserved[port] &= ~bit;
debug_printf("关闭 P%c%d", _PIN_NAME(pin)); debug_printf("关闭 P%c%d", _PIN_NAME(pin));
} }
return true; return true;
} }
/*// 引脚是否被保护 /*// 引脚是否被保护
bool Port::IsBusy(Pin pin) bool Port::IsBusy(Pin pin)
{ {
int port = pin >> 4, sh = pin & 0x0F; int port = pin >> 4, sh = pin & 0x0F;
return (Reserved[port] >> sh) & 1; return (Reserved[port] >> sh) & 1;
}*/ }*/
#endif #endif
@ -166,11 +167,11 @@ OutputPort::OutputPort() : Port() { }
OutputPort::OutputPort(Pin pin) : OutputPort(pin, 2) { } OutputPort::OutputPort(Pin pin) : OutputPort(pin, 2) { }
OutputPort::OutputPort(Pin pin, byte invert, bool openDrain, byte speed) : Port() OutputPort::OutputPort(Pin pin, byte invert, bool openDrain, byte speed) : Port()
{ {
OpenDrain = openDrain; OpenDrain = openDrain;
Speed = speed; Speed = speed;
Invert = invert; Invert = invert;
if(pin != P0) if (pin != P0)
{ {
Set(pin); Set(pin);
Open(); Open();
@ -181,7 +182,7 @@ OutputPort& OutputPort::Init(Pin pin, bool invert)
{ {
Port::Set(pin); Port::Set(pin);
Invert = invert; Invert = invert;
return *this; return *this;
} }
@ -192,27 +193,27 @@ void OutputPort::OnOpen()
#if DEBUG #if DEBUG
debug_printf(" %dM", Speed); debug_printf(" %dM", Speed);
if(OpenDrain) if (OpenDrain)
debug_printf(" 开漏"); debug_printf(" 开漏");
else else
debug_printf(" 推挽"); debug_printf(" 推挽");
bool fg = false; bool fg = false;
#endif #endif
// 根据倒置情况来获取初始状态,自动判断是否倒置 // 根据倒置情况来获取初始状态,自动判断是否倒置
bool rs = Port::Read(); bool rs = Port::Read();
if(Invert > 1) if (Invert > 1)
{ {
Invert = rs; Invert = rs;
#if DEBUG #if DEBUG
fg = true; fg = true;
#endif #endif
} }
#if DEBUG #if DEBUG
if(Invert) if (Invert)
{ {
if(fg) if (fg)
debug_printf(" 自动倒置"); debug_printf(" 自动倒置");
else else
debug_printf(" 倒置"); debug_printf(" 倒置");
@ -230,41 +231,41 @@ void OutputPort::OnOpen()
WEAK bool OutputPort::ReadInput() const WEAK bool OutputPort::ReadInput() const
{ {
if(Empty()) return false; if (Empty()) return false;
return Port::Read() ^ Invert; return Port::Read() ^ Invert;
} }
void OutputPort::Up(uint ms) const void OutputPort::Up(uint ms) const
{ {
if(Empty()) return; if (Empty()) return;
Write(true); Write(true);
Sys.Sleep(ms); Sys.Sleep(ms);
Write(false); Write(false);
} }
void OutputPort::Down(uint ms) const void OutputPort::Down(uint ms) const
{ {
if(Empty()) return; if (Empty()) return;
Write(false); Write(false);
Sys.Sleep(ms); Sys.Sleep(ms);
Write(true); Write(true);
} }
void OutputPort::Blink(uint times, uint ms) const void OutputPort::Blink(uint times, uint ms) const
{ {
if(Empty()) return; if (Empty()) return;
bool flag = true; bool flag = true;
for(int i=0; i<times; i++) for (int i = 0; i < times; i++)
{ {
Write(flag); Write(flag);
flag = !flag; flag = !flag;
Sys.Sleep(ms); Sys.Sleep(ms);
} }
Write(false); Write(false);
} }
/******************************** AlternatePort ********************************/ /******************************** AlternatePort ********************************/
@ -272,7 +273,7 @@ void OutputPort::Blink(uint times, uint ms) const
AlternatePort::AlternatePort() : OutputPort(P0, false, false) { } AlternatePort::AlternatePort() : OutputPort(P0, false, false) { }
AlternatePort::AlternatePort(Pin pin) : OutputPort(P0, false, false) AlternatePort::AlternatePort(Pin pin) : OutputPort(P0, false, false)
{ {
if(pin != P0) if (pin != P0)
{ {
Set(pin); Set(pin);
Open(); Open();
@ -281,7 +282,7 @@ AlternatePort::AlternatePort(Pin pin) : OutputPort(P0, false, false)
AlternatePort::AlternatePort(Pin pin, byte invert, bool openDrain, byte speed) AlternatePort::AlternatePort(Pin pin, byte invert, bool openDrain, byte speed)
: OutputPort(P0, invert, openDrain, speed) : OutputPort(P0, invert, openDrain, speed)
{ {
if(pin != P0) if (pin != P0)
{ {
Set(pin); Set(pin);
Open(); Open();
@ -301,17 +302,17 @@ WEAK void AlternatePort::OpenPin() { OutputPort::OpenPin(); }
InputPort::InputPort() : InputPort(P0) { } InputPort::InputPort() : InputPort(P0) { }
InputPort::InputPort(Pin pin, bool floating, PuPd pull) : Port() InputPort::InputPort(Pin pin, bool floating, PuPd pull) : Port()
{ {
_task = 0; _task = 0;
//Handler = nullptr; //Handler = nullptr;
//Param = nullptr; //Param = nullptr;
_Value = 0; _Value = 0;
_Start = 0; _Start = 0;
PressTime = 0; PressTime = 0;
_Last = 0; _Last = 0;
if(pin != P0) if (pin != P0)
{ {
Set(pin); Set(pin);
Open(); Open();
@ -327,7 +328,7 @@ InputPort& InputPort::Init(Pin pin, bool invert)
{ {
Port::Set(pin); Port::Set(pin);
Invert = invert; Invert = invert;
return *this; return *this;
} }
@ -350,18 +351,18 @@ void InputPort::OnPress(bool down)
//if(down && _Value == Rising) return; //if(down && _Value == Rising) return;
//if(!down && _Value != Rising) return; //if(!down && _Value != Rising) return;
UInt64 now = Sys.Ms(); UInt64 now = Sys.Ms();
// 这一次触发离上一次太近,算作抖动忽略掉 // 这一次触发离上一次太近,算作抖动忽略掉
if(_Last > 0 && ShakeTime > 0 && ((Int64)now - (Int64)_Last) < ShakeTime) return; if (_Last > 0 && ShakeTime > 0 && ((Int64)now - (Int64)_Last) < ShakeTime) return;
_Last = now; _Last = now;
// 允许两个值并存 // 允许两个值并存
_Value = down ? Rising : Falling; _Value = down ? Rising : Falling;
if(down) if (down)
_Start = now; _Start = now;
else else
PressTime = now - _Start; PressTime = now - _Start;
/*if(down) /*if(down)
{ {
@ -372,7 +373,7 @@ void InputPort::OnPress(bool down)
if((Mode & Falling) == 0) return; if((Mode & Falling) == 0) return;
}*/ }*/
if(HardEvent || !_IRQ) if (HardEvent || !_IRQ)
Press(*this, down); Press(*this, down);
else else
Sys.SetTask(_task, true, 0); Sys.SetTask(_task, true, 0);
@ -380,19 +381,23 @@ void InputPort::OnPress(bool down)
void InputPort::InputTask(void* param) void InputPort::InputTask(void* param)
{ {
auto port = (InputPort*)param; auto port = (InputPort*)param;
byte v = port->_Value; byte v = port->_Value;
if(!v) return; if (!v) return;
//v &= port->Mode; //v &= port->Mode;
if(v & Rising) port->Press(*port, true); if (v & Rising) port->Press(*port, true);
if(v & Falling) port->Press(*port, false); if (v & Falling) port->Press(*port, false);
} }
static void InputNoIRQTask(void* param) void InputPort::InputNoIRQTask(void* param)
{ {
auto port = (InputPort*)param; auto port = (InputPort*)param;
port->OnPress(port->Read()); auto val = port->Read();
if (val == port->Val) return;
port->Val = val;
port->OnPress(val);
} }
void InputPort::OnOpen() void InputPort::OnOpen()
@ -400,19 +405,19 @@ void InputPort::OnOpen()
TS("InputPort::OnOpen"); TS("InputPort::OnOpen");
// 如果不是硬件事件则默认使用20ms抖动 // 如果不是硬件事件则默认使用20ms抖动
if(!HardEvent && ShakeTime == 0) ShakeTime = 20; if (!HardEvent && ShakeTime == 0) ShakeTime = 20;
#if DEBUG #if DEBUG
debug_printf(" 抖动=%dms", ShakeTime); debug_printf(" 抖动=%dms", ShakeTime);
if(Floating) if (Floating)
debug_printf(" 浮空"); debug_printf(" 浮空");
else if(Pull == UP) else if (Pull == UP)
debug_printf(" 上升沿"); debug_printf(" 上升沿");
else if(Pull == DOWN) else if (Pull == DOWN)
debug_printf(" 下降沿"); debug_printf(" 下降沿");
//if(Mode & Rising) debug_printf(" 按下"); //if(Mode & Rising) debug_printf(" 按下");
//if(Mode & Falling) debug_printf(" 弹起"); //if(Mode & Falling) debug_printf(" 弹起");
bool fg = false; bool fg = false;
#endif #endif
Port::OnOpen(); Port::OnOpen();
@ -420,18 +425,18 @@ void InputPort::OnOpen()
// 根据倒置情况来获取初始状态,自动判断是否倒置 // 根据倒置情况来获取初始状态,自动判断是否倒置
bool rs = Port::Read(); bool rs = Port::Read();
if(Invert > 1) if (Invert > 1)
{ {
Invert = rs; Invert = rs;
#if DEBUG #if DEBUG
fg = true; fg = true;
#endif #endif
} }
#if DEBUG #if DEBUG
if(Invert) if (Invert)
{ {
if(fg) if (fg)
debug_printf(" 自动倒置"); debug_printf(" 自动倒置");
else else
debug_printf(" 倒置"); debug_printf(" 倒置");
@ -451,21 +456,21 @@ void InputPort::OnClose()
} }
// 输入轮询时间间隔。默认100ms允许外部修改 // 输入轮询时间间隔。默认100ms允许外部修改
uint InputPort_Polling = 100; uint InputPort_Polling = 100;
bool InputPort::UsePress() bool InputPort::UsePress()
{ {
assert(_Pin != P0, "输入注册必须先设置引脚"); assert(_Pin != P0, "输入注册必须先设置引脚");
_IRQ = OnRegister(); _IRQ = OnRegister();
if (!_task && !HardEvent) if (!_task && !HardEvent)
{ {
// 如果硬件中断注册失败则采用10ms定时读取 // 如果硬件中断注册失败则采用10ms定时读取
if(_IRQ) if (_IRQ)
_task = Sys.AddTask(InputTask, this, -1, -1, "输入事件"); _task = Sys.AddTask(InputTask, this, -1, -1, "输入事件");
else else
_task = Sys.AddTask(InputNoIRQTask, this, InputPort_Polling, InputPort_Polling, "输入轮询"); _task = Sys.AddTask(InputNoIRQTask, this, InputPort_Polling, InputPort_Polling, "输入轮询");
} }
return true; return true;

View File

@ -184,16 +184,19 @@ protected:
private: private:
bool _IRQ = false; bool _IRQ = false;
byte _Value = 0; // 当前值
uint _task = 0; // 输入任务 uint _task = 0; // 输入任务
UInt64 _Start = 0; // 开始按下时间 UInt64 _Start = 0; // 开始按下时间
UInt64 _Last = 0; // 最后一次触发时间 UInt64 _Last = 0; // 最后一次触发时间
static void InputTask(void* param); static void InputTask(void* param);
static void InputNoIRQTask(void* param);
private: private:
void OpenPin(); void OpenPin();
void ClosePin(); void ClosePin();
bool OnRegister(); bool OnRegister();
byte _Value = 0; // 当前值
bool Val = false;
}; };
/******************************** AnalogInPort ********************************/ /******************************** AnalogInPort ********************************/