当前位置:编程学习 > C#/ASP.NET >>

C# 让串口一直处于接收状态

我想让串口一直处于接收信息状态,比如持续1分钟,但是接收内容的大小未知。不知道该怎么来写,请大虾们帮帮忙,最好有个例程,谢谢! --------------------编程问答-------------------- 这个没写过
去www.codeproject.com自己去搜索下吧 --------------------编程问答-------------------- 这是前几年做的一个程序,用于设置串口通讯参数,并做检测,如果不按停止一直接受数据

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Xml;


namespace PRMS
{
    public partial class frmSetComm : Form
    {
        private CommPort myCommPort = new CommPort();
        private SerialPort sp = new SerialPort();
        private pubFunction myFunction = new pubFunction();

        private delegate void HandleInterfaceUpdateDelegate(string aString);
        HandleInterfaceUpdateDelegate interfaceUpdateHandle;
        static string strReceive; // 接收到数据的缓冲区
        private string PortName;
        private int nEncode;
        private int nBitStart;
        private int nBitLength;
        private int nBitEndTag;
        private int nNewTag = 0;
        private int nDataReceive = 0;
        private Color[] LogMsgTypeColor = { Color.Orange, Color.Green, Color.Black, Color.Blue, Color.Red };

        public frmSetComm()
        {
            InitializeComponent();
        }
        private void EnableControls(string strMsg)
        {
            // 基于串口的打开与否,设置控件状态
            PortName = cmbPortName.Text;
            rtfTerminal.Clear();
            rtfTerminal.ForeColor = LogMsgTypeColor[3];
            if (sp.IsOpen) { 
                btnOpenPort.Text = "关闭串口";
                if (strMsg == "")
                { this.rtfTerminal.Text = "串口[" + PortName + "]被打开"; }
                cmbPortName.Enabled = cmbBaudRate.Enabled = cmbDataBits.Enabled = cmbParity.Enabled = cmbStopBits.Enabled = false;
                SetProtolCotrols(true);
            }
            else
            { btnOpenPort.Text = "打开串口";
              if (strMsg == "")
              {
                  rtfTerminal.Text = "串口[" + PortName + "]被关闭";
              }
              else
              {
                rtfTerminal.Text = strMsg;
              }

              cmbPortName.Enabled = cmbBaudRate.Enabled = cmbDataBits.Enabled = cmbParity.Enabled = cmbStopBits.Enabled = true;
            }
        }

        private void frmSetComm_Load(object sender, EventArgs e)
        {
           // cmbParity.Items.Clear(); cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
           // cmbStopBits.Items.Clear(); cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));
            interfaceUpdateHandle = new HandleInterfaceUpdateDelegate(ShowText);
            cmbPortName.Items.Clear();
            foreach (string s in SerialPort.GetPortNames())
            {
                cmbPortName.Items.Add(s);
                if (s == myCommPort.sPortName)
                {
                    cmbPortName.Text = s;
                }
            }
            PortName = cmbPortName.Text;
            cmbBaudRate.Text = sp.BaudRate.ToString();
            cmbParity.Text = sp.Parity.ToString();

            cmbDataBits.Text = sp.DataBits.ToString();

            string strStopBits = sp.StopBits.ToString().ToLower();
            switch (strStopBits)
            {
                case "one": cmbStopBits.Text = "1"; break;
                case "two": cmbStopBits.Text = "2"; break;
                default: cmbStopBits.Text = "0";  break;
            }
            cmbEncode.SelectedIndex = int.Parse(myCommPort.sEncode);
            txtTotal.Text = myCommPort.sTotal;
            txtBitStart.Text = myCommPort.sBitStart;
            txtBitEndTag.Text = myCommPort.sBitEndTag;
            txtBitLength.Text = myCommPort.sBitLength;
            EnableControls("");
            btnReceive.Enabled = false;
            this.Icon = global::PRMS.Properties.Resources.ico_SerialPort2;
        }

