实用的java 串口通信程序,从串行口COM1中发送/接收数据

本文主要给出一个实用的java 串口通信程序,供大家讨论学习.

/******************************************
* 程序文件名称:SendComm.java
* 功能:从串行口COM1中发送数据
******************************************/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.comm.*;

class S_Frame extends Frame implements Runnable,ActionListener
{
/*检测系统中可用的通讯端口类 */
static CommPortIdentifier portId;
/*Enumeration 为枚举型类,在util中 */
static Enumeration portList;
OutputStream outputStream;
/*RS-232的串行口 */
SerialPort serialPort;
Thread readThread;
Panel p=new Panel();
TextField in_message=new TextField("打开COM1,波特率9600,数据位8,停止位1.");
TextArea out_message=new TextArea();
Button btnOpen=new Button("打开串口, 发送数据");
Button btnClose=new Button("关闭串口, 停止发送数据");
byte data[]=new byte[10240];
/*设置判断要是否关闭串口的标志*/
boolean mark;

/*安排窗体*/
S_Frame()
{ super("串口发送数据");
setSize(200,200);
setVisible(true);
add(out_message,"Center");
add(p,"North");
p.add(btnOpen);
p.add(btnClose);
add(in_message,"South");
btnOpen.addActionListener(this);
btnClose.addActionListener(this);
} //R_Frame() end

/*点击按扭打开串口.*/
public void actionPerformed(ActionEvent event) {
if (event.getSource()==btnClose){
serialPort.close(); //关闭串口
mark=true; //用于中止线程的run()方法
in_message.setText("串口COM1已经关闭,停止发送数据.");
}
else { mark=false;
/*从文本区按字节读取数据*/
data=out_message.getText().getBytes();
/*打开串口*/
start();
in_message.setText("串口COM1已经打开,正在每2秒钟发送一次数据.....");
}
} //actionPerformed() end

/*打开串口,并调用线程发送数据*/
public void start(){
/*获取系统中所有的通讯端口 */
portList=CommPortIdentifier.getPortIdentifiers();
/* 用循环结构找出串口 */
while (portList.hasMoreElements()){
/*强制转换为通讯端口类型*/
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if (portId.getName().equals("COM1")) {
/*打开串口 */
try {
serialPort = (SerialPort) portId.open("ReadComm", 2000);
}
catch (PortInUseException e) { }
/*设置串口输出流*/
try {
outputStream = serialPort.getOutputStream();
}
catch (IOException e) {}
} //if end
} //if end
} //while end
/*调用线程发送数据*/
try{
readThread = new Thread(this);
//线程负责每发送一次数据,休眠2秒钟
readThread.start();
}
catch (Exception e) { }
} //start() end

/*发送数据,休眠2秒钟后重发*/
public void run() {
/*设置串口通讯参数*/
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) { }
/*发送数据流(将数组data[]中的数据发送出去)*/
try {
outputStream.write(data);
}
catch (IOException e) { }
/*发送数据后休眠2秒钟,然后再重发*/
try { Thread.sleep(2000);
if (mark)
{return; //结束run方法,导致线程死亡
}
start();
}
catch (InterruptedException e) { }
} //run() end
} //类S_Frame end

public class SendComm
{public static void main(String args[])
{ S_Frame S_win=new S_Frame();
S_win.addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{System.exit(0); }
});
S_win.pack();
}
}


/******************************************
* 程序文件名称:ReadComm.java
* 功能:从串行口COM1中接收数据
******************************************/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.comm.*;

