各位高手 小弟在做串口编程的时候 发现自己的串口 串口已经打开 可是在捕获 MsComde 的事件的时候发现 它的事件始终是 5 不可能进入 2的状态 下面是小弟写的一些代码 希望高手指点 小弟现在很迷茫!
m_ctlMSComm.GetPortOpen() // m_ctlMSComm 为MsComm的对象OpenPort()
{ if(m_ctlMSComm.GetPortOpen())
m_ctlMSComm.SetPortOpen(FALSE); m_ctlMSComm.SetCommPort(m_1); //选择com1
if( !m_ctlMSComm.GetPortOpen())
m_ctlMSComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port"); m_ctlMSComm.SetSettings(m_strBaudRate); //波特率9600,无校验,8个数据位,1个停止位
m_ctlMSComm.SetRThreshold(1);
m_ctlMSComm.SetInputMode(1);
m_ctlMSComm.SetInputLen(1024); //设置当前接收区数据长度为0
m_ctlMSComm.GetInput();//先预读缓冲区以清除残留数据
}在MsComm的事件处理如下
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(/*m_ctlMSComm.GetCommEvent()==5 || */m_ctlMSComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp = m_ctlMSComm.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=*(BYTE*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放 m_strReceive += bt; //加入接收编辑框对应字符串
}
m_strReceive += "\r\n";
AfxGetMainWnd()->SetWindowText(m_strReceive);
}各位不够在加 小弟很着急 迷茫ing.....
m_ctlMSComm.GetPortOpen() // m_ctlMSComm 为MsComm的对象OpenPort()
{ if(m_ctlMSComm.GetPortOpen())
m_ctlMSComm.SetPortOpen(FALSE); m_ctlMSComm.SetCommPort(m_1); //选择com1
if( !m_ctlMSComm.GetPortOpen())
m_ctlMSComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port"); m_ctlMSComm.SetSettings(m_strBaudRate); //波特率9600,无校验,8个数据位,1个停止位
m_ctlMSComm.SetRThreshold(1);
m_ctlMSComm.SetInputMode(1);
m_ctlMSComm.SetInputLen(1024); //设置当前接收区数据长度为0
m_ctlMSComm.GetInput();//先预读缓冲区以清除残留数据
}在MsComm的事件处理如下
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(/*m_ctlMSComm.GetCommEvent()==5 || */m_ctlMSComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp = m_ctlMSComm.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=*(BYTE*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放 m_strReceive += bt; //加入接收编辑框对应字符串
}
m_strReceive += "\r\n";
AfxGetMainWnd()->SetWindowText(m_strReceive);
}各位不够在加 小弟很着急 迷茫ing.....
解决方案 »
- 如何判断一个char数组中是否含有数据?
- 讨论vc创建隐藏的IE窗口并模拟地址栏回车按键
- 请教一个 svn or CVS的问题 === 我有一个模块,添加了新的功能, 不想让别人知道,我做失败了 就把他miss 掉
- 请大侠帮忙!! 先用shellexecute打开一个文件,在关闭此文件时如何删除它??
- 热切期盼CSDN的下一版面世。提几个改版建议。
- C sdk程序,但运行时窗口只能点击上面的两个按纽,其它连窗口都无法聚焦.帮忙看看.
- 关于冲击波病毒
- 菜鸟问题: 怎样禁用CDialog右上角的关闭按钮?
- 指针内存的清除
- 很值得思考的问题,关于DLL加载和HOOK的问题!
- 对于非CEdit,CStatic等不能相应WM_GETTEXT消息的窗口如何取得其内容?
- 如何屏蔽钩子?
(中国计算机报 李湘江 2001年10月25日 17:33)在工业控制中,串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。 本文将介绍在Windows平台下串行通信的工作机制和用Visual C++设计串行通信程序的编程方法及通信方式。 VC中实现串行通信的编程技术
以下我们将介绍VC中几种实现串行通信的编程技术: 利用VC++的标准通信函数 利用VC++的标准通信函数_inp和_outp可实现串口通信。下面是一个串口初始化的程序: void init_com(PORT)
{char i;
outp(PORT+3,0x80);
outp(PORT,0x0C);
outp(PORT+1,0);
outp(PORT+3 ,0x3a);
outp(PORT+3 ,0x03);
i=inp(PORT+5) && 0xfe;
outp(PORT+5,i);} 使用串行通信控件MSComm 串行通信控件MSCOmm32.OCX提供了使用RS-232来进行数据通信的所有协议,VC为该控件提供了标准的事件处理函数、过程,并通过属性和方法提供了串行通信的设置。它使用户能够方便地访问Windows串行通信驱动程序的大多数特性,包括输入、输出缓冲区的大小及决定何时使用流控制命令挂起数据传输等。 在ClassWizard中为新创建的通信控件定义成员对象(CMSComm m_Serial),通过该对象便可以对串口属性进行设置,MSComm控件共有27个属性。以下是通过设置控件属性对串口进行初始化的实例: BOOL CSampleDlg:: PortOpen()
{ BOOL m_Opened;
......
m_Serial.SetCommPort(2); // 指定串口号
m_Serial.SetSettings("4800,N,8,1");
// 通信参数设置
m_Serial.SetInBufferSize(1024);
// 指定接收缓冲区大小
m_Serial.SetInBufferCount(0);
// 清空接收缓冲区
m_Serial.InputMode(1);
// 设置数据获取方式
m_Serial.SetInputLen(0);
// 设置读取方式
m_Opened=m_Serail.SetPortOpen(1);
// 打开指定的串口
return m_Opened;} 打开所需串口后,我们需要考虑串口通信的时机。在接收或发送数据过程中,可能需要监视并响应一些事件和错误,所以事件驱动是处理串行端口交互作用的一种非常有效的方法。使用OnComm事件和CommEvent属性捕捉并检查通信事件和错误的值。发生通信事件或错误时将触发OnComm事件,CommEvent属性的值将被改变,应用程序通过检查CommEvent属性值并作出相应的反应。 使用API函数 控件虽然简单易用,但由于必须拿到对话框中使用,在一些需要在线程中实现通信的应用场合下,控件的使用显得捉襟见肘。API是附带在Windows内部的一个极其重要的组成部分。Windows的32位API主要是一系列很复杂的函数和消息集合。它可以看作是Windows系统为在其下运行的各种开发系统提供的开放式通用功能增强接口。 通信程序在CreateFile处指定串口设备及相关的操作属性,再返回一个句柄,该句柄将被用于后续的通信操作,并贯穿整个通信过程。串口打开后,其属性被设置为默认值,根据具体需要,通过调用GetCommState(hComm,&&dcb)读取当前串口设备控制块DCB设置,修改后通过SetCommState(hComm,&&dcb)将其写入。运用ReadFile()与WriteFile()这两个API函数实现串口读写操作,若为异步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,调用GetLastError()函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用WaitForSingleObject()来等待结束信号并设置最长等待时间,举例如下: BOOL bReadStatus;
bReadStatus = ReadFile( m_hIDComDev, buffer,
dwBytesRead, &&dwBytesRead, &&m_OverlappedRead );
if(!bReadStatus){
if(GetLastError()==ERROR_IO_PENDING){
WaitForSingleObject(m_OverlappedRead.hEvent,1000);
return ((int)dwBytesRead);}
return(0);}
return ((int)dwBytesRead); 多线程下实现串行通信
Windows内部的抢先调度程序在活动的线程之间分配CPU时间,Windows区分两种不同类型的线程,一种是用户界面线程(User Interface Thread),它包含消息循环或消息泵,用于处理接收到的消息;另一种是工作线程(Work Thread),它没有消息循环,用于执行后台任务、监视串口事件的线程即为工作线程。 多线程程序的编写在端口的配置,连接部分与单线程的相同,在端口配置完毕后,最重要的是根据实际情况,建立多线程之间的同步对象,如信号灯、临界区和事件等。 一切就绪后即可启动工作线程,程序如下: CWinThrea CommThread = AfxBegin
Thread(CommWatchThread, // 线程函数名
(LPVOID) m_pTTYInfo, // 传递的参数
THREAD_PRIORITY_ABOVE_NORMAL,
// 设置线程优先级
(UINT) 0, // 最大堆栈大小
(DWORD) CREATE_SUSPENDED , // 创建标志
(LPSECURITY_ATTRIBUTES) NULL);
if(WaitCommEvent(pTTYInfo->idComDev,&&dwEvtMask,NULL))
{
if((dwEvtMask && pTTYInfo->dwEvtMask )== pTTYInfo->dwEvtMask)
{
WaitForSingleObject(pTTYInfo->hPostEvent,0xFFFFFFFF);
ResetEvent(pTTYInfo->hPostEvent);
// 置同步事件对象为非信号态
::PostMessage(CSampleView,ID_COM1_DATA,0,0); // 发送通知消息}}
BEGIN_MESSAGE_MAP(CSampleView, CView)
//{{AFX_MSG_MAP(CSampleView)
ON_MESSAGE(ID_COM1_DATA, OnProcessCom1Data)
ON_MESSAGE(ID_COM2_DATA, OnProcessCom2Data)
.....
//}}AFX_MSG_MAP
END_MESSAGE_MAP() 多线程的实现可以使得各端口独立,准确地实现串行通信,使串行通信具有更广泛的灵活性与严格性,且充分利用CPU时间。但在具体的实时监控系统中如何协调多个线程、线程之间以何种方式实现同步,这是多线程串行通信程序实现的难点。 串行通信的操作方式
下面我们将介绍串行通信的几种操作方式: 编辑 吴北 [email protected])
及编程详细过程
作者:龚建伟 可以任意转载,注明作者和说明来自 ◆龚建伟技术主页◆
http://www.csdn.net/develop/article/10/10199.shtm
comEvSend 1 发送事件。
comEvReceive 2 接收事件。
comEvCTS 3 clear-to-send 线变化。
comEvDSR 4 data-set ready 线变化。
comEvCD 5 carrier detect 线变化。
comEvRing 6 振铃检测。
comEvEOF 7 文件结束。怎么会是5的事件,你的窗口怎么连接的