Sorry, you have been blocked

You are unable to access 57tao.net

Why have I been blocked?

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?

You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.

国产PLC精品-海微自动化>>新闻中心
综合资讯    
行业动态  
 
   
当前位置:首页 - 新闻中心 -   行业动态  
Windows CE下的串口通讯实例
文: 来源:集团内部 时间:2009-05-06 点击:1383
Windows CE下的串口通讯实例
串行通讯是目前计算机、通信和控制领域最基本的通信方式。经常有人提问该到哪找串口通讯例子,其实这个问题一般的回答是给你提供一个Pocket PC 2002的SDK例子程序。但到底SDK的程序和MFC的结构有很大的不同,对于想用MFC编写通信程序的人来说也不是很便利。
另一方面,由于Windows CE是一个基于Unicode的操作系统,并且Windows CE不支持Windows下常用的串行通信重叠I/O方式(OVERLAPPED),因此编写Windows CE下的串口通讯类有一些与桌面Windows不同的地方。
该程序是基于“主动发送请求,被动接收响应”的假设,因此只设置了一个接收数据的线程。
源代码如下:
头文件Serial.h
// Serial.h: interface for the CSerial class.
//
//////////////////////////////////////////////////////////////////////
 
#if !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
#define AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
DWORD WINAPI ReadPortThread(LPVOID lpvoid); //读数据线程
 
class CSerial
{
public:
       BOOL InitCommTimeouts(); //设置超时参数
       BOOL InitDCB(); //配置串口
       BOOL m_bConnected;
       BOOL ClosePort(HANDLE hCommPort); //关闭串口
       DWORD WritePort(TCHAR *buf,DWORD dwBytesToWrite); //写数据
       BOOL OpenPort(LPTSTR lpszPortName); //打开串口
       CSerial();
       HANDLE hReadThread;
       virtual ~CSerial();  
};
 
#endif // !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
 
 
 
源文件:Serial.cpp
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////
 
#include "stdafx.h"
#include "Serial.h"
 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
 
HANDLE hPort;
CString strInChar;
 
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
 
CSerial::CSerial()
{
 
}
 
CSerial::~CSerial()
{
       if(hPort != INVALID_HANDLE_VALUE)
              ClosePort(hPort);
}
 
BOOL CSerial::OpenPort(LPTSTR lpszPortName)
{
       DWORD dwError,
               dwThreadID;
      
       if(hPort)
       {
              return FALSE;
       }
 
       //打开串口
       hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,
                                           0, NULL, OPEN_EXISTING,0, NULL);
       //如果打开端口出错, 返回FALSE
       if ( hPort == INVALID_HANDLE_VALUE )
       {
              //不能打开端口
              CString strError;
              strError.Format(_T("Unable to open %s, Error No.=%d"),
                                           lpszPortName, GetLastError());
 
              MessageBox (NULL, strError,      TEXT("Error"), MB_OK);
 
              return FALSE;
       }
 
       //指定端口监测的事件集
       SetCommMask (hPort, EV_RXCHAR);
       //分配设备缓冲区
       SetupComm(hPort,512,512);
       //初始化缓冲区中的信息
       PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
 
       //配置串行端口
       if(!InitDCB())
              return FALSE;
 
       //设置端口超时值
       if(!InitCommTimeouts())
              return FALSE;
 
       //设置端口上指定信号的状态
       // SETDTR: 发送DTR (data-terminal-ready)信号
       // SETRTS: 发送RTS (request-to-send)信号
       EscapeCommFunction (hPort, SETDTR);
       EscapeCommFunction (hPort, SETRTS);
 
       //创建一个从串口读取数据的线程
       if (hReadThread = CreateThread (NULL, 0, ReadPortThread, 0, 0,
                                                                &dwThreadID))
       {
       }
       else
       {
              //不能创建线程
              MessageBox (NULL, TEXT("Unable to create the read thread"),
                                   TEXT("Error"), MB_OK);
              dwError = GetLastError ();
              return FALSE;
       }
 
       m_bConnected=TRUE;
      
       return TRUE;
}
 
DWORD CSerial::WritePort(TCHAR *buf,DWORD dwCharToWrite)
{
       BOOL fWriteState;
       DWORD dwBytesWritten;
 
       //写入数据
       fWriteState=WriteFile(hPort,buf,dwCharToWrite*sizeof(TCHAR),&dwBytesWritten,NULL);
       if(!fWriteState)
       {
              //不能写数据
              MessageBox(NULL,TEXT("Can't Write String to Comm"),TEXT("Error"),MB_OK);
              dwBytesWritten=0;
       }
 
       return dwBytesWritten;
}
 
DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
       BOOL fReadState;
       DWORD dwCommModemStatus;
 
       DWORD dwLength;
       COMSTAT ComStat;
       DWORD dwErrorFlags;
 
       while (hPort != INVALID_HANDLE_VALUE)
       {
              //等待串口的事件发生
              WaitCommEvent (hPort, &dwCommModemStatus, 0);
 
              if (dwCommModemStatus & EV_RXCHAR)
              {
                     ClearCommError(hPort,&dwErrorFlags,&ComStat);
                     //cbInQue返回在串行驱动程序输入队列中的字符数
                     dwLength=ComStat.cbInQue;
 
                     if(dwLength>0)
                     {
                            //从串口读取数据
                            TCHAR* buf=new TCHAR[256];
                            fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
                            if(!fReadState)
                            {
                                   //不能从串口读取数据
                                   MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
                            }
                            else
                            {
                                   //把数据赋值给全局变量
                                   strInChar=buf;
                            }
                            delete[] buf;
                     }    
              }
             
              GetCommModemStatus (hPort, &dwCommModemStatus);
       }
 
       return 0;
}
 
BOOL CSerial::ClosePort(HANDLE hCommPort)
{
       if (hCommPort != INVALID_HANDLE_VALUE)
       {
              //设置连接属性为FALSE
              m_bConnected=FALSE;
 
              //结束线程中WaitCommEvent的等待
              SetCommMask(hPort,0);
             
              //阻塞至线程停止
              if(hReadThread)
              {
                     TerminateThread(hReadThread,0);
                     CloseHandle(hReadThread);
              }
             
              //清除端口上指定信号的状态
              EscapeCommFunction(hPort,CLRDTR);
              EscapeCommFunction(hPort,CLRRTS);
              //清除驱动程序内部的发送和接收队列
              PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
 
              //关闭串口
              CloseHandle (hCommPort);
              hCommPort = INVALID_HANDLE_VALUE;
 
              return TRUE;
       }
       else
       {
              return TRUE;
       }
}
 
BOOL CSerial::InitDCB()
{
       DCB PortDCB;
       DWORD dwError;
 
       PortDCB.DCBlength = sizeof (DCB);    
 
       //得到端口的默认设置信息
       GetCommState (hPort, &PortDCB);
 
       //改变DCB结构设置
       PortDCB.BaudRate = 19200;               //波特率
       PortDCB.fBinary = TRUE;                 //Win32不支持非二进制串行传输模式,必须为TRUE
       PortDCB.fParity = TRUE;                 //启用奇偶校验
       PortDCB.fOutxCtsFlow = TRUE;            //串行端口的输出由CTS线控制
       PortDCB.fOutxDsrFlow = FALSE;           //关闭串行端口的DSR流控制
       PortDCB.fDtrControl = DTR_CONTROL_ENABLE;   //启用DTR线
       PortDCB.fDsrSensitivity = FALSE;        //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
       //PortDCB.fTXContinueOnXoff = TRUE;       //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
       PortDCB.fTXContinueOnXoff = FALSE;
       PortDCB.fOutX = FALSE;                  //设为TRUE指定XON/XOFF控制被用于控制串行输出
       PortDCB.fInX = FALSE;                   //设为TRUE指定XON/XOFF控制被用于控制串行输入
       PortDCB.fErrorChar = FALSE;             //WINCE串行驱动程序的默认执行将忽略这个字段
       PortDCB.fNull = FALSE;                  //设为TRUE将使串行驱动程序忽略收到的空字节
       PortDCB.fRtsControl = RTS_CONTROL_ENABLE;   //启用RTS线
       PortDCB.fAbortOnError = FALSE;          //WINCE串行驱动程序的默认执行将忽略这个字段
       PortDCB.ByteSize = 8;                   //每字节的位数
       PortDCB.Parity = NOPARITY;              //无奇偶校验
       PortDCB.StopBits = ONESTOPBIT;          //每字节一位停止位
 
       //根据DCB结构配置端口
       if (!SetCommState (hPort, &PortDCB))
       {
              //不能配置串行端口
              MessageBox (NULL, TEXT("Unable to configure the serial port"),
                                   TEXT("Error"), MB_OK);
              dwError = GetLastError ();
              return FALSE;
       }
 
       return TRUE;
}
 
BOOL CSerial::InitCommTimeouts()
{
       COMMTIMEOUTS CommTimeouts;
       DWORD dwError;
 
       //得到超时参数
       GetCommTimeouts (hPort, &CommTimeouts);
 
       //改变COMMTIMEOUTS结构设置
       CommTimeouts.ReadIntervalTimeout = MAXDWORD;
       CommTimeouts.ReadTotalTimeoutMultiplier = 0;
       CommTimeouts.ReadTotalTimeoutConstant = 0;   
       CommTimeouts.WriteTotalTimeoutMultiplier = 10;
       CommTimeouts.WriteTotalTimeoutConstant = 1000;   
 
       //设置端口超时值
       if (!SetCommTimeouts (hPort, &CommTimeouts))
       {
              //不能设置超时值
              MessageBox (NULL, TEXT("Unable to set the time-out parameters"),
                                   TEXT("Error"), MB_OK);
              dwError = GetLastError ();
              return FALSE;
       }
 
       return TRUE;
}
 
以上类代码在eMbedded Visual C++4.0和基于ARM9的三星S3C2410开发板(运行Windows CE.NET 4.1)上测试通过。
 
    返回首页 | 信息中心 | 解决方案 | 客服中心 | 下载中心 | 联系我们 |    

Copyright (C) 2008 hiwee automatization All Rights Reserved.
电子邮件:hiwee@21cn.com :: luohaimeng@126.com