        private void SetDataReceived(int n)
        {
            if (n > 0)
            { sp.DiscardInBuffer(); sp.DataReceived += new SerialDataReceivedEventHandler(ComPort_DataReceived); }
            else
            {
                try
                {
                    sp.DataReceived -=new SerialDataReceivedEventHandler(ComPort_DataReceived);
                }
                catch { }
            }
        }

        private void ShowText(string aString)
        {
            //根据通信数据规格显示数据
            try
            {
                rtfTerminal.AppendText(aString+"\n");
                rtfTerminal.ScrollToCaret();
                int nLines = rtfTerminal.Lines.Length;
                if (nLines > 12)
                {
                    int start = rtfTerminal.GetFirstCharIndexFromLine(0);
                    int length = rtfTerminal.Lines[0].Length;
                    rtfTerminal.Select(start, length + 1);
                    rtfTerminal.ReadOnly = false;
                    rtfTerminal.SelectedText = "";
                    rtfTerminal.ReadOnly = true;
                }
                nDataReceive += 1;
            }
            catch
            {
                
            }
        }

        private void ComPort_DataReceived(object sender,SerialDataReceivedEventArgs e)
        {
            if (nEncode == 0)
            {   strReceive = sp.ReadExisting();
                try
                {
                    string b = myFunction.Chr(nBitEndTag);
                    string[] c = myFunction.Split(strReceive, b);
                    strReceive = c[0].Substring(nBitStart);
                }
                catch { }
            }
            else
            {
                byte[] readBuffer = new byte[sp.ReadBufferSize];
                sp.Read(readBuffer, 0, readBuffer.Length);

                //只要截取需要重量数据
                char[] BytesToChars = new char[nBitLength];
                //字节开始截取,并转换成字符
                for (int i = nBitStart; i < nBitLength + nBitStart; i++)
                {
                    BytesToChars[i - nBitStart] = Convert.ToChar(readBuffer[i]);
                }
                //将字符数组转换字符串
                strReceive = new string(BytesToChars);
            }
            strReceive +="[" + strReceive.Length.ToString() + "]";
            sp.DiscardInBuffer();
            BeginInvoke(interfaceUpdateHandle, strReceive);
        }

        private void frmSetComm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (sp.IsOpen) { sp.DiscardInBuffer(); sp.Close(); }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (nNewTag < 10)
            {
                nNewTag += 1;
                if (nDataReceive ==0)
                {
                    if (sp.IsOpen)
                    {
                        rtfTerminal.Text = "没有接收到数据,请检查连线。";
                    }
                }
            }
            else
            { nNewTag = 0; nDataReceive = 0; }
        }

