使用.net的SerialPort串口监控控件接收串口数据

前述:

在一个项目中,需要从串口通信的磁卡读卡器中读取刷卡的卡号,以便后续的业务操作。该刷卡器的型号为:SMR-RU2,使用USB接入电脑,通过USB转串口,Windows会根据USB口分配器固定的串口号。本人使用了.net中自带的SerialPort串口监控控件来读取磁卡读卡器所读取的卡号,下面讲述具体细节。


使用SerialPort接受串口信号:


首先在创建一个From,并且在工具箱中拖入SerialPort控件,在这里我命名为mySerialPort,并拖进一个TextBox,一遍显示信号数据。


接着初始化SerialPort控件,代码如下

	/// 初始化控件
        /// </summary>
        /// <param name="portName"></param>
        private void InitMySerialPort(String portName)
        {
            if (mySerialPort != null)
            {
                mySerialPort.PortName = portName;//端口号,这里可以电脑已经连接的COM口,如COM1;
                mySerialPort.DataBits = 8;//设置每个字节的数据位,在这里我设置为8位,可以为7位
                mySerialPort.DiscardNull = false;
                mySerialPort.DtrEnable = false;
                mySerialPort.Handshake = Handshake.None;
                mySerialPort.Parity = Parity.None;
                mySerialPort.ParityReplace = Convert.ToByte("63");
                mySerialPort.RtsEnable = false;
                mySerialPort.StopBits = StopBits.One;
            }
            if (!mySerialPort.IsOpen)
            {
                mySerialPort.Open();//打开端口,进行监控
            }
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);//这个事件为最关键点,一旦端口收到信号,就会触发该事件,这个事件就是真正读取信号,以便做接下的业务。
        }

最后加上接受信号的事件:

 public void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            string s = "";
            int count = mySerialPort.BytesToRead;

            byte[] data = new byte[count];
            mySerialPort.Read(data, 0, count);

            foreach (byte item in data)
            {
                s += Convert.ToChar(item);
            }

            if (this.InvokeRequired)//由于是非创建线程访问textBox1,所以要使用代理句柄。要不然会抛异常,这点需要特别注意

            {
                this.Invoke(new MethodInvoker(delegate { this.textBox1.Text = s; }));
            }
            else
            {
                this.textBox1.Text = s;
            }
        }
以上为整个 SerialPort控件接收信号的代码,请大家多都指教,如有什么疑惑,可以留言,大家一起共同学习探讨!

已标记关键词 清除标记
相关推荐
运行后再richtextbox1中只显示一个数,例如:33 随后会报错:对象未引用到对象的实例,点了关闭后又会出现一个数据,例如31,之后又会报错,如此循环,而且数据不太对。 整了好久了,希望能帮帮忙,第一次做这,谢谢!! 代码: namespace yfy_串口调试 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /****************************设置变量******************************/ public string[] strArray; public SerialPort sp1 = new SerialPort(); public Byte[] mydata; public int mydatalength; //这个数的值是由接收到的字节长度决定的,并且作为mydata的长度,如果索引值还超过数组定义值,就应该是接收问题。 public int zhengfu = 2, now_x = 30; public static Bitmap bmp = new Bitmap(500,350); public Graphics gph = Graphics.FromImage(bmp); public char name_image='A'; /*****************************相关函数****************************/ public void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)//数据接收函数 { if (sp1.IsOpen==true ) //为了严谨性,加上检查串口是否被打开 { if (rbRcv16.Checked == true) //接收16进制按钮 { try { int average_speed = 0; //设置初始平均速度 Byte[] receivedData = new Byte[sp1.BytesToRead]; //创建接收字节数组 sp1.Read(receivedData, 0, receivedData.Length); //读取数据 sp1.DiscardInBuffer(); //清空SerialPort控件的Buffer mydatalength = receivedData.Length; for (int i = 0; i < receivedData.Length; i++) //窗体显示 { richTextBox1.Text = receivedData[i].ToString("X2"); //16进制显示在接受栏 mydata[i] = receivedData[i]; richTextBox1.Text += ","; //让每个数据都隔开 average_speed += receivedData[i]; } textBox1.Text = (average_speed / receivedData.Length).ToString("X2"); } catch (System.Exception ex) { MessageBox.Show(ex.Message, "出错提示"); } } } else { MessageBox.Show("请打开某个串口或者没有选中16进制接收", "错误提示"); } } private void Form1_Load(object sender, EventArgs e)//页面初始化 { Control.CheckForIllegalCrossThreadCalls = false; //强制不检查线程 sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); //订阅委托 sp1.ReceivedBytesThreshold =1; //当缓冲区的字节数为x时,触发datareceive事件 //检查是否有串口 string[] str = SerialPort.GetPortNames(); if (str == null) { MessageBox.Show("本机没有串口!", "Error!"); return; } //添加串口项目 foreach (string s in System.IO.Ports.SerialPort.GetPortNames()) { cbSerial.Items.Add(s); //获取有COM口 } rbRcv16.Checked = true; //接收数据按16进制进行 } private void btnSwitch_Click(object sender, EventArgs e)//设置串口 { if (sp1.IsOpen == false) { try { string serialName = cbSerial.SelectedItem.ToString();//读取串口号 sp1.PortName = serialName; //设置串口号 sp1.BaudRate = 9600; //波特率 sp1.DataBits = 8; //数据位 sp1.StopBits = StopBits.One; //停止位 sp1.Parity = Parity.None; //校验位 sp1.Open(); //打开串口 btnSwitch.Text = "关闭串口"; } catch (System.Exception ex) { MessageBox.Show("Error:" + ex.Message, "Error"); return; } } else { sp1.Close(); //关闭串口 btnSwitch.Text = "打开串口"; } }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页