page contents

基于C#实现串口通信

本文讲述了基于C#实现串口通信!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-05-NbWrETWj62902ac514110.png

本文讲述了基于C#实现串口通信!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

1.基本概念

2.前端winForm布局如下(仅仅为了实现功能,布局略丑)

3.代码实现如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
namespace SerialPortTest
  {
      public partial class Form1 : Form
      {
          SerialPort sp1 = new SerialPort();
          public Form1()
          {
              InitializeComponent();
          }
   
          private void Form1_Load(object sender, EventArgs e)
          {
        //分别对应前端的波特率、数字位、校验位、停止位
              cbBaudRate.SelectedIndex = 0;
              cbDataBits.SelectedIndex = 0;
              cbCheck.SelectedIndex = 0;
              cbStop.SelectedIndex = 0;
   
              string[] strCom = SerialPort.GetPortNames();
              if (strCom == null)
              {
                  MessageBox.Show("本机没有串口!", "Error");
                  return;
              }
              //GetPortNames()方法:获取当前计算机的串行端口名的数组
              foreach (string com in System.IO.Ports.SerialPort.GetPortNames())
              {
                  cbCom.Items.Add(com);
              }
   
              cbCom.SelectedIndex = 0;
              sp1.BaudRate = 9600;
              Control.CheckForIllegalCrossThreadCalls = false;
              sp1.DataReceived += Sp1_DataReceived;
                            
              sp1.DtrEnable = true;//获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。
              sp1.RtsEnable = true;//获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号
              //设置数据读取超时为1秒
              sp1.ReadTimeout = 1000;
   
              sp1.Close();
          }
   
          private void Sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
          {
              if (sp1.IsOpen)     //判断是否打开串口
              {
                  //输出当前时间
                  DateTime dt = DateTime.Now;
                  txtReceived.Text += dt.GetDateTimeFormats('f')[0].ToString() + "\r\n";
                  try
                  {
                      Byte[] receivedData = new Byte[sp1.BytesToRead];        //创建接收字节数组
                      sp1.Read(receivedData, 0, receivedData.Length);         //读取数据
                      AddContent(new UTF8Encoding().GetString(receivedData));//用万能的UTF8可以传输中文不会乱码
                  }
                 catch (System.Exception ex)
                  {
                      MessageBox.Show(ex.Message, "出错提示!!!!!");
                      txtSendStr.Text = "";
                  }
              }
              else
              {
                  MessageBox.Show("请打开某个串口", "错误提示");
              }
          }
   
          //将接受到的内容显示出来
          private void AddContent(string content)
          {
              this.BeginInvoke(new MethodInvoker(delegate
              {
                  txtReceived.AppendText(content);
                  txtReceived.AppendText("\r\n");
                  //记录收到的字符个数
                  lblRevCount.Text = (int.Parse(lblRevCount.Text) + content.Length).ToString();
              }));
          }
   
          private void btnOpen_Click(object sender, EventArgs e)
          {
              //serialPort1.IsOpen
              if (!sp1.IsOpen)
              {
                  try
                  {
                      //设置串口号
                      string serialName = cbCom.SelectedItem.ToString();
                      sp1.PortName = serialName;
   
                      //设置各“串口设置”
                      string strBaudRate = cbBaudRate.Text;
                      string strDateBits = cbDataBits.Text;
                      string strStopBits = cbStop.Text;
                      Int32 iBaudRate = Convert.ToInt32(strBaudRate);
                      Int32 iDateBits = Convert.ToInt32(strDateBits);
  
                     sp1.BaudRate = iBaudRate;       //波特率
                     sp1.DataBits = iDateBits;       //数据位
                     switch (cbStop.Text)            //停止位
                     {
                         case "1":
                             sp1.StopBits = StopBits.One;
                             break;
                         case "1.5":
                             sp1.StopBits = StopBits.OnePointFive;
                             break;
                         case "2":
                             sp1.StopBits = StopBits.Two;
                             break;
                         default:
                             MessageBox.Show("Error:参数不正确!", "Error");
                             break;
                     }
                     switch (cbCheck.Text)             //校验位
                     {
                         case "无":
                             sp1.Parity = Parity.None;
                             break;
                         case "奇校验":
                             sp1.Parity = Parity.Odd;
                             break;
                         case "偶校验":
                             sp1.Parity = Parity.Even;
                             break;
                         default:
                             MessageBox.Show("Error:参数不正确!", "Error");
                             break;
                     }
  
                     if (sp1.IsOpen == true)//如果打开状态,则先关闭一下
                     {
                         sp1.Close();
                     }
  
                     //设置必要控件不可用
                     cbCom.Enabled = false;
                     cbBaudRate.Enabled = false;
                     cbDataBits.Enabled = false;
                     cbStop.Enabled = false;
                     cbCheck.Enabled = false;
                     sp1.Open();     //打开串口
                     btnOpen.Text = "关闭串口";
                 }
                 catch (System.Exception ex)
                 {
                     MessageBox.Show("Error:" + ex.Message, "Error");
                     return;
                 }
             }
             else
             {
                 //恢复控件功能
                 //设置必要控件不可用
                 cbCom.Enabled = true;
                 cbBaudRate.Enabled = true;
                 cbDataBits.Enabled = true;
                 cbStop.Enabled = true;
                 cbCheck.Enabled = true;
                 sp1.Close();                    //关闭串口
                 btnOpen.Text = "打开串口";
             }
         }
  
         private void btnSend_Click(object sender, EventArgs e)
         {
             byte[] sendData = null;
             if (!sp1.IsOpen) //如果没打开
             {
                 MessageBox.Show("请先打开串口!", "Error");
                 return;
             }
             String strSend = txtSendStr.Text;
             try
             {
                 sendData = Encoding.UTF8.GetBytes(txtSendStr.Text.Trim());
                //sp1.WriteLine(txtSendStr.Text);    //写入数据
                 sp1.Write(sendData, 0, sendData.Length);
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Error:" + ex.Message, "Error");
}
  
}
  
}
}

4.测试运行结果如下

在自己同一台电脑上测试,需要先用Configure Virtual Serial Port Driver建立两个虚拟串口,如下

串口运行结果如下:

上述两窗体通信时要选择同一波特率,不然收发数据会失败

关于C# serialport的一些说明:

SerialPort() :如果未指定,则此构造函数使用默认属性值。 例如, DataBits 属性默认值为 8, Parity 属性默认为 None 枚举值,
StopBits 属性默认值为 1,默认端口名为 COM1。

public static string[] GetPortNames() :获取当前计算机的串行端口名的数组

SerialPort.Read 方法 (Byte[], Int32, Int32) :从 SerialPort 输入缓冲区读取一些字节并将那些字节写入字节数组中指定的偏移量处

SerialPort.ReadLine 方法 () :一直读取到输入缓冲区中的 NewLine 值

SerialPort.Write 方法 (Byte[], Int32, Int32) : 使用缓冲区中的数据将指定数量的字节写入串行端口

SerialPort.WriteLine 方法 (String) : 将指定的字符串和 NewLine 值写入输出缓冲区。

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg


  • 发表于 2022-05-27 09:35
  • 阅读 ( 376 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1312 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章