Windows CE和串口问题(无法打开端口)

发布于 2024-10-04 13:40:15 字数 1938 浏览 0 评论 0原文

我正在尝试为 GPS 设备编写自定义应用程序,并且需要读取 GPS 数据。

我面临的问题是我无法打开 GPS 端口。我知道它是哪个 COM,并且知道波特率,但每当我访问 Open() 方法时,我都会收到 IOException

port = new SerialPort("COM6", 9600);
port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived);
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
try
{
    port.Open();
}
catch (IOException ex)
{
    SetLabel(label1, ex.Message);
}

堆栈跟踪:

at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at PortTest.Form1.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at PortTest.Program.Main()

令人非常恼火的是,我发现示例本机 C++ 代码确实可以工作,可以毫无问题地打开端口,而且我什至可以浏览一些 NMEA 字符串。但这都是使用网络上提供的示例 C++ 代码完成的,我觉得自己不够熟练,无法将我的整个应用程序基于这种语言。我想坚持使用 C#。

是否有其他方法可以使用 Windows CE 中的 SerialPort 类在 C# 中打开端口?或者也许完全使用其他类?
如果没有,是否有一个 C++ 编写的 DLL 可以为 Windows CE 提供相同(或类似)的功能?

编辑(了解更多详细信息): 我得到的例外就是这样。 IOException。 Visual Studio 调试器没有告诉我更多信息。我不知道这是否是由于设备上的一些拙劣的 Windows CE 设置造成的。我确实记得我的 Windows Mobile 设备上存在异常字符串问题,但通过添加对 System.SR 的引用解决了这个问题,我已经在本例中尝试过。如果我在 Windows CE 和异常消息方面缺少一些技巧,我也很想知道。 ;)

我还尝试使用没有事件的代码并通过在构造函数中指定更多参数,并且在尝试打开端口时总是会遇到异常。

最后,我已经尝试在端口名称中添加 : ,但这也没有帮助。

I'm trying to write a custom application for a GPS device, and I need to read the GPS data.

The problem I'm facing is that I cannot open the GPS port. I know which COM it is, and I know the baud rate, but I get an IOException whenever I get to the Open() method.

port = new SerialPort("COM6", 9600);
port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived);
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
try
{
    port.Open();
}
catch (IOException ex)
{
    SetLabel(label1, ex.Message);
}

Stack trace:

at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at PortTest.Form1.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at PortTest.Program.Main()

What makes matters quite infuriating is that a sample native C++ codes that I found DOES work, opens the port without problems, and I could even glance at some of the NMEA strings. But this was all done using sample C++ codes provided around the Web, and I don't feel proficient enough to base my entire application in this language. I'd like to stick to C#.

Are there any other ways to open a port in C# using the SerialPort class in Windows CE? Or perhaps using other classes entirely?
If not, is there perhaps a C++ written DLL that allows the same (or similar) functionality available for Windows CE?

EDIT (for more details):
The exception I get is just that. IOException. The Visual Studio debugger tells me nothing more. I don't know if this is due to some botched Windows CE setting on the device. I DO remember a problem with exception strings on my Windows Mobile device, but that was solved by adding a reference to System.SR, which I already tried in this case. If there's some trick I'm missing with regards to Windows CE and exception messages, I'd love to know too. ;)

I've also tried to use the code without events and by specifying more parameters in the constructor, and I'd always get the exception when trying to open the port.

Finally, I've already tried adding a : to the port name, which also didn't help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

忆悲凉 2024-10-11 13:40:15

我建议为构造函数提供更多选项;奇偶校验、停止位和握手模式。

