基于MFC,利用MSComm控件做得串口通信,只能发送,不能接收,OnComm事件调试模式下发现没有触发,大家进来帮我看看啊,baidu、Google都用了没找到答案,先谢谢大家了

程序员小哈
嵌入式领域优质创作者
博客专家认证
2009-05-11 03:09:17
我现在的情况是这样的,公司买了一个阿尔泰公司的GPRS1090I模块,随模块带了一个ARTServer软件,这个软件可以把终端的数据转发到虚拟串口上,我只要对虚拟串口进行操作就可以了(阿尔泰的技术人员是这么说的),我现在在本机上,用COM1连接那个GPRS模块,ARTServer软件内部做了映射,把数据映射到了COM5,现在的情况是,我利用串口助手丁丁的SSCOM3.2,打开COM1,我自己编写的软件打开COM,都是"9600,n,8,1",结果,我编的软件(COM5),发送一个测试数据“test”,串口助手(COM1)可以收到;反过来,串口助手(COM1)发送的数据,我编的软件一点反应都没有,调试看了一下,OnComm事件根本没有被触发。硬件指定没有问题,因为我开两个串口助手,一个打开COM1,一个打开COM5,结果双方都是收发正常。我下面贴出代码,大家帮我看看吧,憋了好几天了一点眉目没有,谢谢大家了

打开COM5

void CMyQQDlg::OnBtnStartGprs()
{
// TODO: Add your control notification handler code here
if(m_msGPRS.GetPortOpen())
m_msGPRS.SetPortOpen(FALSE);

m_msGPRS.SetCommPort(5); //选择com5
m_msGPRS.SetInBufferSize(1024);
m_msGPRS.SetOutBufferSize(512);

if( !m_msGPRS.GetPortOpen())
m_msGPRS.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");

m_msGPRS.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位

m_msGPRS.SetInputMode(1); //1:表示以二进制方式检取数据
m_msGPRS.SetRThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_msGPRS.SetInputLen(0); //设置当前接收区数据长度为0

m_msGPRS.GetInput(); //先预读缓冲区以清除残留数据

m_btnStartGPRS.EnableWindow(FALSE);
m_btnStopGPRS.EnableWindow(TRUE);
}


发送测试数据test

void CMyQQDlg::OnBtnTest()
{
// TODO: Add your control notification handler code here
CString strMsg="test";
m_msGPRS.SetOutput(COleVariant(strMsg)); //发送数据
}


OnComm数据处理部分==>这块没有响应