class R_Frame extends Frame implements Runnable,ActionListener,SerialPortEventListener
{
/* 检测系统中可用的通讯端口类 */
static CommPortIdentifier portId;
/* Enumeration 为枚举型类,在java.util中 */
static Enumeration portList;
InputStream inputStream;
/* 声明RS-232串行端口的成员变量 */
SerialPort serialPort;
Thread readThread;
String str="";
TextField out_message=new TextField("上面文本框显示接收到的数据");
TextArea in_message=new TextArea();
Button btnOpen=new Button("打开串口");

/*建立窗体*/
R_Frame()
{
super("串口接收数据");
setSize(200,200);
setVisible(true);
btnOpen.addActionListener(this);
add(out_message,"South");
add(in_message,"Center");
add(btnOpen,"North");
} //R_Frame() end

/*点击按扭所触发的事件:打开串口,并监听串口. */
public void actionPerformed(ActionEvent event)
{
/*获取系统中所有的通讯端口 */
portList=CommPortIdentifier.getPortIdentifiers();
/* 用循环结构找出串口 */
while (portList.hasMoreElements()){
/*强制转换为通讯端口类型*/
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if (portId.getName().equals("COM1")) {
try {
serialPort = (SerialPort) portId.open("ReadComm", 2000);
out_message.setText("已打开端口COM1 ,正在接收数据..... ");
}
catch (PortInUseException e) { }

/*设置串口监听器*/
try {
serialPort.addEventListener(this);
}
catch (TooManyListenersException e) { }
/* 侦听到串口有数据,触发串口事件*/
serialPort.notifyOnDataAvailable(true);
} //if end
} //if end
} //while end
readThread = new Thread(this);
readThread.start(); //线程负责每接收一次数据休眠20秒钟
} //actionPerformed() end

/*接收数据后休眠20秒钟*/
public void run() {
try {
Thread.sleep(20000);
}
catch (InterruptedException e) { }
} //run() end

/*串口监听器触发的事件,设置串口通讯参数,读取数据并写到文本区中*/
public void serialEvent(SerialPortEvent event) {
/*设置串口通讯参数:波特率、数据位、停止位、奇偶校验*/
try {
serialPort.setSerialPortParams(9600,
  SerialPort.DATABITS_8,
  SerialPort.STOPBITS_1,
  SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) {   }
byte[] readBuffer = new byte[20];
try {
inputStream = serialPort.getInputStream();
}
catch (IOException e) {}
try {
   /* 从线路上读取数据流 */
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
} //while end
str=new String(readBuffer);
/*接收到的数据存放到文本区中*/
in_message.append(str+"/n");
}
catch (IOException e) { }
} //serialEvent() end
} //类R_Frame end

public class ReadComm
{
public static void main(String args[])
{
/* 实例化接收串口数据的窗体类 */
R_Frame R_win=new R_Frame();
/* 定义窗体适配器的关闭按钮功能 */
R_win.addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{System.exit(0); }
});
R_win.pack();
}
}
展开阅读全文

串口通信 com1com2之间通信

12-19

