基于Modbus的C#串口调试开发

说明:本文主要研究的是使用C# WinForm开发的串口调试软件(其中包含Modbus协议相关操作)。Modbus相关协议可以查阅百度文库等,可参考: 《http://wenku.baidu.com/link?url=J-QZeQVLfvfZh7_lh8Qf0MdwANZuVjEoTqox6zJYrSnKyfgES2RTb_bjC5ZTn8-xgsuUAyiELRYVA3-3FBkBGywWhQ9YGoavJOzwB0IxTyK 》。

  (1)先测试串口设置,发送和接收数据。

  (2)发送modbus的命令帧数据和使用DataReceived接收缓冲区的数据。

 

一、简单的串口调试工具

  下图为串口调试工具的界面,主要包括串口基本设置,功能操作,状态框以及发送接收框。由于这里只是简单的初始化数据,所以当需要发送数据的时候需要点击“串口检测”,来测试当前可用的串口,然后输入需要发送的数据,最后点击“发送数据”(由于测试需要,让发送什么数据就返回什么数据,这里的底层硬件做了短接处理,使用短接貌P30-P31,具体操作可以自行百度)

  

  

  1.1 发送数据操作

    (1)点击 串口检测

    (2)输入发送数据

    (3)点击 发送数据

    下面开始时具体代码:

    #1 软件打开时候初始化操作:Form1_Load(),主要初始化操作串口设置的下拉列表。

 1 private void Form1_Load(object sender, EventArgs e)
 2         {
 3             
 4             //设置窗口大小固定
 5             this.MaximumSize = this.Size;
 6             this.MinimumSize = this.Size;
 7 
 8             //1、设置串口下拉列表
 9             for ( int i = 0; i < 10; i++ ) 
10             {
11                 cbxCOMPort.Items.Add("COM" + (i + 1).ToString());
12             }
13             cbxCOMPort.SelectedIndex = 2;//默认选项
14 
15 
16             //2、设置常用波特率
17             int bt = 300;
18             for (int i = 0; i < 8; i++)
19             {
20                 cbxBaudRate.Items.Add(bt.ToString());
21                 bt *= 2;
22             }
23 
24             cbxBaudRate.Items.Add("38400");
25             cbxBaudRate.Items.Add("43000");
26             cbxBaudRate.Items.Add("56000"); 
27             cbxBaudRate.Items.Add("57600");
28             cbxBaudRate.Items.Add("115200");
29             cbxBaudRate.SelectedIndex = 5;
30 
31 
32             //3、列出停止位
33             cbxStopBits.Items.Add("0");
34             cbxStopBits.Items.Add("1");
35             cbxStopBits.Items.Add("1.5");
36             cbxStopBits.Items.Add("2");
37             cbxStopBits.SelectedIndex = 1;
38 
39             //4、设置奇偶检验
40             cbxParity.Items.Add("");
41             cbxParity.Items.Add("奇校验");
42             cbxParity.Items.Add("偶校验");
43             cbxParity.SelectedIndex = 0;
44 
45             //5、设置数据位
46             cbxDataBits.Items.Add("8");
47             cbxDataBits.Items.Add("7");
48             cbxDataBits.Items.Add("6");
49             cbxDataBits.Items.Add("5");
50             cbxDataBits.SelectedIndex = 0;
51 
52 
53         }
private void Form1_Load(object sender, EventArgs e)

 

    

    #2 检查串口基本设置的参数:CheckPortSetting(),

 1 /// <summary>
 2         /// 【检测端口设置】
 3         /// </summary>
 4         /// <returns></returns>
 5         private bool CheckPortSetting()
 6         {
 7             //检测端口设置
 8             if (cbxCOMPort.Text.Trim() == "" || cbxBaudRate.Text.Trim() == "" || cbxStopBits.Text.Trim() == "" || cbxParity.Text.Trim() == "" || cbxDataBits.Text.Trim() == "")
 9                 return false;
10             return true;
11         }
private bool CheckPortSetting()

 

    #3 设置串口属性,创建SerialPort对象  

 1 /// <summary>
 2         /// 【设置串口属性】
 3         /// </summary>
 4         private void SetPortProperty()
 5         {
 6             //1、设置串口的属性
 7             sp = new SerialPort();
 8 
 9             sp.ReceivedBytesThreshold = 1;//获取DataReceived事件发生前内部缓存区字节数
10             sp.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);//设置委托
11 
12             sp.PortName = cbxCOMPort.Text.Trim();
13 
14             //2、设置波特率
15             sp.BaudRate =  Convert.ToInt32( cbxBaudRate.Text.Trim());
16 
17             //3、设置停止位
18             float f = Convert.ToSingle( cbxStopBits.Text.Trim());
19 
20             if (f == 0) 
21             {
22                 sp.StopBits = StopBits.None;//表示不使用停止位
23             }
24             else if (f == 1.5)
25             {
26                 sp.StopBits = StopBits.OnePointFive;//使用1.5个停止位
27             }
28             else if (f == 2)
29             {
30                 sp.StopBits = StopBits.Two;//表示使用两个停止位
31             }
32             else
33             {
34                 sp.StopBits = StopBits.One;//默认使用一个停止位
35             }
36 
37             //4、设置数据位
38             sp.DataBits = Convert.ToInt16(cbxDataBits.Text.Trim());
39 
40             //5、设置奇偶校验位
41             string s = cbxParity.Text.Trim();
42             if (s.CompareTo("") == 0) 
43             {
44                 sp.Parity = Parity.None;//不发生奇偶校验检查
45             }
46             else if (s.CompareTo("奇校验") == 0)
47             {
48                 sp.Parity = Parity.Odd;//设置奇校验
49             }
50             else if (s.CompareTo("偶校验") == 0)
51             {
52                 sp.Parity = Parity.Even;//设置偶检验
53             }
54             else
55             {
56                 sp.Parity = Parity.None;
57             }
58 
59             //6、设置超时读取时间
60             sp.ReadTimeout = -1;
61 
62             //7、打开串口
63             try
64             {
65                 sp.Open();
66                 isOpen = true;
67             }
68             catch(Exception)
69             {
70                 lblStatus.Text = "打开串口错误!";
71             }
72 
73         }
private void SetPortProperty()

 

     

    #4 “发送数据”按钮点击事件:btnSend_Click(), 在发送数据需要进行,#2,#3验证,然后开始通过串口对象写入数据

 1     /// <summary>
 2         /// 【发送数据】
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void btnSend_Click(object sender, EventArgs e)
 7         {
 8             //发送串口数据
 9 
10             //1、检查串口设置
11             if (!CheckPortSetting()) 
12             {
13                 MessageBox.Show("串口未设置!", "错误提示");
14                 return;
15             }
16 
17             //2、检查发送数据是否为空
18             if(tbxSendData.Text.Trim() == ""){
19                  MessageBox.Show("发送数据不能为空");
20                  return;
21             }
22 
23             //3、设置
24             if (!isSetProperty) 
25             {
26                 SetPortProperty();
27                 isSetProperty = true;
28             }
29 
30             //4、写串口数据
31             if (isOpen)
32             {
33                 //写出口数据
34                 try
35                 {
36                     sp.Write(tbxSendData.Text);
37                     tbxStatus.Text = "发送成功!";
38                     
39 
40                     tbxRecvData.Text += sp.ReadLine();//读取发送的数据                    
41 
42                 }
43                 catch
44                 {
45                     tbxStatus.Text = "发送数据错误";
46                 }
47             }
48             else
49             {
50                 MessageBox.Show("串口未打开", "错误提示");
51             }
52 
53             
54         }                        

 

 

  1.2 接受数据操作

    接收数据和发送数据有点类似   

 1 /// <summary>
 2         /// 【读取数据】
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void btnRecv_Click(object sender, EventArgs e)
 7         {
 8             if(isOpen) 
 9             { 
10                 try  
11                 {
12                     //读取串口数据
13   
14                     tbxRecvData.Text += sp.ReadLine()+"\r\n"15                 }  
16                 catch(Exception) 
17                 {  
18                     lblStatus.Text = "读取串口时发生错误!"19                     return20                 } 
21             } 
22             else 
23             {  
24               MessageBox.Show("串口未打开!""错误提示"); 
25               return26                 
27             } 
28         }

 

 

  最后附上该窗体的后台代码:Form1.cs 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.IO.Ports;
  7 using System.Linq;
  8 using System.Text;
  9 using System.Threading.Tasks;
 10 using System.Windows.Forms;
 11 
 12 
 13 namespace 串口调试
 14 {
 15     public partial class Form1 : Form
 16     {
 17         SerialPort sp = null;
 18 
 19         bool isOpen = false;//是否打开
 20 
 21         bool isSetProperty = false;//是否通过串口设置
 22 
 23 
 24         public Form1()
 25         {
 26             InitializeComponent();
 27         }
 28 
 29         private void Form1_Load(object sender, EventArgs e)
 30         {
 31             
 32             //设置窗口大小固定
 33             this.MaximumSize = this.Size;
 34             this.MinimumSize = this.Size;
 35 
 36             //1、设置串口下拉列表
 37             for ( int i = 0; i < 10; i++ ) 
 38             {
 39                 cbxCOMPort.Items.Add("COM" + (i + 1).ToString());
 40             }
 41             cbxCOMPort.SelectedIndex = 2;//默认选项
 42 
 43 
 44             //2、设置常用波特率
 45             int bt = 300;
 46             for (int i = 0; i < 8; i++)
 47             {
 48                 cbxBaudRate.Items.Add(bt.ToString());
 49                 bt *= 2;
 50             }
 51 
 52             cbxBaudRate.Items.Add("38400");
 53             cbxBaudRate.Items.Add("43000");
 54             cbxBaudRate.Items.Add("56000"); 
 55             cbxBaudRate.Items.Add("57600");
 56             cbxBaudRate.Items.Add("115200");
 57             cbxBaudRate.SelectedIndex = 5;
 58 
 59 
 60             //3、列出停止位
 61             cbxStopBits.Items.Add("0");
 62             cbxStopBits.Items.Add("1");
 63             cbxStopBits.Items.Add("1.5");
 64             cbxStopBits.Items.Add("2");
 65             cbxStopBits.SelectedIndex = 1;
 66 
 67             //4、设置奇偶检验
 68             cbxParity.Items.Add("");
 69             cbxParity.Items.Add("奇校验");
 70             cbxParity.Items.Add("偶校验");
 71             cbxParity.SelectedIndex = 0;
 72 
 73             //5、设置数据位
 74             cbxDataBits.Items.Add("8");
 75             cbxDataBits.Items.Add("7");
 76             cbxDataBits.Items.Add("6");
 77             cbxDataBits.Items.Add("5");
 78             cbxDataBits.SelectedIndex = 0;
 79 
 80 
 81         }
 82 
 83 
 84         /// <summary>
 85         /// 【串口检测按钮】
 86         /// </summary>
 87         /// <param name="sender"></param>
 88         /// <param name="e"></param>
 89         private void btnCheckCOM_Cl
  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值