BEGIN_EVENTSINK_MAP(CMyQQDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CMyQQDlg)
ON_EVENT(CMyQQDlg, IDC_MSCOMM_GPRS, 1 /* OnComm */, OnOnCommMscommGprs, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

int flag =0;
void CMyQQDlg::OnOnCommMscommGprs()
{
// TODO: Add your control notification handler code here
DWORD InBufferCount;
InBufferCount=m_msGPRS.GetInBufferCount();

if(TRUE)
{
VARIANT m_input1;
COleSafeArray m_input2;
long length,i;
BYTE data[1024];
CString str ="";
CString strTemp;

if(m_msGPRS.GetCommEvent()==2)//接收缓冲区内有字符
{
m_input1=m_msGPRS.GetInput();//读取缓冲区内的数据
m_input2=m_input1;//将VARIANT型变量转换为ColeSafeArray型变量
length=m_input2.GetOneDimSize();//确定数据长度

for(i=0;i<length;i++)
m_input2.GetElement(&i,data+i); //将数据转换为BYTE型数组

for(i=0;i<length;i++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(data+i); //字符型
strTemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_strReceiveMsg +=strTemp; //加入接收编辑框对应字符串,在这儿,编辑框不是必须的,可做相应处理
char ch=(char)bt;
if(ch=='#')
{
//在此处设置一个可以接收数据的全局标志,说明接收到数据前的‘#’标志了,下一步可以读数据了,同时将m_strReceiveMsg清空
flag=1;
m_strReceiveMsg.Empty(); //下一次接收的便为有用的数据
}
if(ch=='$')
{
flag=0; //下面可以提取数据了

//先获取窗口句柄
HWND hWnd = ::FindWindow(NULL, "RSD有机溶剂在线监测仪远程控制软件");

CString strPara = _T("m_strReceiveMsg");
::SendMessage(hWnd,WM_GPRS_ADD_POINT ,0,(LPARAM)(LPCTSTR)strPara);
}
if(flag==1) //标志为1,
{
//提取数据
if (ch!='#')
{
m_strReceiveMsg +=strTemp;
}
}
}
}
UpdateData(FALSE); //-----更新编辑框内容
}
else
{
MessageBox("串口事件!");
}
}


大家帮我看看吧,例外很奇怪,网上很多串口助手同开两个测试,双方收到的都是乱码,而丁丁的这个串口助手就没有问题,这个串口助手写得真好啊,向他(她)学习,不知道用API写得还是控件做的,希望大家能够交流一下,首先拜托大家先帮我看看上面的问题再说^_^
...全文
867 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lihong08 2009-10-31
  • 打赏
  • 举报
回复
我也看看啊
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
谢谢你,先下个测试一下,好用的话,立刻结贴^_^
[Quote=引用 13 楼 lfchen 的回复:]
http://www.codeproject.com/KB/system/cserialport.aspx

//29th September 1999就没改动过了,哪下都一样。
[/Quote]
一条晚起的虫 2009-05-11
  • 打赏
  • 举报
回复
http://www.codeproject.com/KB/system/cserialport.aspx

//29th September 1999就没改动过了,哪下都一样。
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
SerialPort上哪能下到最新版本啊?这个类还有官网吗?
我的那个是在csdn下载的

[Quote=引用 11 楼 lfchen 的回复:]
SerialPort这个类很常用。
没注意到有什么bug,下个最新版的就好了。
[/Quote]
一条晚起的虫 2009-05-11
  • 打赏
  • 举报
回复
SerialPort这个类很常用。
没注意到有什么bug,下个最新版的就好了。
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
MSCOMM和虚拟串口不兼容? 这个不清楚啊,
我问了阿尔泰公司技术人员,
那个ARTServer是用什么写的,
他说是用API写的,我没用过API,一直用的MSComm控件,
莫非真是你说的原因,还真不知道啊,
大家用API做串口通信,是现成的类吗?我在网上下了一个SerialPort.cpp,
不知道是不是你们所说的API?
我查了一下,有人说这个类有bug,
也不清楚bug在哪,大家继续指点一下吧
[Quote=引用 8 楼 lfchen 的回复:]
关注一下。
COM1能引起中断,说明代码没有问题。
MSCOMM和虚拟串口不兼容?

mark一下。
[/Quote]
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复

这段代码我也加了,VC自动生成的,好奇怪啊

BEGIN_EVENTSINK_MAP(CMyQQDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CMyQQDlg)
ON_EVENT(CMyQQDlg, IDC_MSCOMM_GPRS, 1 /* OnComm */, OnOnCommMscommGprs, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

一条晚起的虫 2009-05-11
  • 打赏
  • 举报
回复
关注一下。
COM1能引起中断,说明代码没有问题。
MSCOMM和虚拟串口不兼容?

mark一下。
miaopangzi 2009-05-11
  • 打赏
  • 举报
回复
还有:
BEGIN_EVENTSINK_MAP(CCharTerminalDlg, CDialog)
ON_EVENT(CCharTerminalDlg, ID_COMMCTRL, 1, OnCommMscomm, VTS_NONE)
END_EVENTSINK_MAP()
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
您好,我看了你的代码,我是在OnComm函数体中第一行处加的断点,
没有响应,说明OnComm没有被触发啊!~~~

void CMyQQDlg::OnOnCommMscommGprs()
{
// TODO: Add your control notification handler code here
断点==>DWORD InBufferCount;

miaopangzi 2009-05-11
  • 打赏
  • 举报
回复
还有:
BEGIN_EVENTSINK_MAP(CCharTerminalDlg, CDialog)
ON_EVENT(CCharTerminalDlg, ID_COMMCTRL, 1, OnCommMscomm, VTS_NONE)
END_EVENTSINK_MAP()
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
首先谢谢你的回复,我按你说的做了,OnComm事件还是没有任何响应。
我又尝试把m_msGPRS.SetCommPort(5); //选择com5 语句改为m_msGPRS.SetCommPort(1); //选择com1
然后利用串口助手从COM5发送数据到COM1,结果OnComm事件却可以触发,
这是为什么呢?COM1和COM5的区别只是一个是物理串口一个是虚拟串口,如果是虚拟串口不可以的话,
那为什么串口助手却没有问题呢?在线等大家的帮助
miaopangzi 2009-05-11
  • 打赏
  • 举报
回复
以前用控件做的一个例子,你参考一下。
void CCharTerminalDlg::OnCommMscomm()
{
VARIANT vResponse;
char *str;
char *str1;
int k, nEvent, i;

nEvent = m_Com.GetCommEvent();

switch(nEvent)
{
case 2: //收到大于RTHresshold个字符
k = m_Com.GetInBufferCount(); //接收到的字符数目

if(k > 0)
{
vResponse=m_Com.GetInput(); //read
//对数据进行其他处理
str = (char*)(unsigned char*) vResponse.parray->pvData;
}
// 接收到字符,MSComm控件发送事件
i = 0;
str1 = str;
while (i < k)
{
i++;
str1++;
}
*str1 = '\0';
m_strReceive = (const char *)str;
//清除字符串中的不必要字符
break;
case 3: //CTS线状态发生了变化
break;
case 4: //DSR线状态发生了变化
break;
case 5: //CD线状态发生了变化
break;
case 6: //Ring Indicator发生变化
break;
}

UpdateData(FALSE);
m_nEdit.Invalidate();
}
一条晚起的虫 2009-05-11
  • 打赏
  • 举报
回复
SetInputLen(0) ;//改为1试试看
//mscomm不太熟,一般用API
程序员小哈 2009-05-11
  • 打赏
  • 举报
回复
自己UP一下,我刚才又验证了一下,打开串口之后我设置了一个定时器,然后利用串口助手发送数据,利用下面代码:

DWORD InBufferCount;
InBufferCount=m_msGPRS.GetInBufferCount();
CString str;
str.Format("%d",InBufferCount);
AfxMessageBox(str);

发现缓存中有数据,但是为什么没有触发我的OnComm事件呢?是我参数哪里设置的不对吗?

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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