При работае с портами карты расширения (адвантековская rs485) выскакивает ошибка при открытии порта:System.IO.IOException was unhandled
Message="The parameter is incorrect.\r\n"
Source="System"
StackTrace:
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream.set_DtrEnable(Boolean value)
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 Burner.Form1.button4_Click(Object sender, EventArgs e) in D:\Project\Burner\Burner\Form1.cs:line 414
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Burner.Program.Main() in D:\Project\Burner\Burner\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Может имя не нравится...
SerialPort o = new SerialPort("COM4");
o.Open(); — этого достаточно для ошибки.
Подскажите как выкрутиться
Здравствуйте, Yeti_Bigfoot, Вы писали:
Y_B>Может имя не нравится...
Y_B> SerialPort o = new SerialPort("COM4"); Y_B> o.Open(); — этого достаточно для ошибки. Y_B>Подскажите как выкрутиться
Имя вроде бы правильное...
Попробуй гипертерминалом или другой программой открыть СОМ-порт. Он вообще живой?
Здравствуйте, Yeti_Bigfoot, Вы писали:
Y_B> at System.IO.Ports.SerialStream.set_DtrEnable(Boolean value)
Судя по этому, SerialPort пытается выполнить EscapeCommFunction, передав ей SETDTR, а драйвер порта это не поддерживает. Поставьте Portmon — можно будет точнее сказать, на какую операцию драйвер порта возвращает ошибку.
Офф. Можете забросать меня камнями и поставить кучу минусов, но... SerialPort — зло.
Программы написанные "под win32" — креейт, реад, врайт файл — работают на ура. Нашел особенность — в настройках дров есть "485 буфер енейбл" — актив хай, лоу, и нормал. Вот с нормал позволяет открыть. Но обмен данными не происходит. Узнать бы что спрятали под этой опцией... Сериал порт не зло, как таковой — для общих рабочих нужд вполне подходит. Н вот для этой не подошел нужды...))) просто городить конструкцию на шарпе под креейт файл не охота(
Здравствуйте, HowardLovekraft, Вы писали:
HL>Здравствуйте, Yeti_Bigfoot, Вы писали:
Y_B>>по после этой конструкции прерывание не срабатывает
HL>Не понятно, о каком прерывании речь, но зачем переоткрывать порт для смены четности?
А разве не надо переинициализировать его?.. тогда надо просто сделать ожидание пока все не уйдут, и менять паритет?
Здравствуйте, Yeti_Bigfoot, Вы писали:
Y_B>по после этой конструкции прерывание не срабатывает
Понял. Событие.
Y_B>А разве не надо переинициализировать его?.. тогда надо просто сделать ожидание пока все не Y_B>уйдут, и менять паритет? Y_B>Но после такого подхода на осциллографе никто даже не уходит.
Не знаю, что точно вы подразумеваете под переинициализацией, но то, что смена четности безболезненно может делаться для открытого порта, уверен. Я про общий случай — что точно делает SerialPort, надо смотреть. Сеттер свойства SerialPort.Parity в конечном счете вызовет API SetCommState.
По поводу ожидания отправки данных. Не факт, что метод Write этого не ждет. Рефлектора под рукой нет, глянуть не могу. На асме х.з., на API я бы вызывал WaitCommEvent.
В любом случае, для того, чтоб узнать, что на самом деле происходит с портом, настоятельно рекомендую portmon. Намного более информативная вещь, чем осциллограф. Интереса ради поставьте его и посмотрите, сколько лишних телодвижений делает SerialPort на каждый чих.
А так — слишком много неизвестных. Не видя протокола обмена с устройством, лога обращений к драйверу порта, не зная, что за конвертор вы используете, сложно сказать что-то более определенное.
Спасибо за совет, проверил программой portmon, правда по началу она меня озадачила(из 30 отправленных байт только 21 показывала), в целом она помогла выловить ошибку компонента SerialPort, возникала при обращении к состоянию флага DTR, видимо драйвер тех карточек что-то левое возвращал.
Пишу свой класс работы с портом, осталость только асинхронное чтение организовать. Как я понял WaitCommEvent дает возможность сделать чтение событийным. Подскажите как это должно выглядеть на C#.