添加串口主要有以下几个参数:
1.串口名称(PortName)
2.波特率(BaudRate)
3.数据位(DataBits)
4.奇偶效应(Parity)
5.停止位(StopBits)
1 using System
2 using System.Collections.Generic
3 using System.Linq
4 using System.Text
5 using System.Windows
6 using System.Windows.Controls
7 using System.Windows.Data
8 using System.Windows.Documents
9 using System.Windows.Input
10 using System.Windows.Media
11 using System.Windows.Media.Imaging
12 using System.Windows.Navigation
13 using System.Windows.Shapes
14 using System.IO.Ports
15
16 namespace CsharpComm
17 {
18 /// <summary>
19 /// Window1.xaml 的交互逻辑
20 /// </summary>
21 public partial class Window1 : Window
22 {
23 public Window1()
24 {
25 InitializeComponent()
26 }
27
28 //定义 SerialPort对象
29 SerialPort port1
30
31 //初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型
32 public void InitCOM(string PortName)
33 {
34 port1 = new SerialPort(PortName)
35 port1.BaudRate = 9600//波特率
36 port1.Parity = Parity.None//无奇偶校验位
37 port1.StopBits = StopBits.Two//两个停止位
38 port1.Handshake = Handshake.RequestToSend//控制协议
39 port1.ReceivedBytesThreshold = 4//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
40 port1.DataReceived += new SerialDataReceivedEventHandler(port1_DataReceived)//DataReceived事件委托
41 }
42
43 //DataReceived事件委托方法
44 private void port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
45 {
46 try
47 {
48 StringBuilder currentline = new StringBuilder()
49 //循环接收数据
50 while (port1.BytesToRead >0)
51 {
52 char ch = (char)port1.ReadByte()
53 currentline.Append(ch)
54 }
55 //在这里对接收到的数据进行处理
56 //
57 currentline = new StringBuilder()
58 }
59 catch(Exception ex)
60 {
61 Console.WriteLine(ex.Message.ToString())
62 }
63
64 }
65
66 //打开串口的方法
67 public void OpenPort()
68 {
69 try
70 {
71 port1.Open()
72 }
73 catch { }
74 if (port1.IsOpen)
75 {
76 Console.WriteLine("the port is opened!")
77 }
78 else
79 {
80 Console.WriteLine("failure to open the port!")
81 }
82 }
83
84 //关闭串口的方法
85 public void ClosePort()
86 {
87 port1.Close()
88 if (!port1.IsOpen)
89 {
90 Console.WriteLine("the port is already closed!")
91 }
92 }
93
94 //向串口发送数据
95 public void SendCommand(string CommandString)
96 {
97 byte[] WriteBuffer = Encoding.ASCII.GetBytes(CommandString)
98 port1.Write(WriteBuffer, 0, WriteBuffer.Length)
99 }
100
101 //调用实例
102 private void btnOpen_Click(object sender, RoutedEventArgs e)
103 {
104 //我现在用的COM1端口,按需要可改成COM2,COM3
105 InitCOM("COM1")
106 OpenPort()
107 }
108 }
109 }
基本方法是使用CreateFile来建立一个串口文件,然后用overlap的方式进行读写#define SERAIL_PORT_BUF_MAX (1024*8)
typedef HRESULT (*PFN_CMD_PARSE_DATA)(HANDLE hParseApp, LPCSTR szRspCmd, int nCmdLen)
class CUsbSrvApp// : public CWinApp
{
public:
CUsbSrvApp()
~CUsbSrvApp()
BOOL OnSendData(const char *szBuf, int nLen)// 发送数据
int ComConnect(CString strPort)// 连接COM口
HANDLE OpenComPort(CString strPort, int nBaudRate, int nDataBits, int nStopBits, int nParity, int nFlowCtrlType)// 打开串口
void Close()// 关闭串口
HANDLE m_hCom
BOOL m_bConnected
OVERLAPPED m_OverlappedRead
OVERLAPPED m_OverlappedWrite
CWinThread *m_pThread
PFN_CMD_PARSE_DATA m_pRspCmdFunc// 用来处理接受数据的CALLBACK
HANDLE m_hParseApp
}
CUsbSrvApp::CUsbSrvApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
m_bConnected = false
m_hCom = NULL
m_pRspCmdFunc = NULL
}
CUsbSrvApp::~CUsbSrvApp()
{
}
//打开串口通信,并返回串口句柄
HANDLE CUsbSrvApp::OpenComPort(CString strPortName,
int nBaudRate,
int nDataBits,
int nStopBits,
int nParity,
int nFlowCtrlType)
{
DCB dcb
COMMTIMEOUTS CommTimeOuts
COMMCONFIG ComConfig
HANDLE hComPort
CString strPort
strPort.Format("\\\\.\\%s",strPortName)// COM口的文件名应该是 \\.\COMXX
//打开窗口其实就是创建一个文件
hComPort = CreateFile(strPort,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL)
if (INVALID_HANDLE_VALUE == hComPort)
return INVALID_HANDLE_VALUE
// 设置一些COM口通讯参数和OVERLAP
CommTimeOuts.ReadIntervalTimeout = -1
CommTimeOuts.ReadTotalTimeoutConstant = 0
CommTimeOuts.ReadTotalTimeoutMultiplier = 0
CommTimeOuts.WriteTotalTimeoutConstant = 0
CommTimeOuts.WriteTotalTimeoutMultiplier = 0x1388
SetCommTimeouts( m_hCom, &CommTimeOuts )
SetDefaultCommConfig(strPortName, &ComConfig, sizeof(COMMCONFIG))
GetCommState(m_hCom, &dcb )
dcb.BaudRate = nBaudRate
dcb.ByteSize = nDataBits
dcb.StopBits = nStopBits
dcb.fParity = (NOPARITY != nParity)
dcb.Parity = nParity
//set the receive char
dcb.EvtChar = 0x0D
switch(nFlowCtrlType)
{
case 0: //no flow control
break
case 1://HARD_FLOW_CTRL:
dcb.fOutxCtsFlow = TRUE
dcb.fOutxDsrFlow = TRUE
dcb.fDtrControl = DTR_CONTROL_DISABLE
dcb.fDsrSensitivity = TRUE
dcb.fRtsControl = RTS_CONTROL_TOGGLE
break
case 2://SOFT_FLOW_CTRL:
dcb.fOutX = TRUE
dcb.fInX = TRUE
break
}
BuildCommDCB(_T("baud=115200 parity=N data=8 stop=1"),&dcb)
SetCommState(hComPort, &dcb )
SetCommMask(hComPort, 0)
SetCommMask(hComPort, EV_RXCHAR|EV_CTS|EV_DSR|EV_RLSD|EV_RING)
SetupComm( hComPort, SERAIL_PORT_BUF_MAX,SERAIL_PORT_BUF_MAX)
//clear read and write buffer
PurgeComm( hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR )
return hComPort
}
void CUsbSrvApp::Close()
{
if(m_bConnected)
{
m_bConnected = false
CloseHandle(m_hCom)
m_hCom = NULL
}
}
// 这个线程是监视串口数据,一旦有数据则读取并调用CALLBACK通知客户端
UINT ReceiveComData(LPVOID pParam)
{
CUsbSrvApp *pUsbSrv = (CUsbSrvApp *)pParam
HANDLE hComPort = pUsbSrv->m_hCom
DWORD dwEvtMask=0
DWORD dwErrorFlags
SetCommMask( hComPort, EV_RXCHAR)
OVERLAPPED osRead
osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)
DWORD dwTransfer = 0
while(pUsbSrv->m_bConnected)
{
if( !WaitCommEvent( hComPort, &dwEvtMask,&osRead))
{
if( GetLastError()== ERROR_IO_PENDING)
{
WaitForSingleObject(osRead.hEvent, INFINITE)
if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)
{
COMSTAT ComStat={0}
DWORD dwReadLen = 0
DWORD dwBytesRead = 0
DWORD dwTotalLen = 0
ClearCommError(hComPort, &dwErrorFlags, &ComStat )
dwTotalLen = ComStat.cbInQue
dwReadLen = (SERAIL_PORT_BUF_MAX >dwTotalLen)?dwTotalLen:SERAIL_PORT_BUF_MAX
BYTE *pBuf = new BYTE[dwTotalLen+1]
memset(pBuf, 0 , dwTotalLen+1)
DWORD nReadBufLen=0
while(dwTotalLen>0)
{
if(FALSE == ReadFile( hComPort, pBuf+nReadBufLen,dwReadLen, &dwBytesRead,&pUsbSrv->m_OverlappedRead))
{
if(GetLastError() == ERROR_IO_PENDING)
{
GetOverlappedResult(hComPort,&osRead, &dwTransfer, TRUE )
}
break
}
nReadBufLen +=dwBytesRead
dwTotalLen -=dwBytesRead
dwReadLen -= dwBytesRead
dwReadLen = (SERAIL_PORT_BUF_MAX>dwReadLen)?dwReadLen:SERAIL_PORT_BUF_MAX
}
if(pUsbSrv->m_pRspCmdFunc!=NULL&&nReadBufLen!=0)
{
pUsbSrv->m_pRspCmdFunc(pUsbSrv->m_hParseApp, (char*)pBuf,nReadBufLen)
}
delete pBuf
ClearCommError(hComPort, &dwErrorFlags, &ComStat )
int len =0//= m_retList.GetSize()
}//endif if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)
}//endif if( GetLastError()== ERROR_IO_PENDING)
}//endif if( !WaitCommEvent( hComPort, &dwEvtMask,&o))
else
{
if(GetLastError() == ERROR_IO_PENDING) {
GetOverlappedResult(hComPort, &osRead, &dwTransfer, TRUE )// sleep thread
}
}
Sleep(1)
} //endwhile while(m_bConnected)
return 0
}
int CUsbSrvApp::ComConnect(CString strPort)
{
int nBaudRate = 115200
int nDataBits = 8
int nStopBits = 1
int nParity = 0
int nFlowCtrl = 1
if (NULL != m_hCom || m_bConnected)
{
return 0
}
m_hCom = OpenComPort(strPort,nBaudRate,nDataBits,nStopBits,nParity,nFlowCtrl)
if( INVALID_HANDLE_VALUE == m_hCom)
{
m_hCom = NULL
return 0
}
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) )
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) )
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL )
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL )
m_pThread = AfxBeginThread( ReceiveComData,(void*)this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED ,NULL )
if( NULL == m_pThread )
{
CloseHandle( m_hCom )
m_hCom = NULL
return FALSE
}
else
{
m_bConnected = TRUE
m_pThread->ResumeThread( )
}
return TRUE
}
int CUsbSrvApp::OnSendData(const char *szBuf, int nLen)
{
BOOL bWriteStat
BOOL bWrite = TRUE
DWORD dwBytesWrite = 0
DWORD dwBytesWritten = 0
int dwByteswrittenTotal = 0
if (NULL == m_hCom)
return 0
int nSentTimes=0
while(dwByteswrittenTotal<nLen&&nSentTimes<10)
{
nSentTimes++
dwBytesWrite = nLen-dwByteswrittenTotal
bWriteStat = WriteFile( m_hCom, szBuf+dwByteswrittenTotal, dwBytesWrite, &dwBytesWritten, &m_OverlappedWrite )
if( !bWriteStat)
{
if ( GetLastError() == ERROR_IO_PENDING )
{
dwBytesWritten = 0
bWrite = FALSE
}
}
if (!bWrite)
{
bWrite = TRUE
bWriteStat = GetOverlappedResult(m_hCom, // Handle to COMM port
&m_OverlappedWrite, // Overlapped structure
&dwBytesWritten, // Stores number of bytes sent
TRUE)// Wait flag
//deal with the error code
}
dwByteswrittenTotal += dwBytesWritten
}
if(dwByteswrittenTotal<nLen)
return 0
else
return 1
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)