打开两个com:com3和com4,rncom3代码如下:rnrn#include rn#include rn#include rn#include rnrnHANDLE hComm;rnOVERLAPPED m_ov;rnCOMSTAT comstat;rnunsigned char *words;rnrnrnProcessErrorMessage(char* ErrorText)rnrn char *Temp = new char[200];rn LPVOID lpMsgBuf;rn FormatMessage(rn FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,rn NULL,rn GetLastError(),rn MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default languagern (LPTSTR) &lpMsgBuf,rn 0,rn NULLrn );rn sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, "com2");rn MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);rn LocalFree(lpMsgBuf);rn delete[] Temp;rn return true;rnrnrnbool openport(char *portname)rnrnrnhComm = CreateFile(portname,rn GENERIC_READ | GENERIC_WRITE,rn 0,rn 0,rn OPEN_EXISTING,rn FILE_FLAG_OVERLAPPED, rn 0);rnif (hComm == INVALID_HANDLE_VALUE)rnreturn FALSE;rnelsernreturn true;rnrnrnbool setupdcb(int rate_arg)rnrn DCB dcb;rn int rate= rate_arg;rn memset(&dcb,0,sizeof(dcb));rn if(!GetCommState(hComm,&dcb))rn rn ProcessErrorMessage("GetCommState()");rn return FALSE;rn rn /* -------------------------------------------------------------------- */rn // set DCB to configure the serial portrn dcb.DCBlength = sizeof(dcb);rn /* ---------- Serial Port Config ------- */rn dcb.BaudRate = rate;rn dcb.Parity = NOPARITY;rn dcb.fParity = 0;rn dcb.StopBits = ONESTOPBIT;rn dcb.ByteSize = 8;rn dcb.fOutxCtsFlow = 0;rn dcb.fOutxDsrFlow = 0;rn dcb.fDtrControl = DTR_CONTROL_DISABLE;rn dcb.fDsrSensitivity = 0;rn dcb.fRtsControl = RTS_CONTROL_DISABLE;rn dcb.fOutX = 0;rn dcb.fInX = 0;rn /* ----------------- misc parameters ----- */rn dcb.fErrorChar = 0;rn dcb.fBinary = 1;rn dcb.fNull = 0;rn dcb.fAbortOnError = 0;rn dcb.wReserved = 0;rn dcb.XonLim = 2;rn dcb.XoffLim = 4;rn dcb.XonChar = 0x13;rn dcb.XoffChar = 0x19;rn dcb.EvtChar = 0;rn /* -------------------------------------------------------------------- */rn // set DCBrn if(!SetCommState(hComm,&dcb))rn rn ProcessErrorMessage("SetCommState()");rn return false;rn rn elsern return true;rnrnrnbool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant)rnrn COMMTIMEOUTS timeouts;rn timeouts.ReadIntervalTimeout=ReadInterval;rn timeouts.ReadTotalTimeoutConstant=ReadTotalconstant;rn timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier;rn timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;rn timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;rn if(!SetCommTimeouts(hComm, &timeouts))rn rn ProcessErrorMessage("SetCommTimeouts()");rn return false;rn rn elsern return true;rnrnrnReceiveChar( )rnrnBOOL bRead = TRUE;rnBOOL bResult = TRUE;rnDWORD dwError = 0;rnDWORD BytesRead = 0;rnchar RXBuff;rnfor (;;)rnrn bResult = ClearCommError(hComm, &dwError, &comstat);rn if (comstat.cbInQue == 0)rn continue;rn if (bRead)rn rn bResult = ReadFile(hComm, // Handle to COMM portrn &RXBuff, // RX Buffer Pointerrn 1, // Read one bytern &BytesRead, // Stores number of bytes readrn &m_ov); // pointer to the m_ov structurern printf("%c",RXBuff);rn if (!bResult)rn rn switch (dwError = GetLastError())rn rn case ERROR_IO_PENDING:rn rn bRead = FALSE;rn break;rn rn default:rn rn break;rn rn rn rn elsern rn bRead = TRUE;rn rn // close if (bRead)rn if (!bRead)rn rn bRead = TRUE;rn bResult = GetOverlappedResult(hComm, // Handle to COMM portrn &m_ov, // Overlapped structurern &BytesRead, // Stores number of bytes readrn TRUE); // Wait flagrn rn rnreturn RXBuff;rnrnrnWriteChar(BYTE* m_szWriteBuffer,DWORD m_nToSend)rnrnBOOL bWrite = TRUE;rnBOOL bResult = TRUE;rnDWORD BytesSent = 0;rn//HANDLE m_hWriteEvent;rn//ResetEvent(m_hWriteEvent);rnif (bWrite)rnrnm_ov.Offset = 0;rnm_ov.OffsetHigh = 0;rn// Clear bufferrnbResult = WriteFile(hComm, // Handle to COMM Portrn m_szWriteBuffer, // Pointer to message buffer in calling finctionrn m_nToSend, // Length of message to sendrn &BytesSent, // Where to store the number of bytes sentrn &m_ov ); // Overlapped structurernif (!bResult)rnrnDWORD dwError = GetLastError();rnswitch (dwError)rnrncase ERROR_IO_PENDING:rnrn// continue to GetOverlappedResults()rnBytesSent = 0;rnbWrite = FALSE;rnbreak;rnrndefault:rnrn// all other error codesrnProcessErrorMessage("WriteFile()");rnrnrnrn // end if(bWrite)rnif (!bWrite)rnrnbWrite = TRUE;rnbResult = GetOverlappedResult(hComm, // Handle to COMM portrn &m_ov, // Overlapped structurern &BytesSent, // Stores number of bytes sentrn TRUE); // Wait flagrnrn// deal with the error codernif (!bResult)rnrnProcessErrorMessage("GetOverlappedResults() in WriteFile()");rnrn // end if (!bWrite)rnrn// Verify that the data size send equals what we tried to sendrnif (BytesSent != m_nToSend)rnrnprintf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));rnrnreturn true;rnrnrnDWORD WINAPI MyThread1(LPVOID pParam)rnrnReceiveChar();rnreturn 0;rnrnrnDWORD WINAPI MyThread2(LPVOID pParam)rnrn while(hComm!=INVALID_HANDLE_VALUE) rn rn unsigned char d;rn d=getch();rn printf("%c",d);rn WriteChar(&d,1);rn rnreturn 0;rnrnrnrnvoid main()rnrnif(openport("com3"))rnprintf("open comport success\n");rnif(setupdcb(9600))rnprintf("setupDCB success\n");rnif(setuptimeout(0,0,0,0,0))rnprintf("setuptimeout success\n");rnPurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);rnwords=(unsigned char *)malloc(256); rnprintf("please input your data:\n");rnscanf("%s",words); rnrnWriteChar(words,20);rnprintf("received data:\n");rnReceiveChar( );rnHANDLE hThread1=CreateThread(NULL, 0, MyThread1, 0, 0, NULL); rnHANDLE hThread2=CreateThread(NULL, 0, MyThread2, 0, 0, NULL); rnCloseHandle(hThread1);rnCloseHandle(hThread2);rnsystem("pause");rnrnrnrn运行程序以后出现两个console框,在com3的"please input your data:"后面输入字符串,但是com4的console窗收不到发送的字符串,该如何解决呢?rn 论坛

