请参考下面的方法。
技术要点: (1).首先,SerialPort的ReceivedBytesThreshold先设置成1,表示只要有1个字符送达端口时便触发DataReceived事件 (2).当DataReceived触发时,先把ReceivedBytesThreshold设置成一个比较大的值,达到读取本次端口数据时,不再触发DataReceived. (3).循环读取端口中的数据,直至读完。 (4).移除读取数据中的非法字符。 (5).触发一个后台线程处理收到的数据。 (6).在finally中把ReceivedBytesThreshold重置回1 private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { if (sender.GetType() != typeof(System.IO.Ports.SerialPort)) { return; } string strReceive = string.Empty; string strCollect = string.Empty; System.IO.Ports.SerialPort comPort = (System.IO.Ports.SerialPort)sender; try { comPort.ReceivedBytesThreshold = comPort.ReadBufferSize; while (true) { strReceive = comPort.ReadExisting(); if (string.Equals(strReceive, string.Empty)) { break; } else { strCollect += strReceive; Application.DoEvents(); Thread.Sleep(100); } } strCollect = strCollect.Replace("\0", string.Empty); strCollect = strCollect.Replace("\r\n", string.Empty); strCollect = strCollect.Replace("\r", string.Empty); strCollect = strCollect.Replace("\n", string.Empty); if (!this.bIsHandleCom) { this.bIsHandleCom = true; mReceiveData = strCollect; if (ReceiveDataParserEvent != null) ReceiveDataParserEvent(mReceiveData); if (ThreadReceiveParser != null && !ThreadReceiveParser.IsAlive) { ThreadReceiveParser.Start(); } } } catch (Exception ex) { MessageBox.Show(this, ex.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { comPort.ReceivedBytesThreshold = 1; } }
private SerialPort _com = new SerialPort();//串口对象
/// <summary> /// 打开串口 /// </summary> /// <param name="strCom">串口名“COM1” </param> /// <param name="nBot">波特率 </param> /// <param name="nThreshold">引发消息事件的字节数 </param> public void OpenPort(string strCom, int nBot) { try { //串口设置与打开 //_com.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceivedAddress); _com.PortName = strCom; _com.BaudRate = nBot; _com.DataBits = 8; _com.StopBits = StopBits.One; _com.Parity = Parity.Even; _com.Open(); } catch (Exception ex) { //Application.Exit();//退出应用程序 //System.Diagnostics.Process.Start("JT.exe");//启动程序 MessageBox.Show("“" + ex.Message + "”设置硬件功能将不可用,如要使用该功能,请到主窗体的系统设置中选择正确的串口信息,并重新打开该模块!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } OpenPort(com1, 9600); _com.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceivedAddress); public void DataReceivedAddress(object sender, SerialDataReceivedEventArgs e) { byte[] data = new byte[_com.BytesToRead]; _com.Read(data, 0, data.Length); if (data.Length != 0) { DisposeRecvDataAddress(data); } } public void DisposeRecvDataAddress(byte[] data) { string strReceive = ""; //MessageBox.Show("进来了"); try { for (int i = 0; i < data.Length; i++) { strReceive += TenToHex(data[i].ToString()); //strReceive += data[i].ToString(); } 然后把接收到的数据按照协议来处理 }
void __fastcall TForm1::Button2Click(TObject *Sender)
{ if (hComm!=INVALID_HANDLE_VALUE) CloseHandle(hComm); exit(EXIT_SUCCESS); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { char *ComNo; DCB dcb; String Temp; //取得要打开的通讯端口。 Temp = "COM"+IntToStr(1); //转换至指针类型Char。 ComNo = Temp.c_str(); hComm = CreateFile(ComNo,GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (hComm == INVALID_HANDLE_VALUE) // 如果通讯端口未打开 { MessageBox(0, "打开通讯端口错误!!","Comm Error",MB_OK); return; } // GetCommState(hComm,&dcb); // 获得当前通讯端口状态。 dcb.BaudRate = CBR_9600; // 设置速率为9600 dcb.ByteSize = 8; // 字节为8 bit dcb.Parity = NOPARITY; // Parity 为 None dcb.StopBits = ONESTOPBIT; // 1 个 Stop bit //端口设置。 if (!SetCommState(hComm, &dcb)) { // 设置通讯端口状态 MessageBox (0, "通讯端口错误!!!","Set Error",MB_OK); CloseHandle(hComm); return; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { String Temp; char *SendData; int ln; unsigned long lrc,BS; if (hComm==0) return; //检查Handle值 Temp = mSend->Text;//取得要发送的字符串 SendData = Temp.c_str(); //字符串转换 //取得要发送的字符串数。 BS = Temp.Length(); //BS = StrLen(SendData); //也可以用此方法取得要发送的字符串长度。 //实际的发送动作。 WriteFile(hComm,SendData,BS, &lrc,NULL); // 发送数据。 } //--------------------------------------------------------------------------- void __fastcall TForm1::Button4Click(TObject *Sender) { String Temp; char inbuff[1024]; DWORD nBytesRead, dwEvent, dwError; COMSTAT cs; //取得状态 ClearCommError(hComm,&dwError,&cs); // 数据是否大于我们准备的缓冲区 if (cs.cbInQue > sizeof(inbuff)) { PurgeComm(hComm, PURGE_RXCLEAR); // 清除通讯端口数据。 return; } ReadFile(hComm, inbuff,cs.cbInQue,&nBytesRead,NULL); //接收通讯端口的数据。 //数组中的字符串接尾处接上\0. inbuff[cs.cbInQue]= '\0'; //将数组显示在MEMO1上。 |
lingshi
最新推荐文章于 2023-03-13 13:14:44 发布