        private void cmbPortName_SelectedIndexChanged(object sender, EventArgs e)
        {
             EnableControls("");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (cmbPortName.Text == "")
            {
                MessageBox.Show("请选择一个串口,不能空。");
                return;
            }
            string UpdateResult =UpdateXML_CommPort();
            if ( UpdateResult== "OK")
            {
                myCommPort.sPortName = this.PortName;
                myCommPort.sBaudRate = cmbBaudRate.Text;
                myCommPort.sDataBits = cmbDataBits.Text;
                myCommPort.sStopBits = cmbStopBits.Text;
                myCommPort.sParity = cmbParity.SelectedIndex.ToString();
                myCommPort.sEncode = cmbEncode.SelectedIndex.ToString();
                myCommPort.sTotal = txtTotal.Text;
                myCommPort.sBitStart = txtBitStart.Text;
                myCommPort.sBitLength = txtBitLength.Text;
                myCommPort.sBitEndTag = txtBitEndTag.Text;
                this.DialogResult = DialogResult.OK;
            }
            else
            {
                MessageBox.Show(UpdateResult);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
        }

        private bool bReceive = false;

        private void btnReceive_Click(object sender, EventArgs e)
        {
            if (bReceive)
            {
                bReceive = false;
                btnReceive.Text = "接收数据";
                timer1.Enabled = false;
                SetProtolCotrols(true);
                SetDataReceived(0);
                rtfTerminal.ForeColor = LogMsgTypeColor[3];
            }
            else
            {
                
                try
                {
                    sp.Close();
                    sp.ReadBufferSize = int.Parse(txtTotal.Text);
                    sp.ReceivedBytesThreshold = int.Parse(txtTotal.Text);
                    sp.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("ReadBufferSize设置的"+ex.Message +"\n数据总长度请设置为偶数。", Application.ProductName, MessageBoxButtons.OK);
                    return;
                }
                nEncode = cmbEncode.SelectedIndex;
                nBitStart = int.Parse(txtBitStart.Text);
                nBitLength = int.Parse(txtBitLength.Text);
                nBitEndTag = int.Parse(txtBitEndTag.Text);
                bReceive = true;
                btnReceive.Text = "停止接收";
                SetDataReceived(1);
                timer1.Enabled = true;
                SetProtolCotrols(false);
                rtfTerminal.Clear();
                rtfTerminal.ForeColor = LogMsgTypeColor[0];
            }
        }

--------------------编程问答-------------------- 在接收事件里 用一个标识 控制serialport的接收 --------------------编程问答-------------------- 不太懂#3的意思,能给个实例吗?#2的代码我研究下。 --------------------编程问答--------------------  class ClsOther
    {
        private Thread reader;
        private SerialPort sPort;       
        public delegate void newzl(string data);
        public event newzl NewZL;
        public delegate void errer(string e);
        public event errer NewErrer;
        public string zl;

  
        /// <summary>
        /// 以指定参数初始化串口设备
        /// </summary>
        /// <param name="port">串口号</param>
        /// <param name="BR">波特率</param>
        /// <param name="DB">数据位</param>
        /// <param name="SB">停止位</param>
        /// <param name="P">校验</param>
        public ClsOtherXK(string port, int BR, int DB, StopBits SB, Parity P)
        {   sPort = new SerialPort(port);
                sPort.BaudRate = BR;
                sPort.DataBits = DB;
                sPort.StopBits = SB;
                sPort.Parity = P;               
                sPort.Open();
                this.reader = new Thread(new ThreadStart(this.Reader));
                this.reader.Start();
                this.reader.IsBackground = true;          
        }    
        private void Reader()//同步接收,解析
        {
string stemp = "";
                string sWeight = "";
                string s = "";

                    try
                    {
                        while (this.bstartread)
                        {
                            this.sPort.DiscardInBuffer();
                            stemp = "";
                            if (this.sPort.ReadByte() == 0xff)
                            {
                                for (int i = 0; i < 4; i++)
                                {
                                    stemp = stemp + string.Format("{0:X2}", this.sPort.ReadByte()) + " ";
                                }
                                Thread.Sleep(10);
                                char[] chArray = stemp.Replace(" ", "").ToCharArray();
                                sWeight = chArray[6].ToString() + chArray[7].ToString() + chArray[4].ToString() + chArray[5].ToString() + chArray[2].ToString() + chArray[3].ToString();
                                if (chArray[0].ToString().Equals("2") || chArray[0].ToString().Equals("3"))
                                {
                                    if (sWeight.IndexOf("FF") > 0)
                                    {
                                        continue;
                                    }
                                    sWeight = "-" + uint.Parse(sWeight.Trim()).ToString();
                                }
                                else
                                {
                                    if (sWeight.IndexOf("FF") > 0)
                                    {
                                        continue;
                                    }
                                    sWeight = uint.Parse(sWeight.Trim()).ToString();
                                } 
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (this.sPort.IsOpen)
                        {
                            this.sPort.DiscardInBuffer();
                            this.sPort.Close();
                        }                        
                    } 
        }
    } 
--------------------编程问答-------------------- 用一个Timer控件控制把 --------------------编程问答-------------------- 你得做个默认缓冲区。 --------------------编程问答-------------------- 如果可以监听
写到 windows服务里吧。 --------------------编程问答-------------------- while (true)
{
//
} --------------------编程问答-------------------- 谢谢大家的帮助,我正在根据大家的建议尝试程序,等程序调好了就会结贴。希望还有好方法的大大,不吝赐教! --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 很简单: 
private void serialPort3_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
                     
        } --------------------编程问答-------------------- 楼主,如果你是用C#的话,直接拖出一个控件serialPort,在DataReceived事件里面serialPort1.ReadExisting();获取接收的值(记得应该是字符串,也有方法是获取字节的,自己查)。接收后的业务逻辑自己处理,注意DataReceived事件里面控件线程安全控制 --------------------编程问答--------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace SerialAssistant
{
    class COM
    {
        public COM()
        {

        }

        ~COM()
        {

        }

        public System.IO.Ports.SerialPort serialPort = new System.IO.Ports.SerialPort();

        public bool IsOpen()
        {
            return (serialPort.IsOpen);
        }

        public string WriteToCom(byte[] buf, int len)
        {
            try
            {
                serialPort.Write(buf, 0, len);
            }
            catch (Exception err)
            {
                return err.Message;
            }
            return null;
        }

        public string WriteToCom(string buf)
        {
            try
            {
                serialPort.Write(buf);
            }
            catch (Exception err)
            {
                return err.Message;
            }
            return null;
        }

        public string OpenCom(  string ComPort, 
                                string ComBrd, 
                                string ComDataBits, 
                                string StopBits, 
                                string Parity
            )
        {
            if (!serialPort.IsOpen)
            {
                serialPort.PortName = ComPort;
                serialPort.BaudRate = Convert.ToInt32(ComBrd);
                serialPort.DataBits = Convert.ToInt32(ComDataBits);

                if (StopBits == "None")
                    serialPort.StopBits = System.IO.Ports.StopBits.None;
                else if (StopBits == "One")
                    serialPort.StopBits = System.IO.Ports.StopBits.One;
                else if (StopBits == "Two")
                    serialPort.StopBits = System.IO.Ports.StopBits.Two;
                else if (StopBits == "OnePointFive")
                    serialPort.StopBits = System.IO.Ports.StopBits.OnePointFive;
                
                if(Parity == "None")
                    serialPort.Parity = System.IO.Ports.Parity.None;
                else if (Parity == "Odd")
                    serialPort.Parity = System.IO.Ports.Parity.Odd;
                else if (Parity == "Even")
                    serialPort.Parity = System.IO.Ports.Parity.Even;
                else if (Parity == "Mark")
                    serialPort.Parity = System.IO.Ports.Parity.Mark;
                else if (Parity == "Space")
                    serialPort.Parity = System.IO.Ports.Parity.Space;

                try
                {
                    serialPort.Open();

                    serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
                }
                catch (Exception err)
                {
                    return err.Message;
                }
            }

            return null;
        }

        public string CloseCom()
        {
            if (serialPort.IsOpen)
            {
                try
                {
                    serialPort.Close();
                }
                catch (Exception err)
                {
                    return err.Message;
                }

            }
            return null;
        }

        const int BUFFSIZE = 2048;
        byte[] ReadBuff = new byte[BUFFSIZE];
        int ReadPos = 0;
        int ReadLen = 0;
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            ReadLen = serialPort.Read(ReadBuff, ReadPos, serialPort.BytesToRead);
            ReadPos += ReadLen;
        }

        public int ReadComDatas(byte[] dest, int second, int msecond)
        {
            int sec = second * 1000;//s -> ms
            int msec = msecond;

            ReadBuff.Initialize();
            ReadPos = 0;
            ReadLen = 0;

            while (true)
            {
                if (sec > 0) sec--;
                if (msec > 0) msec--;
                Thread.Sleep(1);//睡眠1ms
                
                if (sec == 0 && msec == 0)//如果超时,返回
                {
                    Array.Copy(ReadBuff, 0, dest, 0, ReadPos);
                    return 0;
                }
            }
        }
    }
}


我也提供一个com类,供楼主参考
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,