- 积分
- 40165
- 好友
- 记录
- 主题
- 帖子
- 听众
- 收听
|
发表于 2013-4-12 22:07:59
|
显示全部楼层
[code=csharp]using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Windows.Forms;
namespace modbus
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region 端口初始化及数据初始化处理
public SerialPort mySerialPort = new SerialPort();
private string btn_sender = "";
private const int read_num = 99;
private const int read_num2 = 60;
private Boolean received = false;
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
Array.Sort(ports);
comboPortName.Items.AddRange(ports);
comboPortName.SelectedIndex = comboPortName.Items.Count > 0 ? 0 : -1;
comboBaurate.SelectedIndex = comboBaurate.Items.IndexOf("9600");
comboParity.SelectedIndex = comboParity.Items.IndexOf("None");
comboDatabits.SelectedIndex = comboDatabits.Items.IndexOf("8");
comboStopBit.SelectedIndex = comboStopBit.Items.IndexOf("2");
Txtaddr.SelectedText = "1";
}
private void btnOpen_Click(object sender, EventArgs e)
{
String myParity;
String myStopBits;
myParity =comboParity.SelectedItem.ToString();
myStopBits =comboStopBit.SelectedItem.ToString();
//设置校验位
switch (myParity)
{
case "None":
mySerialPort.Parity = Parity.None;
break;
case "Even":
mySerialPort.Parity = Parity.Even;
break;
case "Odd":
mySerialPort.Parity = Parity.Odd;
break;
default:
mySerialPort.Parity = Parity.None;
break;
}
//设置数据位
mySerialPort.DataBits = Convert.ToInt32(comboDatabits.SelectedItem);
//设置停止位
switch (myStopBits)
{
case "1":
mySerialPort.StopBits = StopBits.One;
break;
case "2":
mySerialPort.StopBits = StopBits.Two;
break;
default:
mySerialPort.StopBits = StopBits.One;
break;
}
//采用ASCII编码方式
mySerialPort.Encoding=Encoding.ASCII;
//接收到一个字符就触发接收事件
mySerialPort.ReceivedBytesThreshold = 1;
if (mySerialPort.IsOpen) //判断串口当前状态
{
try
{
mySerialPort.Close();
}
catch (Exception err)
{
Portstatus.Text = "串口 " + comboPortName.Text + "关闭失败,错误信息: " + err.Message;
}
Portstatus.Text = "串口" + comboPortName.Text + ",关闭成功。";
}
else
{
//设置好端口名和波特率
mySerialPort.PortName = comboPortName.Text;
mySerialPort.BaudRate = int.Parse(comboBaurate.Text);
try
{
mySerialPort.Open();
}
catch (Exception err)
{
//打开失败,将错误信息给用户看,同时创建一个新的端口
Portstatus.Text = "串口" + comboPortName.Text + "打开失败,错误信息:" + err.Message;
mySerialPort = new SerialPort();
}
Portstatus.Text = "串口" + comboPortName.Text + ",打开成功。";
}
btnOpen.Text = mySerialPort.IsOpen ? "关闭串口" : "打开串口";
}
#endregion
#region 数据接收处理
private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] b = new byte[mySerialPort.BytesToRead];//定义byte数组,serialPort读取数据
this.mySerialPort.Read(b, 0, b.Length);
string str = "";
for (int i = 0; i < b.Length; i++)
{
str += string.Format("{0:X2} ", b);
}
switch (btn_sender)
{
case "读取":
txtRcv2.AppendText(str);
label06H.Text = "读取寄存器通讯正常";
break;
}
str = null;
received = true;
}
#endregion
#region 输入检测
//用来检测输入的数据是否有效
public static void formatstring(string strinput, int length, out string stroutput, out Boolean Valid)
{
stroutput = "";
Valid = true;
byte temp;
if ((strinput.Length <= length) & (strinput.Length > 0))
{
for (int i = 0; i < strinput.Length; i++)
{
try
{
//将指定基数的数字的字符串表示形式转换为等效的 8 位无符号整数。
temp = Convert.ToByte(strinput.ToString(), 16);
}
catch
{
Valid = false;
stroutput = "";
break;
}
stroutput += strinput;
}
if (Valid & (strinput.Length < length))
{ //判断字节长度,补零
for (int j = 0; j < length - strinput.Length; j++)
{
stroutput = "0" + stroutput;
}
}
}
else
{ //发生错误
Valid = false;
stroutput = "";
}
}
#endregion
#region 功能码03H,写寄存器
private void Fsc03H(string Staddr, string value)
{
byte[] defByte = new byte[6];
txtRcv2.Text = "";
//设备地址检测
string str1x_03 = Txtaddr.Text.ToString();
string str1_03 = "";
Boolean Macvalid1_03;
formatstring(str1x_03, 2, out str1_03, out Macvalid1_03);
if (!Macvalid1_03)
{
MessageBox.Show("设备地址数值不符合规范,最多输入2位十六进制数", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
byte[] numbyte1_03 = this.mysendb(str1_03);//先转换成数组类型然后赋值。
defByte[0] = numbyte1_03[0];
//功能码03H
string fun_str1_03 = "03";
byte[] fun_numbyte1_03 = this.mysendb(fun_str1_03);//打包方法,把字符串转换成Byte[]
defByte[1] = fun_numbyte1_03[0];
//起始地址
string str2x_03 = Staddr;
string str2_03 = "";
Boolean addrvalid2_03;
formatstring(str2x_03, 4, out str2_03, out addrvalid2_03);
if (!addrvalid2_03)
{
MessageBox.Show("寄存器地址数值不符合规范,最多输入4位十六进制数", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
byte[] numbyte2_03 = this.mysendb(str2_03);
defByte[2] = numbyte2_03[0];
defByte[3] = numbyte2_03[1];
// 数据数量(长度)
string str_num_03 = value;
Boolean num_valid_03 = true;
try
{
int num_03 = Convert.ToInt16(str_num_03);
Boolean numvalid = (Convert.ToInt16(str_num_03) > read_num);
}
catch
{
num_valid_03 = false;
}
if (!num_valid_03)
{
MessageBox.Show("输入寄存器数量不符合规范,请重新输入", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if ((Convert .ToInt16(str_num_03)>read_num) | (Convert.ToInt16(str_num_03) == 0))
{
MessageBox.Show("输入寄存器数量过大或为0,请重新输入", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
string str_num2_03 = Convert.ToString(Convert.ToInt16(str_num_03), 16);
string str3_03 = "";
Boolean vlvalid=true;
formatstring(str_num_03, 4, out str3_03, out vlvalid);
if (vlvalid)
{
byte[] numbyte3_03 = this.mysendb(str3_03);
defByte[4] = numbyte3_03[0];
defByte[5] = numbyte3_03[1];
//计算CRC
byte crch = 0;
byte crcl = 0;
CalculateCRC(defByte, defByte.Length, out crch, out crcl);
byte[] rebyte = new byte[defByte.Length + 2];
for (int i = 0; i < defByte.Length; i++)
{
rebyte = defByte;
}
rebyte[6] = crcl;
rebyte[7] = crch;
received = false;
this.mySerialPort.Write(rebyte, 0, rebyte.Length);//发送
timer1.Enabled = true;
textBoxInformation.AppendText("读取成功\r\n");
//显示发送内容
txtsend.Text = "";
string strsend = "";
for (int i = 0; i < rebyte.Length; i++)
{
strsend += string.Format("{0:X2} ", rebyte);
}
txtsend.Text = strsend;
strsend = null;
}
}
#endregion
#region 将字符串打包、空格删除
public byte[] mysendb(string s)
{
string temps=delspace(s);
if (temps.Length % 2 != 0)
{
temps = "0" + temps;
}
byte[] tempb = new byte[50];
int j = 0;
for (int i = 0; i < temps.Length; i = i + 2, j++)
{
tempb[j] = Convert.ToByte(temps.Substring(i, 2), 16);
}
byte[] send = new byte[j];
Array.Copy(tempb, send, j);
return send;
}
//空格删除
public string delspace(string putin)
{
string putout = "";
for (int i = 0; i < putin.Length; i++)
{
if (putin != ' ')
{
putout+= putin;
}
}
return putout;
}
#endregion
#region CRC
public static void CalculateCRC(byte[] pByte, int nNumberOfBytes, out ushort pChecksum)
{
int nBit;
ushort nShiftedBit;
pChecksum = 0xFFFF;
for (int nByte = 0; nByte < nNumberOfBytes; nByte++)
{
pChecksum ^= pByte[nByte];
for (nBit = 0; nBit < 8; nBit++)
{
if ((pChecksum & 0x1) == 1)
{
nShiftedBit = 1;
}
else
{
nShiftedBit = 0;
}
pChecksum >>= 1;
if (nShiftedBit != 0)
{
pChecksum ^= 0xA001;
}
}
}
}
public static void CalculateCRC(byte[] pByte, int nNumberOfBytes, out byte hi, out byte lo)
{
ushort sum;
CalculateCRC(pByte, nNumberOfBytes, out sum);
lo = (byte)(sum & 0xFF);
hi = (byte)((sum & 0xFF00) >> 8);
}
#endregion
private void btnread_Click(object sender, EventArgs e)
{
string a = Convert.ToString(5);
string b = Convert.ToString(1);
Fsc03H(a, b);
btn_sender = ((Button)sender).Text.ToString();
}
private void timer1_Tick_1(object sender, EventArgs e)
{
if (!received)
{
switch (btn_sender)
{
case "读取":
label03H.Text = "读取寄存器通讯超时,请检查设置";
break;
}
}
// textBoxInformation.AppendText("hah");
timer1.Enabled = false;
}
}
}
[/code]
代码我看没什么问题,你调试的时候返回的是什么,是无响应还是没有数据。
如果是没有数据,那应该是传的数据的问题,如果是接收时没有响应就应该是接收时的问题了
你调试看看是什么情况 |
|