logo资料库

ModBus协议发送数据——从机和主机程序(c#).docx

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
模拟 ModBus 协议发送数据——从机和主机程序(c#) 2011-08-27 17:23 230 人阅读 评论(0) 收藏 举报 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.Threading; //为一个库,包含 thread namespace modbus_2 { public partial class Form1 : Form { public Form1() { } InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; //跨线程调用界面资源 private byte[] byRecBuff = new Byte[1024]; //为从串口接收到的数据预留空间 private byte[] array = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; //进行测试发送的 十个数据,主机和从机都可以使用 private byte[] byBcakFrame = new byte[15]; //在 GetFrame()函数得到的数据发在这个数组中来,然后对这个数组 中的数据来进行一定的处理
/// /// 进行串口初始化 /// /// /// private void Form1_Load(object sender, EventArgs e) { //byte[] array_1 = new byte[] { 0x01,0x03,0x0A,0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; //将所要发送的数据进行 CRC 校验,作为测试只用而已 serialPort1.BaudRate = 9600; //波特率 serialPort1.PortName = "COM1"; //端口号 serialPort1.Parity = System.IO.Ports.Parity.None; //校验位 serialPort1.DataBits = 8; //数据位 serialPort1.StopBits = System.IO.Ports.StopBits.One; //停止位 serialPort1.Open(); //打开端口 } /// /// 从机程序 /// 从串口获取数据并且在 text1 窗口中显示 /// /// private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { Thread.Sleep(1000); //具有休眠作用,使数据得到缓存,缓存一秒 int iCount = serialPort1.BytesToRead; //读取有多少个数据 /** **显示获取的数据长度 **/ string len = Convert.ToString(iCount); //将 int 型的 icount 转换成 string 类型 MessageBox.Show(len); //测试获取数据的长度
/** **从串口获取数据 **/ serialPort1.Read(byRecBuff, 0, iCount); //将数据存在数组 byRecBuff 中 /** **返还数据 **/ ushort iCRC = CRC16(byRecBuff, iCount - 2); if (((byte)(iCRC >> 8) == byRecBuff[iCount - 2]) && ((byte)(iCRC) == byRecBuff[iCount - 1])) //判断奇偶校 验码是否正确 { if (byRecBuff[0] == 0x01) //第一个是不是 01 { if (byRecBuff[1] == 0x03) //第二个是不是 03 { for (int i = 0; i < iCount; i++) { textBox1.Text += byRecBuff[i].ToString("X2"); //tostring 为将 byte 型数组转换成 string 的形式, X2 为一种格式,用来格式化数据 } int How_Many_To_Send = (byRecBuff[5]) * 2; byBcakFrame = new byte[How_Many_To_Send + 5]; //设定数组的存储空间大小 GetFrame(0x01, 0x03, (byte)How_Many_To_Send, array); //得到的数据存于 byBcakFrame 数组 serialPort1.Write(byBcakFrame, 0, How_Many_To_Send + 5); //将 byBcakFrame 数组中的数据 MessageBox.Show("数据返还成功"); 中去 发送出去 } } } } /// /// 主机程序
/// 在 text_box2 窗口中输入要显示的字符,点击按键从串口中发送出去 /// /// private void button1_Click(object sender, EventArgs e) { byte[] senddata = System.Text.Encoding.Default.GetBytes(textBox2.Text); //将 textbox 中的 string 类型数据放到 byte 型数组中去 //int datacount = Encoding.Default.; int datacount = senddata.Length; //获取动态数组长度 serialPort1.Write(senddata,0,datacount); //任意程度的数据发送 MessageBox.Show("数据发送成功"); } /// /// 点击按键,结束程序 /// /// /// private void button2_Click(object sender, EventArgs e) { } this.Dispose(); //程序结束执行 /// /// 进行奇偶校验 /// /// 测试的数据 /// 需要测试数据的长度 /// CRCResult 数据结果 public static ushort CRC16(byte[] data, int Len) {
const ushort polinomio = 0xA001; ushort result = 0xFFFF; for (int i = 0; i < Len; i++) { byte tmp = data[i]; result = (ushort)(tmp ^ result); for (int j = 0; j < 8; j++) { if ((result & 0x0001) == 1) { } result = (ushort)((result >> 1) ^ polinomio); else result = (ushort)(result >> 1); { } } } ushort CRCResult = (ushort)((result << 8) + (result >> 8)); return CRCResult; } /// /// 将测试过后的数据打包发到新数组中去,并且返回新数组 /// /// 地址码(第一位) /// 通信判断码(第二位) /// 数据位数(第三位) /// 返回的数组 private void GetFrame(byte byAddr, byte byFun, byte byByteNum, byte[] byData) { } int iCounts = 0; byBcakFrame[iCounts++] = byAddr; byBcakFrame[iCounts++] = byFun; byBcakFrame[iCounts++] = byByteNum; for (int i = 0; i < byByteNum; i++) //通过判断数据位数,来从数组中取出数据放到新数组中 { } byBcakFrame[iCounts++] = byData[i]; ushort iCRC = CRC16(byBcakFrame, iCounts); //得出新数组的奇偶校验之前的奇偶校验码 byBcakFrame[iCounts++] = (byte)(iCRC >> 8); //将奇偶校验码的前两位放入新数组中去 byBcakFrame[iCounts] = (byte)(iCRC); //将奇偶校验码的后两位放入新数组中去
} }
分享到:
收藏