VC中 使用 CSerialPort类,WM_COMM_RXFLAG_DETECTED 消息问题

cyberdavinci 2010-12-20 01:30:40


我在VC中,用CSerial Port 类,写一个串口通信小程序,想用WM_COMM_RXFLAG_DETECTED这个事件告知我一次接收信息完成。

我的主程序文件是:CVerDlg.cpp,在该文件中:

ON_MESSAGE(WM_COMM_RXFLAG_DETECTED, OnCommEnd)

LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)


在CVerDlg.h中:
afx_msg LONG OnCommEnd(WPARAM ch, LPARAM port);


现在,当接收到串口发送来的消息后,我可以进入
LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)

这个函数

但是,问题在于:
如果串口到来的消息只有一个字节,我每接收完这条消息后,进入LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)这个函数一次, 如果串口发送的消息大于一个字节(2~N)则每次接收完消息后,会进入这个函数两次,为啥会这样?还盼牛人指点!!!! 或者是,我对WM_COMM_RXFLAG_DETECTED这个事件的理解有问题??
...全文
359 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
laicai1989 2013-05-24
  • 打赏
  • 举报
回复
ls 问题解决了吗 求解。。
kavy00 2012-01-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xianglitian 的回复:]

引用 6 楼 cyberdavinci 的回复:
引用 5 楼 grf9527 的回复:

你到底想说什么,进入几次不重要,重要的是你怎么处理接收的。如果是end了,你也得接收下一个啊,你的协议是什么,能贴点源码吗


我的协议是:没接收到一条信息,不验证信息的内容,立即回复一条信息(回复的信息是预先存储的,且每一条按次序均不相同)。在这种情况下,如果其实只收到一条信息,但却进入了两……
[/Quote]我用的是 Serialport这个多线程类来编的一个类似与串口调试助手程序,但有个那个在接收框中 如何实现自动换行啊 就是说没接收完一次数据 就会自动换行!!我用的是OnComm(WPARAM ch,LPARAM port)这个函数来接收数据的,这个函数是每当接收缓冲区有一个字符到来时 他就响应了 那我如何判断何时数据接收完了啊
向立天 2012-01-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cyberdavinci 的回复:]
引用 5 楼 grf9527 的回复:

你到底想说什么,进入几次不重要,重要的是你怎么处理接收的。如果是end了,你也得接收下一个啊,你的协议是什么,能贴点源码吗


我的协议是:没接收到一条信息,不验证信息的内容,立即回复一条信息(回复的信息是预先存储的,且每一条按次序均不相同)。在这种情况下,如果其实只收到一条信息,但却进入了两次LONG CVer1Dlg::OnCommEnd(W……
[/Quote]你这个机制是有问题的啊
下位和上位其实是不同步的
下位来了一个消息
但是上位可能不能一次读完
这个是正常的
你不做判断不合适吧
有什么特殊需求么?
kavy00 2012-01-12
  • 打赏
  • 举报
回复
你想实现那个自动应答的话 这样应该就可以了:比如规定一个数据的协议啊 发送的数据以#结尾啊 然后在接收的时候检测#即可啊
kavy00 2012-01-12
  • 打赏
  • 举报
回复
这个是因为 你使用的OnComm()这个函数 他响应的条件是:每当接收缓冲区有一个字符到来时 他就会触发这个OnComm()函数 所以当你发一个字节的时候就触发一次 多个字节的时候就是触发多次了!!已也可以Debug下 在OnComm()设置断点 发多字节 观察变量值就很明白了 !!
cyberdavinci 2010-12-21
  • 打赏
  • 举报
回复
把CSerialPort类的代码贴出来。。。 虽然貌似这个类在网上很多的样子。。
SerialPort.h

#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__

#define WM_COMM_BREAK_DETECTED WM_USER+1 // A break was detected on input.
#define WM_COMM_CTS_DETECTED WM_USER+2 // The CTS (clear-to-send) signal changed state.
#define WM_COMM_DSR_DETECTED WM_USER+3 // The DSR (data-set-ready) signal changed state.
#define WM_COMM_ERR_DETECTED WM_USER+4 // A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
#define WM_COMM_RING_DETECTED WM_USER+5 // A ring indicator was detected.
#define WM_COMM_RLSD_DETECTED WM_USER+6 // The RLSD (receive-line-signal-detect) signal changed state.
#define WM_COMM_RXCHAR WM_USER+7 // A character was received and placed in the input buffer.
#define WM_COMM_RXFLAG_DETECTED WM_USER+8 // The event character was received and placed in the input buffer.
#define WM_COMM_TXEMPTY_DETECTED WM_USER+9 // The last character in the output buffer was sent.

class CSerialPort
{
public:
int m_nWriteSize;
void ClosePort();
// contruction and destruction
CSerialPort();
virtual ~CSerialPort();

// port initialisation
BOOL InitPort(CWnd* pPortOwner, UINT portnr = 1, UINT baud = 19200, char parity = 'N', UINT databits = 8, UINT stopbits = 1, DWORD dwCommEvents = EV_RXCHAR, UINT writebuffersize = 1024);
HANDLE m_hComm;

// start/stop comm watching
BOOL StartMonitoring();
BOOL RestartMonitoring();
BOOL StopMonitoring();

DWORD GetWriteBufferSize();
DWORD GetCommEvents();
DCB GetDCB();

void WriteToPort(char* string);
void WriteToPort(char* string,int n);
void WriteToPort(LPCTSTR string);
void WriteToPort(LPCTSTR string,int n);

protected:
// protected memberfunctions
void ProcessErrorMessage(char* ErrorText);
static UINT CommThread(LPVOID pParam);
static void ReceiveChar(CSerialPort* port, COMSTAT comstat);
static void WriteChar(CSerialPort* port);

// thread
CWinThread* m_Thread;

// synchronisation objects
CRITICAL_SECTION m_csCommunicationSync;
BOOL m_bThreadAlive;

// handles
HANDLE m_hWriteEvent;
HANDLE m_hShutdownEvent;

// Event array.
// One element is used for each event. There are two event handles for each port.
// A Write event and a receive character event which is located in the overlapped structure (m_ov.hEvent).
// There is a general shutdown when the port is closed.
HANDLE m_hEventArray[3];

// structures
OVERLAPPED m_ov;
COMMTIMEOUTS m_CommTimeouts;
DCB m_dcb;

// owner window
CWnd* m_pOwner;

// misc
UINT m_nPortNr;
char* m_szWriteBuffer;
DWORD m_dwCommEvents;
DWORD m_nWriteBufferSize;
};

#endif __SERIALPORT_H__
cyberdavinci 2010-12-21
  • 打赏
  • 举报
回复
T_T
cyberdavinci 2010-12-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 grf9527 的回复:]

