c++ mfc编程 如何添加serialport控件

c++ mfc编程 如何添加serialport控件,第1张

在窗体上点右键,出现菜单,添加控件,找到 serialport 完成

添加串口主要有以下几个参数:

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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11444700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存