سؤال
أحاول الفتح والقراءة من منفذ تسلسلي باستخدام فئة System.IO.Ports.SerialPort.لقد قمت بسحب المنفذ التسلسلي من جزء الأدوات (VS 2008) إلى نموذج Windows الخاص بي.لقد قمت بإعداد شبكة خصائص حتى أتمكن بسهولة من تغيير خصائص المنفذ التسلسلي في وقت التشغيل.عندما أحاول فتح المنفذ، يظهر لي الخطأ الموضح أدناه.لا أفهم السبب لأنه يمكنني الفتح والقراءة من المنفذ باستخدام Hyperterminal.أيه أفكار؟
System.IO.IOException Error connection: A device attached to the system is not functioning
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.InternalResources.WinIOError()
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 Test.CardReader.frmMain.Connect() in D:\Develop\2.0\Projects\Kiosk\EmbeddedBrowser\Windows Forms\Test.CardReader\Form1.cs:line 166
لاحظ ، هذا اتصال USB بحيث يكون Actuall منفذًا متسلسلًا افتراضيًا على الإعدادات الخاصة بي على النحو التالي:
معدل الباود = 9600
وحدات البيانات = 8
DiscardNull = false
DtrEnable = false
المصافحة = لا يوجد
التكافؤ = لا شيء
استبدال التكافؤ = 63
اسم المنفذ = COM3
حجم القراءة = 4096
مهلة القراءة = -1
البايتات المستلمة = 1
ترسينابلي = خطأ
ستوببيتس = واحد
حجم المخزن المؤقت للكتابة = 2048
مهلة الكتابة = -1
لقد قمت بتنزيل PortMon من sysinternals.لقد قمت بالتقاط سجلين، الأول هو السجل الذي يحدث عندما يفتح Hyperterminal المنفذ، والثاني هو ما يحدث عندما تحاول فئة .net SerialPort فتح المنفذ:
المحطة الفائقة:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_SET_QUEUE_SIZE USBSER000 SUCCESS InSize: 8192 OutSize: 8192
IOCTL_SERIAL_CONFIG_SIZE USBSER000 SUCCESS Size: 0
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_SET_RTS USBSER000 SUCCESS
IOCTL_SERIAL_SET_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:f6 XOFF:6
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:80000001 Replace:80000040 XonLimit:80 XoffLimit:200
IOCTL_SERIAL_SET_TIMEOUTS USBSER000 SUCCESS RI:10 RM:0 RC:0 WM:0 WC:5000
IOCTL_SERIAL_SET_WAIT_MASK USBSER000 SUCCESS Mask: RLSD ERR
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_WAIT_ON_MASK USBSER000
IRP_MJ_READ USBSER000 Length 80
صافي المنفذ التسلسلي:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_GET_PROPERTIES USBSER000 SUCCESS
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IRP_MJ_CLEANUP USBSER000 SUCCESS
IRP_MJ_CLOSE USBSER000 SUCCESS
المحلول
فيما يتعلق بالاختلافات بين Hyperterminal وكائن المنفذ التسلسلي .NET، فإن Hyperterminal هو تطبيق تجاري ومستقر.إذا مات كائن المنفذ التسلسلي الأساسي أو ألقى استثناءً، فإن Hyperterminal قام بإخفائه عنك.يطرح كائن المنفذ التسلسلي .NET استثناءات أكثر من أي كائن .NET آخر استخدمته.
النقاط التي يجب القيام بها:
- عندما تقوم بتغيير أحد الإعدادات، قم بإغلاقه أولاً، ثم قم بتغييره، ثم أعد فتحه.بعض المنافذ تكرهها حقًا عند تغييرها أثناء فتحها.
- توقع إجراء الكثير من عمليات "محاولة الالتقاط" حول كائن المنفذ التسلسلي الخاص بك، وحول كل شيء تفعله.
- تأكد من وجود واحد لكل استثناء محتمل مدرج، وتأكد من أن كل استثناء يتحقق من الرسالة (يمكن أن يكون مختلفًا في ظل ظروف مختلفة).والعديد منها قابل للاسترداد ببساطة عن طريق الإغلاق وإعادة الفتح.
- حاول المتابعة بالضبط حيث يتم طرح الاستثناءات.معرفة ما إذا كان تعديل الترتيب الذي قمت بتعيينه للأشياء سيؤدي إلى إصلاحه ...الكائن صعب حقًا.
إذا حاولت ضبط DTR بشكل صريح على false قبل فتحه، فقد يتعين عليك فقط أن تبتسم وتكشفه باستخدام هذا الجهاز.لا يعد كائن SerialPort أحد الأمثلة المتوهجة للمكتبة المنفذة جيدًا في .NET.إذا لاحظت، فإن Hyperterminal يحصل على نفس الخطأ، لكنه يتجاهله فقط.
إذا استطعت، فجرب ذلك باستخدام منفذ تسلسلي عادي أو جهاز USB ذو علامة تجارية مختلفة.إذا كنت لا تزال تحصل على نفس الخطأ، فقد يكون ذلك بسبب شيء ما من جانب التطبيق الخاص بك.
نصائح أخرى
في UART
الحقيقي، سوف DTREnable
يؤكد دبوس DTR
من UART
لتشير إلى أنك على استعداد لاستقبال البيانات.
واعتمادا على تنفيذ برنامج التشغيل الخاص بك، قد تحتاج إلى إعادة ضبط DTREnable
إلى true
لفتح الميناء.
ويبدو أن الفرق هو المصافحة.
ولم تكن لدي مشاكل مع الطبقة منفذ تسلسلي وكتبوا التطبيقات التي شغلت في 800،000 نقطة أساس.