Qt的串口通信接收数据错误

03-31

我在win8+qt5.1.0 下开发的一个串口传输的程序,在自己电脑上运行正常。但在交给客户的时候,在他们电脑上(xp 系统)运行就出错了。经过检查,发现应该是数据接收错误的。因为如果发送错误,下位机就不会有任何回复,而程序接收到的数据是或多或少的。先上下代码吧,rn [code=c] for(k = 0; k < 3; k++)rn rn requestData = outdata[i][0];rn serial->write(requestData);rn if (serial->waitForBytesWritten(120))rn rn // read responsern if (serial->waitForReadyRead(2000))rn rn// serial->bytesAvailable() == 20;rn responseData = serial->readAll();rn txt << responseData.toHex() <<"===1 this is recived data." << "\r\n";rn if(responseData.count() == 20)rn rn save1 << electricEnergy(responseData);rn serial->readAll();rn break;rn rn else if(k == 2)rn rn save1 << "0000";rn serial->readAll();rn rn rn else if(k == 2)rn rn save1 << "0000";rn serial->readAll();rn rn rn rn QThread::msleep(waittime);[/code]rnrn代码只是一段,没有全部贴出来。rn接收到的数据是这样的:rn1 this is recived data.rnfe===1 this is recived data.rnfe===1 this is recived data.rn68===1 this is recived data.rn2 this is recived data.rn6847648680000068010243c48b16===send data 2 ;rn6847648680000068010243c48b16===send data 2 ;rn47648680000068810643c3833533332c16b62 this is recived data.rn6847648680000068010243c48b16===send data 2 ;rnff2 this is recived data.rnrn上面数据是两段接收到的数据。rn正确的接收到的数据是,以fefe开头,以16结尾的一列数据的rn比如:fefe6847648680000068810643c3833533332c16rnrn情况就是这样的,我不知道怎么修改了,大神们指点下吧!rn各位给点建议吧! 论坛