SerialPort port = new SerialPort ("COM6", 9600, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;

I'd suggest providing more options to the constructor; parity, stop bits and handshake mode.

SerialPort port = new SerialPort ("COM6", 9600, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;
逆光飞翔i 2024-10-11 13:40:15

建议的解决方案均无效。那一部分仍然“无法打开”。我们通过 C++ 编写的本机 DLL 解决了这个问题,该 DLL 打开端口并从中读取数据。

这个解决方案并不理想,但它是我们能想到的最好的解决方案。

这是一个相当“长”的解决方案,表明在这种特殊情况下 Compact Framework 出现了问题。

None of the suggested solutions worked. That one part remained "unopenable". We got around the issue through a C++ written native DLL which opens the port and read data from it.

This solution is hardly ideal, but it's the best we managed to come up with.

This is a rather "long" walkaround, and suggests that something is wrong with Compact Framework in this particular case.

嘿咻 2024-10-11 13:40:15

我遇到了同样的问题,重新安装了 System_SR_ENU.cab 和 NETCFv2。后来就没有问题了。

I had the same problem, reinstalled System_SR_ENU.cab and NETCFv2. It worked without problems afterwards.

一指流沙 2024-10-11 13:40:15

我遇到了类似的问题,以下代码适用于我的情况。我必须至少从另一个应用程序访问串行端口一次才能正确初始化它。我尝试将串行端口作为普通文件打开(请注意,我使用“COM8:”而不是“COM8”作为文件)。

//The settings object is defined elsewhere...
settings.PortName = "COM8";

//Creates the serial port.
SerialPort port = new SerialPort();
port.PortName = settings.PortName;
port.BaudRate = settings.BaudRate;        
port.Parity = settings.Parity;
port.DataBits = settings.DataBits;
port.StopBits = settings.StopBits;
port.ReadTimeout = 10000;
port.DtrEnable = true;
port.RtsEnable = true;


string vComm = settings.PortName + ":";
FileStream stream = null;
try 
{
   stream = new FileStream(vComm, FileMode.Open, FileAccess.Read);
}
catch
{
   //pass    
}
port.Open();
if(stream != null)
    stream.Dispose();

I had a similar problem and the following code worked in my case. I had to access the serial port from another application at least once in order to initialize it properly. I tried to open the serial port as a normal file(notice that I used "COM8:" instead of "COM8" for the file).

//The settings object is defined elsewhere...
settings.PortName = "COM8";

//Creates the serial port.
SerialPort port = new SerialPort();
port.PortName = settings.PortName;
port.BaudRate = settings.BaudRate;        
port.Parity = settings.Parity;
port.DataBits = settings.DataBits;
port.StopBits = settings.StopBits;
port.ReadTimeout = 10000;
port.DtrEnable = true;
port.RtsEnable = true;


string vComm = settings.PortName + ":";
FileStream stream = null;
try 
{
   stream = new FileStream(vComm, FileMode.Open, FileAccess.Read);
}
catch
{
   //pass    
}
port.Open();
if(stream != null)
    stream.Dispose();
薄暮涼年 2024-10-11 13:40:15

目前我不太确定,但通过使用本机 Win32 API,您必须通过名称 COM6: 来调用设备,而不仅仅是 COM6。但我不知道 C# SerialPort 类在这一点上的行为到底如何。

另外,我不认为这是所使用参数的问题,因为它们稍后会发挥作用。所以我的第二个猜测是您添加的事件订阅可能会导致问题。因此,为了绝对确定,我会注释您订阅 ErrorReceivedDataReceived 的两行。

我也曾经经历过一次相当奇怪的失败。回顾过去,我似乎以这种方式编写了错误的端口名称,这些字符不是我的代码文件中用于声明端口名称的默认 ANSI 字符。因此,删除并重写构造函数后,问题突然消失了。

最后但并非最不重要的一点是,您在代码中表明 StackTrace 抛出了 WinIOError。但是您能否更新您的问题并告诉我们确切的错误代码或错误消息?

Currently i'm not quite sure, but by using the native Win32 API you had to call the device by the name COM6: and not only COM6. But i don't know how the C# SerialPort class behaves in this point exactly.

Additionally i don't think that it is a problem of the used parameters, cause they will come later into play. So my second guess would be that your added event subscriptions could maybe lead to a problem. So just to be absolutely sure i would comment the two lines where you subscribe to ErrorReceived and DataReceived.

Also i had one time also a quite bizarre failure. Looking backwards it seemed that i wrote the port name in that way wrong, that the characters are not the default ANSI chars in my code file for declaring the port name. So after deleting and rewriting the constructor the problem was suddenly gone.

Last but not least you showed in your code that the StackTrace throwed an WinIOError. But could you maybe update your question and tell us the exact error code or error message?

缱绻入梦 2024-10-11 13:40:15

CE 中的端口名称必须带有冒号后缀,因此将其更改为“COM6:”

The port name in CE must be suffixed with a colon, so chane it to "COM6:"

自此以后,行同陌路 2024-10-11 13:40:15

需要冒号的说法并不正确 [Windows CE 6.0R3 上的 Compact Framework 3.5]。对于 n > 的 com 端口,我仅使用“COMn”或“$device\COMn”打开串行端口。 9. 但是看起来Compact Framework V1 所需的OpenNetCf 版本需要冒号。

我建议调用静态方法 SerialPort.GetPortNames() 并确保硬编码为 COM6 的设备实际上在返回的字符串数组中可用。

Not true that a colon is required [Compact Framework 3.5 on Windows CE 6.0R3]. I open my serial ports with just "COMn" or "$device\COMn" for com ports where n > 9. But it looks like the OpenNetCf version that was needed for V1 of Compact Framework needed the colon.

I suggest calling the static method SerialPort.GetPortNames() and making sure that the device you have hard-coded as COM6 is in fact available in the returned string array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文