急!龚建伟关于串口通信的程序有问题的,期望高手解决!
按照龚建伟个人主页的《串口调试助手源程序及编程详细过程》一步步编程,编译通过,运行时候,只要点发送就会出错,找不到原因!(之前我将串口23角连好了,用龚建伟的串口调试助手...
按照龚建伟个人主页的 《串口调试助手源程序及编程详细过程》 一步步编程,编译通过,运行时候,只要点发送就会出错,找不到原因!(之前我将串口2 3角连好了,用龚建伟的 串口调试助手 实验成功!)
我怀疑出错在两个地方:
1.响应函数出错!
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{ ////////以下你可以根据自己的通信协议加入处理代码
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k<len;k++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_strRXData+=strtemp; //加入接收编辑框对应字符串
}
}
UpdateData(FALSE); //更新编辑框内容
}
分布调试,怀疑以下三句中有问题的:
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
2. 怀疑打开串口初始化中有问题的
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);
m_ctrlComm.SetCommPort(1); //选择com1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");
m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位
m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据
m_ctrlComm.SetRThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
请高手赐教啊!另外哪位有龚建伟串口调试助手的源代码能否提供也好啊,我的邮箱是sunyangguan@tom.com
非常感谢!
魔高丈你好!我知道原因了,龚建伟给的程序只有发没有收!我把串口2 3 线连接好后,实验不成功。但是我与另一台计算机连接,另外一台使用串口助手,就可以接收到。
那么,接收语句是啥呢?请指教!谢谢
魔高丈你好!我仔细看了你给我的程序,发现情况是这样的:
之前只能发不能收的原因是:1.我看了你的程序,发现没有在ClassWizard 中给IDC_MSCOMM1添加OnComm消息,因此我直接在类CCuteComDlg中添加响应函数void CCuteComDlg::OnComm(),但是又没有添加你刚说的 串口控件的事件映射 的语句,所以每次运行时候程序根本没有走到void CCuteComDlg::OnComm()函数,所以根本接收不了。
现在的问题是我添加了 串口控件的事件映射 的语句以后,程序可以走到OnComm()函数了,但是老问题又出现了,报错,我分部调试,发现问题就出现在
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
程序走不过这里,走过这就报错:
Unhandled exception in .exe
另外我在网上下了一个小程序(非串口助手),也是龚建伟做的,出现完全相同的问题,难道是我的机子设置方面有问题?请指教,谢谢! 展开
我怀疑出错在两个地方:
1.响应函数出错!
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{ ////////以下你可以根据自己的通信协议加入处理代码
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k<len;k++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_strRXData+=strtemp; //加入接收编辑框对应字符串
}
}
UpdateData(FALSE); //更新编辑框内容
}
分布调试,怀疑以下三句中有问题的:
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
2. 怀疑打开串口初始化中有问题的
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);
m_ctrlComm.SetCommPort(1); //选择com1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");
m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位
m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据
m_ctrlComm.SetRThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
请高手赐教啊!另外哪位有龚建伟串口调试助手的源代码能否提供也好啊,我的邮箱是sunyangguan@tom.com
非常感谢!
魔高丈你好!我知道原因了,龚建伟给的程序只有发没有收!我把串口2 3 线连接好后,实验不成功。但是我与另一台计算机连接,另外一台使用串口助手,就可以接收到。
那么,接收语句是啥呢?请指教!谢谢
魔高丈你好!我仔细看了你给我的程序,发现情况是这样的:
之前只能发不能收的原因是:1.我看了你的程序,发现没有在ClassWizard 中给IDC_MSCOMM1添加OnComm消息,因此我直接在类CCuteComDlg中添加响应函数void CCuteComDlg::OnComm(),但是又没有添加你刚说的 串口控件的事件映射 的语句,所以每次运行时候程序根本没有走到void CCuteComDlg::OnComm()函数,所以根本接收不了。
现在的问题是我添加了 串口控件的事件映射 的语句以后,程序可以走到OnComm()函数了,但是老问题又出现了,报错,我分部调试,发现问题就出现在
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
程序走不过这里,走过这就报错:
Unhandled exception in .exe
另外我在网上下了一个小程序(非串口助手),也是龚建伟做的,出现完全相同的问题,难道是我的机子设置方面有问题?请指教,谢谢! 展开
3个回答
展开全部
粗略的看了一下,你的代码没有问题,我怀疑是其他的地方出现了问题。
给你一个我以前写的,模仿串口调试助手用串口控件的方法写的程序,你参考一下吧。
代码已发到你的邮箱。
补充:
接收就是在OnComm() 函数里啊,你的这段代码没有什么问题。
有没有做串口控件的事件映射啊:
BEGIN_EVENTSINK_MAP(CCuteComDlg, CDialog)
ON_EVENT(CCuteComDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
END_EVENTSINK_MAP()
如果有的话,那接收应该没有问题的。况且即使只有发没有收,那也不会点发送就会出错的。
我发给你的代码你看到了吗,那是标准串口控件的用法,里面收发演示都有的,你详细看一下吧,应该是对你有所帮助的。
有人说是因为龚建伟的串口初始化部分代码有问题,才导致了后面的安全数组出现错误。
我一直是使用如下代码进行串口控件的初始化的,已经应用到过很多程序中没有出现过问题,你可以试试:
if(m_ctrlComm.get_PortOpen())
m_ctrlComm.put_PortOpen(FALSE);
m_ctrlComm.put_CommPort(1); //选择com1
//输出方式为二进制方式
m_ctrlComm.put_InputMode(1);//text,binary
//m_ctrlComm.put_InBufferSize(64);
//m_ctrlComm.put_OutBufferSize(512);
m_ctrlComm.put_Settings("9600,n,8,1"); //波特率9600,无校验ndo,8个数据位,1个停止位
if( !m_ctrlComm.get_PortOpen())
m_ctrlComm.put_PortOpen(TRUE);//打开串口
m_ctrlComm.put_RThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.put_InputLen(0); //设置当前接收区数据长度为0
//0---读接收缓冲区的所有内容
//n---读接收缓冲区的 n 个字符(或二进制码)
m_ctrlComm.get_Input();//先预读缓冲区以清除残留数据
这是VS2008中的代码,在VC6.0中请把函数前缀get_替换为Get、put_替换为Set
给你一个我以前写的,模仿串口调试助手用串口控件的方法写的程序,你参考一下吧。
代码已发到你的邮箱。
补充:
接收就是在OnComm() 函数里啊,你的这段代码没有什么问题。
有没有做串口控件的事件映射啊:
BEGIN_EVENTSINK_MAP(CCuteComDlg, CDialog)
ON_EVENT(CCuteComDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
END_EVENTSINK_MAP()
如果有的话,那接收应该没有问题的。况且即使只有发没有收,那也不会点发送就会出错的。
我发给你的代码你看到了吗,那是标准串口控件的用法,里面收发演示都有的,你详细看一下吧,应该是对你有所帮助的。
有人说是因为龚建伟的串口初始化部分代码有问题,才导致了后面的安全数组出现错误。
我一直是使用如下代码进行串口控件的初始化的,已经应用到过很多程序中没有出现过问题,你可以试试:
if(m_ctrlComm.get_PortOpen())
m_ctrlComm.put_PortOpen(FALSE);
m_ctrlComm.put_CommPort(1); //选择com1
//输出方式为二进制方式
m_ctrlComm.put_InputMode(1);//text,binary
//m_ctrlComm.put_InBufferSize(64);
//m_ctrlComm.put_OutBufferSize(512);
m_ctrlComm.put_Settings("9600,n,8,1"); //波特率9600,无校验ndo,8个数据位,1个停止位
if( !m_ctrlComm.get_PortOpen())
m_ctrlComm.put_PortOpen(TRUE);//打开串口
m_ctrlComm.put_RThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.put_InputLen(0); //设置当前接收区数据长度为0
//0---读接收缓冲区的所有内容
//n---读接收缓冲区的 n 个字符(或二进制码)
m_ctrlComm.get_Input();//先预读缓冲区以清除残留数据
这是VS2008中的代码,在VC6.0中请把函数前缀get_替换为Get、put_替换为Set
2012-12-17
展开全部
试下把工程改成Release的版本编译,我发现release之后,还原为debug都能通过了!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1)主要是初始化的顺序有问题,并非安全数组的原因,有一个setinputmodel的没设置,所以出了这样的问题,设置以后就没有问题了。
2)接收部分有问题,请参考修改后程序,现在是只收三个字节!
修改完善后的代码:
BOOL CSerTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_ctrlComm.SetCommPort(4);
m_ctrlComm.SetInBufferSize(1024);
m_ctrlComm.SetOutBufferSize(512);
if(!m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);
m_ctrlComm.SetInputMode(1); //设置输入方式为二进制方式
m_ctrlComm.SetSettings("2400,n,8,1");
m_ctrlComm.SetRThreshold(1);
m_ctrlComm.SetInputLen(0);
//m_ctrlComm.GetInput();
return TRUE;
}
void CSerTestDlg::OnComm()
{
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG k,len;
char* str;
BYTE rxdata[2048];
BYTE receiver[3];
CString strtemp;
CString strtemp1;
CString strtemp2;
if(m_ctrlComm.GetCommEvent()==2)
{
k=m_ctrlComm.GetInBufferCount();
if(k>0)
{
variant_inp=m_ctrlComm.GetInput();
safearray_inp=variant_inp;
str=(char*)(unsigned char*)variant_inp.parray->pvData;
}
for(long i=0;i<3;i++)//收3个字节,若收多个,请改动这个大小!
{
safearray_inp.GetElement(&i,receiver+i);
}
strtemp.Format("%2X",receiver[0]);
strtemp1.Format("%2X",receiver[1]);
strtemp2.Format("%2X",receiver[2]);
m_strEditRXData=strtemp+strtemp1+strtemp2;
UpdateData(FALSE);
}
}
一个最简单的收发例程已发至你邮箱了
2)接收部分有问题,请参考修改后程序,现在是只收三个字节!
修改完善后的代码:
BOOL CSerTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_ctrlComm.SetCommPort(4);
m_ctrlComm.SetInBufferSize(1024);
m_ctrlComm.SetOutBufferSize(512);
if(!m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);
m_ctrlComm.SetInputMode(1); //设置输入方式为二进制方式
m_ctrlComm.SetSettings("2400,n,8,1");
m_ctrlComm.SetRThreshold(1);
m_ctrlComm.SetInputLen(0);
//m_ctrlComm.GetInput();
return TRUE;
}
void CSerTestDlg::OnComm()
{
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG k,len;
char* str;
BYTE rxdata[2048];
BYTE receiver[3];
CString strtemp;
CString strtemp1;
CString strtemp2;
if(m_ctrlComm.GetCommEvent()==2)
{
k=m_ctrlComm.GetInBufferCount();
if(k>0)
{
variant_inp=m_ctrlComm.GetInput();
safearray_inp=variant_inp;
str=(char*)(unsigned char*)variant_inp.parray->pvData;
}
for(long i=0;i<3;i++)//收3个字节,若收多个,请改动这个大小!
{
safearray_inp.GetElement(&i,receiver+i);
}
strtemp.Format("%2X",receiver[0]);
strtemp1.Format("%2X",receiver[1]);
strtemp2.Format("%2X",receiver[2]);
m_strEditRXData=strtemp+strtemp1+strtemp2;
UpdateData(FALSE);
}
}
一个最简单的收发例程已发至你邮箱了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询