win32 串口通信接收数据异常

04-27

在使用win32进行串口通信编程时,发送数据可以成功,但是接收数据发现数据错乱。rn发送方发送的数据为:(16进制)11 11 11 11 22 22 22 22 33 33 33 44 rn接收方收到的数据为:[img=https://img-bbs.csdn.net/upload/201804/27/1524818049_300825.png][/img]rnrn发送是通过串口调试助手做的:[img=https://img-bbs.csdn.net/upload/201804/27/1524818089_96450.png][/img]rnrn接收方代码如下:rnrntypedef struct NormalCommandrnrn unsigned char szDataBuffer[MAX_LEN];rn int dataLen;rnrn NormalCommand()rn rn memset(szDataBuffer, 0, MAX_LEN);rn dataLen = 0;rn rnrnstruNormalCommad;rnrnint ReadNormalAnswer(HANDLE Handle, struNormalCommad* commandTmp)rnrn if (Handle == INVALID_HANDLE_VALUE)rn rn return FALSE;rn rnrn DWORD realRecvLen = 0;rn DWORD curLen = 0;rn BOOL ret = FALSE;rnrn DWORD Error;rn COMSTAT cs = 0 ;rnrn while (1)rn rn ClearCommError(Handle, &Error, &cs);rnrn //MAX_HEAD_LEN 13 内部约定的数据包头长度。rn ret = ReadFile(Handle, commandTmp->szDataBuffer + curLen, MAX_HEAD_LEN, &realRecvLen, NULL);rn if (ret != FALSE)rn rn if (realRecvLen == 0)rn rn PurgeComm(Handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);rn return FALSE;rn rn curLen += realRecvLen;rn commandTmp->dataLen += realRecvLen;rnrn int leftLen = AnalyzeDataLen(commandTmp);rn if (leftLen > 0)rn rn ClearCommError(Handle, &Error, &cs);rnrn ret = ReadFile(Handle, commandTmp->szDataBuffer + curLen, leftLen, &realRecvLen, NULL);rn if (ret != FALSE)rn rn if (realRecvLen == 0)rn rn PurgeComm(Handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);rn return FALSE;rn rn curLen += realRecvLen;rn commandTmp->dataLen += realRecvLen;rn return TRUE;rn rn rn elsern rn return TRUE;rn rn rn rnrn return TRUE;rn 论坛

串口通信 接收数据问题

01-10

从网上下了一段串口通信的代码rn数据接收段如下:rnDWORD RS232::input( LPVOID pdest, DWORD len, DWORD dwMaxWait ) rn BOOL bSuccess; rn DWORD result = 0, rn read = 0, // num read bytes rn mask = 0; // a 32-bit variable that receives a mask rn // indicating the type of event that occurred rn if ( len < 1 ) rn return(0); rn // create event for overlapped I/O rn m_ov.hEvent = CreateEvent( NULL, // pointer to security attributes rn FALSE, // flag for manual-reset event rn FALSE, // flag for initial state rn "" ); // pointer to event-object name rn if ( m_ov.hEvent == INVALID_HANDLE_VALUE ) rn RS232::ErrorToString( "RS232::input() CreateEvent() failed" ); rn return -1; rn rn // Specify here the event to be enabled rn bSuccess = SetCommMask( m_hCom, EV_RXCHAR ); rn if ( ! bSuccess ) rn CloseHandle(m_ov.hEvent); rn RS232::ErrorToString("RS232::input() SetCommMask() failed"); rn return -1; rn rn // WaitForSingleObject rn bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov); rn if ( !bSuccess ) rn int err = GetLastError(); rn if ( err == ERROR_IO_PENDING ) rn result = WaitForSingleObject(m_ov.hEvent,INFINITE); //wait dwMaxWait rn // milli seconds before returning rn if ( result == WAIT_FAILED ) rn CloseHandle(m_ov.hEvent); rn RS232::ErrorToString( "RS232::input() WaitForSingleObject() failed" ); rn return -1; rn rn rn rn // The specified event occured? rn if ( mask & EV_RXCHAR ) rn rn bSuccess = ReadFile( m_hCom, // handle of file to read rn pdest, // address of buffer that receives data rn len, // number of bytes to read rn &read, // address of number of bytes read rn &m_ov); // address of structure for data rn if ( RS232::IsNT() ) rn bSuccess = GetOverlappedResult(m_hCom, &m_ov, &read, TRUE); rn if ( !bSuccess ) rn CloseHandle( m_ov.hEvent ); rn RS232::ErrorToString( "RS232::input() GetOverlappedResult() failed" ); rn return -1; rn rn rn else if ( !bSuccess ) rn CloseHandle(m_ov.hEvent); rn RS232::ErrorToString( "RS232::input() ReadFile() failed" ); rn return -1; rn rn rn else rn CloseHandle(m_ov.hEvent); rn wsprintf( m_lpszErrorMessage, "RS232::input() No EV_RXCHAR occured\n" ); rn return -1; rn rn CloseHandle(m_ov.hEvent); rn return read; rn rn运行时,运行到 bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov);就一直等待了,另外本人设置的等待时间是无限 论坛

串口通信界面接收数据没反应

02-02

我做的串口通信界面是按照龚建伟老师的教程做的,发送数据没问题,但是接收不到数据。rn代码如下:rn// SCommTestDlg.cpp : implementation filern//rnrn#include "stdafx.h"rn#include "SCommTest.h"rn#include "SCommTestDlg.h"rnrn#ifdef _DEBUGrn#define new DEBUG_NEWrn#undef THIS_FILErnstatic char THIS_FILE[] = __FILE__;rn#endifrnrn/////////////////////////////////////////////////////////////////////////////rn// CAboutDlg dialog used for App Aboutrnrnclass CAboutDlg : public CDialogrnrnpublic:rn CAboutDlg();rnrn// Dialog Datarn //AFX_DATA(CAboutDlg)rn enum IDD = IDD_ABOUTBOX ;rn //AFX_DATArnrn // ClassWizard generated virtual function overridesrn //AFX_VIRTUAL(CAboutDlg)rn protected:rn virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV supportrn //AFX_VIRTUALrnrn// Implementationrnprotected:rn //AFX_MSG(CAboutDlg)rn //AFX_MSGrn DECLARE_MESSAGE_MAP()rn;rnrnCAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)rnrn //AFX_DATA_INIT(CAboutDlg)rn //AFX_DATA_INITrnrnrnvoid CAboutDlg::DoDataExchange(CDataExchange* pDX)rnrn CDialog::DoDataExchange(pDX);rn //AFX_DATA_MAP(CAboutDlg)rn //AFX_DATA_MAPrnrnrnBEGIN_MESSAGE_MAP(CAboutDlg, CDialog)rn //AFX_MSG_MAP(CAboutDlg)rn // No message handlersrn //AFX_MSG_MAPrnEND_MESSAGE_MAP()rnrn/////////////////////////////////////////////////////////////////////////////rn// CSCommTestDlg dialogrnrnCSCommTestDlg::CSCommTestDlg(CWnd* pParent /*=NULL*/)rn : CDialog(CSCommTestDlg::IDD, pParent)rnrn //AFX_DATA_INIT(CSCommTestDlg)rn m_strEditRXData = _T("");rn m_strEditTXData = _T("");rn //AFX_DATA_INITrn // Note that LoadIcon does not require a subsequent DestroyIcon in Win32rn m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);rnrnrnvoid CSCommTestDlg::DoDataExchange(CDataExchange* pDX)rnrn CDialog::DoDataExchange(pDX);rn //AFX_DATA_MAP(CSCommTestDlg)rn DDX_Control(pDX, IDC_MSCOMM1, m_ctrlComm);rn DDX_Text(pDX, IDC_EDIT_RXDATA, m_strEditRXData);rn DDX_Text(pDX, IDC_EDIT_TXDATA, m_strEditTXData);rn //AFX_DATA_MAPrnrnrnBEGIN_MESSAGE_MAP(CSCommTestDlg, CDialog)rn //AFX_MSG_MAP(CSCommTestDlg)rn ON_WM_SYSCOMMAND()rn ON_WM_PAINT()rn ON_WM_QUERYDRAGICON()rn ON_BN_CLICKED(IDC_BUTTON_MANUALSEND, OnButtonManualsend)rn //AFX_MSG_MAPrnEND_MESSAGE_MAP()rnrn/////////////////////////////////////////////////////////////////////////////rn// CSCommTestDlg message handlersrnrnBOOL CSCommTestDlg::OnInitDialog()rnrn CDialog::OnInitDialog();rn if(m_ctrlComm.GetPortOpen()) rn m_ctrlComm.SetPortOpen(FALSE);rn m_ctrlComm.SetCommPort(1);//选择com1rn m_ctrlComm.SetInputMode(1);//输入方式为二进制rn m_ctrlComm.SetInBufferSize(1024);rn m_ctrlComm.SetOutBufferSize(512);rn m_ctrlComm.SetSettings("9600,n,8,1");rn if(!m_ctrlComm.GetPortOpen())rn m_ctrlComm.SetPortOpen(TRUE);rn m_ctrlComm.SetRThreshold(1);rn m_ctrlComm.SetInputLen(0);rn m_ctrlComm.GetInput();rn return TRUE;rn // Add "About..." menu item to system menu.rnrn // IDM_ABOUTBOX must be in the system command range.rn ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);rn ASSERT(IDM_ABOUTBOX < 0xF000);rnrn CMenu* pSysMenu = GetSystemMenu(FALSE);rn if (pSysMenu != NULL)rn rn CString strAboutMenu;rn strAboutMenu.LoadString(IDS_ABOUTBOX);rn if (!strAboutMenu.IsEmpty())rn rn pSysMenu->AppendMenu(MF_SEPARATOR);rn pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);rn rn rnrn // Set the icon for this dialog. The framework does this automaticallyrn // when the application's main window is not a dialogrn SetIcon(m_hIcon, TRUE); // Set big iconrn SetIcon(m_hIcon, FALSE); // Set small iconrn rn // TODO: Add extra initialization herern rn return TRUE; // return TRUE unless you set the focus to a controlrnrnrnvoid CSCommTestDlg::OnSysCommand(UINT nID, LPARAM lParam)rnrn if ((nID & 0xFFF0) == IDM_ABOUTBOX)rn rn CAboutDlg dlgAbout;rn dlgAbout.DoModal();rn rn elsern rn CDialog::OnSysCommand(nID, lParam);rn rnrnrn// If you add a minimize button to your dialog, you will need the code belowrn// to draw the icon. For MFC applications using the document/view model,rn// this is automatically done for you by the framework.rnrnvoid CSCommTestDlg::OnPaint() rnrn if (IsIconic())rn rn CPaintDC dc(this); // device context for paintingrnrn SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);rnrn // Center icon in client rectanglern int cxIcon = GetSystemMetrics(SM_CXICON);rn int cyIcon = GetSystemMetrics(SM_CYICON);rn CRect rect;rn GetClientRect(&rect);rn int x = (rect.Width() - cxIcon + 1) / 2;rn int y = (rect.Height() - cyIcon + 1) / 2;rnrn // Draw the iconrn dc.DrawIcon(x, y, m_hIcon);rn rn elsern rn CDialog::OnPaint();rn rnrnrn// The system calls this to obtain the cursor to display while the user dragsrn// the minimized window.rnHCURSOR CSCommTestDlg::OnQueryDragIcon()rnrn return (HCURSOR) m_hIcon;rnrnrnBEGIN_EVENTSINK_MAP(CSCommTestDlg, CDialog)rn //AFX_EVENTSINK_MAP(CSCommTestDlg)rn ON_EVENT(CSCommTestDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)rn //AFX_EVENTSINK_MAPrnEND_EVENTSINK_MAP()rnrn void CSCommTestDlg::OnComm() rnrn // TODO: Add your control notification handler code herern VARIANT variant_inp;rn COleSafeArray safearray_inp;rn LONG len,k;rn BYTE rxdata[2048];rn CString strtemp; rn //UpdateData(TRUE);rn if(m_ctrlComm.GetCommEvent()==2)rn variant_inp=m_ctrlComm.GetInput();rn safearray_inp=variant_inp;rn len=safearray_inp.GetOneDimSize();rn for(k=0;k 论坛

用C#写的串口通信程序接收数据出错

03-12

事件背景:rn给定了利用RS485协议的下位机和RS232的下位机,要求按照一定的通信协议用C#2.0实现上位机程序(以下简称上位机),串口的波特率为2400,8位无校验,1停止位。rnrn使用硬件平台:rn使用PCI串口(RS232)卡的电脑,RS485与RS232的转换电路rnrn软件:rnVS2005,非独占模式的串口监视软件COMgrasp,串口调试助手(MFC+WinAPI编写成的)rnrn程序:rn使用C#中内建的SerialPort类进行串口通信并用标准的Invoke方法调用数据处理函数(也就是显示数据),设计了一个直接写在Write方法里的byte数组为第一缓冲区,另有一个将第一缓冲区收到数据拼成完整数据的第二缓冲区(似乎SerialPort类一次最多接受8字节所以要开这个缓冲区)。rnrn过程:rn1、为RS232的下位机编写上位机,经测试一切正常;rn2、为RS485的下位机编写上位机,尚未使用第二缓冲区,显示返回数据不符合通信协议规范,数据包字节数少且数据本身的值基本全错;rn3、用串口调试助手按照通信协议规范发送通信数据包,回显数据符合通信协议,正常;rn4、利用串口监视软件监视收发数据,发现无论是正在编写的上位机程序还是串口调试助手,发送给下位机的数据完全相同且符合通信协议,但收回的数据中,两者差别很大,串口调试助手中是逐字节接收而上位机程序是一次接收多字节且每次接收的个数无规律;rn5、用一拖二的线把信号引至同一串口卡的另一串口(机器上就这俩串口),同时用上位机程序和串口调试助手监视两个串口,用调试助手向下位机发送数据,调试助手回显数据正常上位机不显示,用上位机向下位机发送数据,调试助手回显数据正常上位机有显示但不正常,串口监视软件的监视情况和两个软件的显示情况相同;rn6、在上位机中加入ErrorReceived事件的处理函数,显示错误类型为FRAME,MSDN说明为“硬件检测到一个组帧错误”,出现此错误的时间也是随机的,有的时候回显的数据也不对,但是不报任何错。rnrn俺要求助的问题:rn1、C#的SerialPort类,能直接访问输入和输出缓冲区不,要是能的话是哪个方法?我没查到......rn2、串口调试助手中对串口接收数据的处理是每收到一个字节就抛出一个WM_RXCHAR消息,在C#中也设置了ReceivedBytesThreshold属性为1字节,为什么收数据的时候触发一次事件就收到不止一字节的数据,关键是还不规律?rn3、2400也不算高速,为啥用MFC(或者叫WinAPI)正常而C#收到的数据既丢帧值也错误?所谓的Frame错误又从何而来?rn4、如何对SerialPort类进行编程才能纠正上述各种错误,使其能起到和串口调试助手相同的作用?rn5、如果解决方案是C#内嵌WinAPI的话,该用哪些函数或类,又该怎么处理线程和事件?rn 论坛

没有更多推荐了,返回首页