+ -
当前位置:首页 → 问答吧 → 串口打开成功,但用WriteFile()发送却发不出来,也不报错????

串口打开成功,但用WriteFile()发送却发不出来,也不报错????

时间:2011-12-24

来源:互联网

在wince下,我调用CreatFile()成功打开了COM4,但调用WriteFile()发送时,里边的参数和返回值都表示发出去了,但物理上却没有数据出来,这是怎么回事儿,和驱动有关系吗??

作者: zhanweizhao_111   发布时间: 2011-12-24

串口的DCB参数你是否设置,要与物理设备保持一致才能正常通讯,否则发送的数据可能是乱码,或造成WriteFile成功,而设备实际没有接收到正确的数据;
通过GetCommState、SetCommState来修改COM的DCB;

作者: chayedanwc   发布时间: 2011-12-24

引用 1 楼 chayedanwc 的回复:
串口的DCB参数你是否设置,要与物理设备保持一致才能正常通讯,否则发送的数据可能是乱码,或造成WriteFile成功,而设备实际没有接收到正确的数据;
通过GetCommState、SetCommState来修改COM的DCB;


这两个函数都调用了,并且设置了波特率 校验位 停止位等,并且这两个函数的返回值返回值均为true

作者: zhanweizhao_111   发布时间: 2011-12-24

这是我DCB结构的声明:
C# code

//设备控制块结构体类型
        [StructLayout(LayoutKind.Sequential)]
        public struct DCB
        {
            //taken from c struct in platform sdk 
            public int DCBlength;           // sizeof(DCB) 
            public int BaudRate;            // 指定当前波特率 current baud rate
            // these are the c struct bit fields, bit twiddle flag to set
            public int fBinary;          // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check 
            public int fParity;          // 指定是否允许奇偶校验 enable parity checking 
            public int fOutxCtsFlow;      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control 
            public int fOutxDsrFlow;      // 指定CTS是否用于检测发送控制 DSR output flow control 
            public int fDtrControl;       // DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type 
            public int fDsrSensitivity;   // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity 
            public int fTXContinueOnXoff; // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx 
            public int fOutX;          // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control 
            public int fInX;           // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control 
            public int fErrorChar;     // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement 
            public int fNull;          // eTRUE时,接收时去掉空(0值)字节 enable null stripping 
            public int fRtsControl;     // RTS flow control 
            /*RTS_CONTROL_DISABLE时,RTS置为OFF
                     RTS_CONTROL_ENABLE时, RTS置为ON
                     RTS_CONTROL_HANDSHAKE时,
                     当接收缓冲区小于半满时RTS为ON
                      当接收缓冲区超过四分之三满时RTS为OFF
                     RTS_CONTROL_TOGGLE时,
                     当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF*/

            public int fAbortOnError;   // TRUE时,有错误发生时中止读和写操作 abort on error 
            public int fDummy2;        // 未使用 reserved 

            public uint flags;
            public ushort wReserved;          // 未使用,必须为0 not currently used 
            public ushort XonLim;             // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold 
            public ushort XoffLim;            // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold 
            public byte ByteSize;           // 指定端口当前使用的数据位 number of bits/byte, 4-8 
            public byte Parity;             // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY  0-4=no,odd,even,mark,space 
            public byte StopBits;           // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS  0,1,2 = 1, 1.5, 2 
            public char XonChar;            // 指定用于发送和接收字符XON的值 Tx and Rx XON character 
            public char XoffChar;           // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character 
            public char ErrorChar;          // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character 
            public char EofChar;            // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character 
            public char EvtChar;            // 当接收到此字符时,会产生一个事件 received event character 
            public ushort wReserved1;         // 未使用 reserved; do not use 
        }



这是对DCB的设置:
C# code

 // 打开串口 OPEN THE COMM PORT.
        public int OpenCom()
        {
            hComm = CreateFile(comPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

            SetupComm(hComm, 1024, 1024);//输入输出缓冲区大小都是1024个字节
            // 设置通信超时时间 SET THE COMM TIMEOUTS.
            GetCommTimeouts(hComm, ref ctoCommPort);
            ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
            ctoCommPort.ReadTotalTimeoutMultiplier = 300;
            ctoCommPort.WriteTotalTimeoutMultiplier = 300;
            ctoCommPort.WriteTotalTimeoutConstant = 500;
            SetCommTimeouts(hComm, ref ctoCommPort);

            // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
            GetCommState(hComm, ref dcbCommPort);
            dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);
            dcbCommPort.BaudRate = 115200;
            //dcbCommPort.fParity = 1;
            dcbCommPort.ByteSize = (byte)8;
            dcbCommPort.Parity = (byte)0;
            dcbCommPort.StopBits = 0;
            //if (dcbCommPort.Parity > 0)
            //{
            //    dcbCommPort.fParity = 1;
            //dcbCommPort.flags |= 2;
            //}
            dcbCommPort.flags = 0;
            //dcbCommPort.flags |= 1;
            //dcbCommPort.wReserved = 0;
/*          //------------------------------
            SetDcbFlag(0, 1, dcbCommPort);            //二进制方式 
            SetDcbFlag(1, (dcbCommPort.Parity == 0) ? 0 : 1, dcbCommPort);
            SetDcbFlag(2, 0, dcbCommPort);            //不用CTS检测发送流控制
            SetDcbFlag(3, 0, dcbCommPort);            //不用DSR检测发送流控制
            SetDcbFlag(4, 0, dcbCommPort);            //禁止DTR流量控制
            SetDcbFlag(6, 0, dcbCommPort);            //对DTR信号线不敏感
            SetDcbFlag(9, 1, dcbCommPort);            //检测接收缓冲区
            SetDcbFlag(8, 0, dcbCommPort);            //不做发送字符控制
            SetDcbFlag(10, 0, dcbCommPort);           //是否用指定字符替换校验错的字符
            SetDcbFlag(11, 0, dcbCommPort);           //保留NULL字符
            SetDcbFlag(12, 0, dcbCommPort);           //允许RTS流量控制
            SetDcbFlag(14, 0, dcbCommPort);           //发送错误后,继续进行下面的读写操作

            //------------------------------
            dcbCommPort.wReserved = 0;                       //没有使用,必须为0  
            dcbCommPort.XonLim = 0;                          //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
            dcbCommPort.XoffLim = 0;                         //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
            dcbCommPort.XonChar = (char)0;                         //发送和接收的XON字符 
            dcbCommPort.XoffChar = (char)0;                        //发送和接收的XOFF字符
            dcbCommPort.ErrorChar = (char)0;                       //代替接收到奇偶校验错误的字符 
            dcbCommPort.EofChar = (char)0;                         //用来表示数据的结束  
            dcbCommPort.EvtChar = (char)0;                         //事件字符,接收到此字符时,会产生一个事件  
            dcbCommPort.wReserved1 = 0;                      //没有使用 
*/

            SetCommState(hComm, ref dcbCommPort);
            return hComm;
        }


作者: zhanweizhao_111   发布时间: 2011-12-24

没有人知道可能的原因吗

作者: zhanweizhao_111   发布时间: 2011-12-24

没搞过wince
不知道是否可以打印日志 或者 单步调试
如果写的内容正确的话 刷新下缓存

作者: c_losed   发布时间: 2011-12-24