我想检测串口引脚上是否有触发信号,应该是这样的吧:4(DTR)配1(DCD)、6(DSR)、8(CTS)。
可是无论我怎么操作,GetCommModemStatus返回的状态都是0。困扰好多天了,请哪位大虾帮忙分析一下。多谢了!以下是代码://开始监控
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex < 0) return; try
{
comPort = comboBox1.SelectedItem.ToString(); comm_handle = CreateFile(comPort, FileAccess.ReadWrite, FileShare.None, 0, FileMode.Open, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
if (comm_handle.Equals(INVALID_HANDLE_VALUE)) return; SpThread = new Thread(SPortThreadExecute);
SpThread.Start(); AddNewLine("串口 " + comPort + " 打开成功!"); comboBox1.Enabled = false;
button1.Enabled = false;
button2.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}//停止监控
private void button2_Click(object sender, EventArgs e)
{
try
{
if (!comm_handle.Equals(INVALID_HANDLE_VALUE)) CloseHandle(comm_handle); while ((SpThread != null) && SpThread.IsAlive)
{
SpThread.Abort();
Thread.Sleep(100);
} AddNewLine("串口 " + comPort + " 关闭成功!"); comboBox1.Enabled = true;
button1.Enabled = true;
button2.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}//监控线程
private void SPortThreadExecute()
{
OVERLAPPED m_ov = new OVERLAPPED();
m_ov.hEvent = CreateEvent(IntPtr.Zero, true, false, null); if (m_ov.hEvent > 0)
{
bool bSuccess = SetCommMask(comm_handle, EV_CTS | EV_DSR | EV_RLSD);
if (!bSuccess)
{
MessageBox.Show("SetCommMask 出错!");
CloseHandle(m_ov.hEvent);
return;
} while (true)
{
uint dwEventMask = 0;
bSuccess = WaitCommEvent(comm_handle, ref dwEventMask, ref m_ov);
if (!bSuccess)
{
int errorCode = GetLastError();
if (errorCode != ERROR_IO_PENDING)
{
continue;
}
} //重叠 I/O 操作正在进行中,可以继续做
uint Event = WaitForSingleObject(m_ov.hEvent, Timeout.Infinite);
if (Event == WAIT_OBJECT_0)
{
uint BytesLen = 0;
if (!GetOverlappedResult(comm_handle, ref m_ov, ref BytesLen, false))
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult return false. " });
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult successfully, " + BytesLen.ToString() + " bytes read. " }); uint dwModemStatus = 0;
if (GetCommModemStatus(comm_handle, ref dwModemStatus))
{
if ((dwModemStatus & MS_CTS_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_CTS_ON is be detected" }); } if ((dwModemStatus & MS_DSR_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_DSR_ON is be detected" }); } if ((dwModemStatus & MS_RLSD_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_RLSD_ON is be detected" }); } this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return true. Status = " + dwModemStatus.ToString() + ", Now time is " + DateTime.Now.ToString() });
}
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return false. " });
} ResetEvent(m_ov.hEvent); } //end while
}
}
可是无论我怎么操作,GetCommModemStatus返回的状态都是0。困扰好多天了,请哪位大虾帮忙分析一下。多谢了!以下是代码://开始监控
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex < 0) return; try
{
comPort = comboBox1.SelectedItem.ToString(); comm_handle = CreateFile(comPort, FileAccess.ReadWrite, FileShare.None, 0, FileMode.Open, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
if (comm_handle.Equals(INVALID_HANDLE_VALUE)) return; SpThread = new Thread(SPortThreadExecute);
SpThread.Start(); AddNewLine("串口 " + comPort + " 打开成功!"); comboBox1.Enabled = false;
button1.Enabled = false;
button2.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}//停止监控
private void button2_Click(object sender, EventArgs e)
{
try
{
if (!comm_handle.Equals(INVALID_HANDLE_VALUE)) CloseHandle(comm_handle); while ((SpThread != null) && SpThread.IsAlive)
{
SpThread.Abort();
Thread.Sleep(100);
} AddNewLine("串口 " + comPort + " 关闭成功!"); comboBox1.Enabled = true;
button1.Enabled = true;
button2.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}//监控线程
private void SPortThreadExecute()
{
OVERLAPPED m_ov = new OVERLAPPED();
m_ov.hEvent = CreateEvent(IntPtr.Zero, true, false, null); if (m_ov.hEvent > 0)
{
bool bSuccess = SetCommMask(comm_handle, EV_CTS | EV_DSR | EV_RLSD);
if (!bSuccess)
{
MessageBox.Show("SetCommMask 出错!");
CloseHandle(m_ov.hEvent);
return;
} while (true)
{
uint dwEventMask = 0;
bSuccess = WaitCommEvent(comm_handle, ref dwEventMask, ref m_ov);
if (!bSuccess)
{
int errorCode = GetLastError();
if (errorCode != ERROR_IO_PENDING)
{
continue;
}
} //重叠 I/O 操作正在进行中,可以继续做
uint Event = WaitForSingleObject(m_ov.hEvent, Timeout.Infinite);
if (Event == WAIT_OBJECT_0)
{
uint BytesLen = 0;
if (!GetOverlappedResult(comm_handle, ref m_ov, ref BytesLen, false))
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult return false. " });
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult successfully, " + BytesLen.ToString() + " bytes read. " }); uint dwModemStatus = 0;
if (GetCommModemStatus(comm_handle, ref dwModemStatus))
{
if ((dwModemStatus & MS_CTS_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_CTS_ON is be detected" }); } if ((dwModemStatus & MS_DSR_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_DSR_ON is be detected" }); } if ((dwModemStatus & MS_RLSD_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_RLSD_ON is be detected" }); } this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return true. Status = " + dwModemStatus.ToString() + ", Now time is " + DateTime.Now.ToString() });
}
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return false. " });
} ResetEvent(m_ov.hEvent); } //end while
}
}
解决方案 »
- 如何从Interface(接口)获取数据啊?
- 这里有没有外包团队?若有空的可以联系我
- 【急】关于Common language runtime debugging services(公共语言运行库调试服务)
- 一条sql语句怎么写 急急 在线等了
- 如何在TextBox中完全屏蔽字符
- winform子窗体通过一个类更新主窗体的内容,应该怎样子写?谢谢
- 数据库的问题。。。。
- 关于webform的小菜问题,希望大家指教,顶者有分
- 哪位高手有c#《高校后勤管理系统》的源代码啊?急求!!!
- 哪里有可以使用的vs.net, 我下载的总有问题。
- 如何在C#中输出C++6.0所绘制的窗体
- C#调用C写的DLL时遇到的问题
private static extern bool SetCommMask(int hFile, uint dwEvtMask);[DllImport("kernel32.dll")]
private static extern bool WaitCommEvent(int hFile, ref uint lpEvtMask, ref OVERLAPPED lpOverlapped);[DllImport("kernel32.dll")]
private static extern bool GetCommModemStatus(int hFile, ref uint modemStat); //EV_CTS|EV_DSR|EV_RLSD[DllImport("kernel32.dll")]
private static extern uint WaitForSingleObject(int hFile, int dwMilliseconds);
1, 把uint 类型改为 int:
[DllImport("kernel32.dll", SetLastError=true)] static extern int GetCommModemStatus ( int hFile, ref int lpModemStat) 2,保CTS,DSR,RING,RLSD的常量是否正确:
MS_CTS_ON:0x0010
The CTS (clear-to-send) signal is on.MS_DSR_ON:0x0020
The DSR (data-set-ready) signal is on.MS_RING_ON:0x0040
The ring indicator signal is on.MS_RLSD_ON:0x0080
The RLSD (receive-line-signal-detect) signal is on.
int dwModemStatus = 0;
if (GetCommModemStatus(comm_handle, ref dwModemStatus))
{
Console.WriteLine(dwModemStatus.ToString());//它的状态为0吗?
if ((dwModemStatus & MS_CTS_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_CTS_ON is be detected" }); } if ((dwModemStatus & MS_DSR_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_DSR_ON is be detected" }); } if ((dwModemStatus & MS_RLSD_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_RLSD_ON is be detected" }); } this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return true. Status = " + dwModemStatus.ToString() + ", Now time is " + DateTime.Now.ToString() });
}
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return false. " });
要不就是硬件方面问题啊
private const UInt32 EV_RXFLAG = 0x0002; //The event character was received and placed in the input buffer.
private const UInt32 EV_TXEMPTY = 0x0004; //The last character in the output buffer was sent.
private const UInt32 EV_CTS = 0x0008; //The CTS (clear-to-send) signal changed state.
private const UInt32 EV_DSR = 0x0010; //The DSR (data-set-ready) signal changed state.
private const UInt32 EV_RLSD = 0x0020; //The RLSD (receive-line-signal-detect) signal changed state.
private const UInt32 EV_BREAK = 0x0040; //A break was detected on input.
private const UInt32 EV_ERR = 0x0080; //A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
private const UInt32 EV_RING = 0x0100; //A ring indicator was detected. private const UInt32 MS_CTS_ON = 0x0010; //The CTS (clear-to-send) signal is on.
private const UInt32 MS_DSR_ON = 0x0020; //The DSR (data-set-ready) signal is on.
private const UInt32 MS_RING_ON = 0x0040; //The ring indicator signal is on.
private const UInt32 MS_RLSD_ON = 0x0080; //The RLSD (receive-line-signal-detect) signal is on.//我指的是它传出的参数dwModemStatus=0
//改成int还是一样
uint Event = WaitForSingleObject(m_ov.hEvent, Timeout.Infinite);
if (Event == WAIT_OBJECT_0)
{
uint BytesLen = 0;
if (!GetOverlappedResult(comm_handle, ref m_ov, ref BytesLen, false))
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult return false. " });
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetOverlappedResult successfully, " + BytesLen.ToString() + " bytes read. " }); int dwModemStatus = 0;
if (GetCommModemStatus(comm_handle, ref dwModemStatus))
{
if ((dwModemStatus & MS_CTS_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_CTS_ON is be detected" }); } if ((dwModemStatus & MS_DSR_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_DSR_ON is be detected" }); } if ((dwModemStatus & MS_RLSD_ON) > 0)
{ this.Invoke(new ShowString(AddNewLine), new object[] { "MS_RLSD_ON is be detected" }); } this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return true. Status = " + dwModemStatus.ToString() + ", Now time is " + DateTime.Now.ToString() });
}
else
this.Invoke(new ShowString(AddNewLine), new object[] { "GetCommModemStatus return false. " });
}
试试更改以下代码(ref --> out) :[DllImport("kernel32.dll")]
private static extern bool GetCommModemStatus(int hFile, out uint modemStat); //EV_CTS|EV_DSR|EV_RLSD
int dwModemStatus = 0;
if (GetCommModemStatus(comm_handle, out dwModemStatus))
参考串口监控示例
事实上如何触发它我并不确定,因为4配168几乎从来没有成功过,
偶尔的几次都是4、5触发,或者是串口掉地上了然后莫明其妙就触发了 我用的是COM5(5以下的串口都坏了。。),用它来进行485通讯是没有问题的也许问题并不在于GetCommModemStatus?
private static extern bool GetCommModemStatus(int hFile, ref uint modemStat);
改成这样试试,当然,其它的API函数也要修改。
[DllImport("kernel32.dll", EntryPoint="GetCommModemStatus", CharSet=CharSet.Auto)]
private static extern bool GetCommModemStatus(IntPtr hFile, ref int modemStat);