你到底想说什么,进入几次不重要,重要的是你怎么处理接收的。如果是end了,你也得接收下一个啊,你的协议是什么,能贴点源码吗
[/Quote]

我的协议是:没接收到一条信息,不验证信息的内容,立即回复一条信息(回复的信息是预先存储的,且每一条按次序均不相同)。在这种情况下,如果其实只收到一条信息,但却进入了两次LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)函数,这是,我的程序就会发出两条不同的应答信息,但事实上,这时候应该只发送一条应答信息,这就是现在的问题。。。

代码的话,其实就是我在1楼所贴的:
我的程序中使用了CSerialPort 类,我使用了该类中定义的WM_COMM_RXFLAG_DETECTED事件(Serial Port.h文件中)
#define WM_COMM_RXFLAG_DETECTED		WM_USER+8	// The event character was received and placed in the input buffer. 


而后,在我的主程序文件(CVer1Dlg.cpp)中,定义了LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)这个函数对该事件的响应
ON_MESSAGE(WM_COMM_RXFLAG_DETECTED, OnCommEnd)

LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)


当然,在CVer1Dlg.h中,也有声明
afx_msg LONG OnCommEnd(WPARAM ch, LPARAM port);


就是这样的了。。。

现在的情况是,接收到一次串口数据后,可以进入上述函数,如果接收的数据只有一个字节,则只进入上述函数一次;如果一次接收的数据超过一个字节,就会进入上述函数两次。。。。。 我想要的结果是,一次不管接收多少个字节,只进入这个函数一次。 这个,是不是也是WM_COMM_RXFLAG_DETECTED这个事件的本来意义?或者说,我对WM_COMM_RXFLAG_DETECTED这个事件的理解有问题?
grf9527 2010-12-20
  • 打赏
  • 举报
回复
你到底想说什么,进入几次不重要,重要的是你怎么处理接收的。如果是end了,你也得接收下一个啊,你的协议是什么,能贴点源码吗
cyberdavinci 2010-12-20
  • 打赏
  • 举报
回复
哪位大侠 帮帮忙啊。。
cyberdavinci 2010-12-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 varding 的回复:]

我以前用这个串口类读取大量的数据用的是在timer里定时读取(轮询)的方式,事件没试过,也许需要设置阈值什么的?

其实进入OnCommEnd多次也没关系的,你自己要把数据重新打包然后在接收端解包就可以了
[/Quote]
如果是单纯地接受数据的话,确实这样是没什么影响的。 但是,我现在要根据收到的数据自动应答,如果接收到一次,但是却两次进入LONG CVer1Dlg::OnCommEnd(WPARAM ch, LPARAM port)函数的话,我就自动应答两次,就悲剧了。。。
varding 2010-12-20
  • 打赏
  • 举报
回复
我以前用这个串口类读取大量的数据用的是在timer里定时读取(轮询)的方式,事件没试过,也许需要设置阈值什么的?

其实进入OnCommEnd多次也没关系的,你自己要把数据重新打包然后在接收端解包就可以了
cyberdavinci 2010-12-20
  • 打赏
  • 举报
回复
求救啊!!!

那位大侠能指点下啊!!!

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