C#实现串口发送序列化数据
如下图:
其中红色框内展现的为实现效果图,其中最前面的文本框是要发送的具体字节,可以手动修改,后面的按钮为单击可控制单次发送,同时双机要发送的文本框可修改按钮的标题,用于做备注使用,后面的红色数字用于定义序列发送的顺序,我这里定义的是小于20,大于20的时候认为不转发,最后面的蓝色数字为发送完成后的等待时间,单位毫秒;
当下面的checkbox(循环)选中的时候,就开始按自定义序列发送,当不选中的时候,就停止发送,保存配置按钮,可以将上面修改的配置保存,下次启动程序调用配置,可省去从新编辑的时间。
下面简单说名一下编写方法:
单击循环checkbox函数
{
if(checkBox1.Checked)
{
forcanrun = true;//循环发送标志有效
//定义其他界面按钮的状态
btn_sttestcom.Text = "结束";
commname = comboBox4.Text;
commbps = combobps.Text;
commcrc = combocrc.SelectedIndex;
sendstr = richTextBox3.Text;
//收集上面文本框,发送序列号,延时时间的数据并保存到数组中
oradata();
//创建一个线程,用于控制并按顺序发送
forsend = new Thread(func_forsend);
forsend.IsBackground = true;
forsend.Start();
forcanrun = true;
Console.WriteLine("func_forsend thread started \r\n");
}
else//如果checkbox没有选中,停止发送,终止线程
{
forcanrun = false;
forsend.Join(0);
Console.WriteLine("func_forsend thread joined \r\n");
Thread.Sleep(1000);
}
}
//收集数据的函数,将数据保存到数组中
public string[] oradata()
{
arraytxt[0] = richTextBox3.Text;//发送str
arraytxt[1] = richTextBox4.Text;
arraytxt[2] = richTextBox5.Text;
arraytxt[3] = richTextBox6.Text;
arraytxt[4] = richTextBox7.Text;
arraytxt[5] = richTextBox8.Text;
arraytxt[6] = richTextBox9.Text;
arraytxt[7] = richTextBox10.Text;
arraytxt[8] = richTextBox11.Text;
arraytxt[9] = richTextBox12.Text;
arraytxt[10] = richTextBox13.Text;
arraytxt[11] = richTextBox14.Text;
arraytxt[12] = richTextBox15.Text;
arraytxt[13] = richTextBox16.Text;
sendindex[0] = Convert.ToInt16(textBox8.Text); //发送index
sendindex[1] = Convert.ToInt16(textBox10.Text);
sendindex[2] = Convert.ToInt16(textBox12.Text);
sendindex[3] = Convert.ToInt16(textBox14.Text);
sendindex[4] = Convert.ToInt16(textBox16.Text);
sendindex[5] = Convert.ToInt16(textBox18.Text);
sendindex[6] = Convert.ToInt16(textBox20.Text);
sendindex[7] = Convert.ToInt16(textBox22.Text);
sendindex[8] = Convert.ToInt16(textBox24.Text);
sendindex[9] = Convert.ToInt16(textBox26.Text);
sendindex[10] = Convert.ToInt16(textBox28.Text);
sendindex[11] = Convert.ToInt16(textBox30.Text);
sendindex[12] = Convert.ToInt16(textBox32.Text);
sendindex[13] = Convert.ToInt16(textBox34.Text);
sleeptime[0] = Convert.ToInt16(textBox9.Text);//发送 delay
sleeptime[1] = Convert.ToInt16(textBox11.Text);
sleeptime[2] = Convert.ToInt16(textBox13.Text);
sleeptime[3] = Convert.ToInt16(textBox15.Text);
sleeptime[4] = Convert.ToInt16(textBox17.Text);
sleeptime[5] = Convert.ToInt16(textBox19.Text);
sleeptime[6] = Convert.ToInt16(textBox21.Text);
sleeptime[7] = Convert.ToInt16(textBox23.Text);
sleeptime[8] = Convert.ToInt16(textBox25.Text);
sleeptime[9] = Convert.ToInt16(textBox27.Text);
sleeptime[10] = Convert.ToInt16(textBox29.Text);
sleeptime[11] = Convert.ToInt16(textBox31.Text);
sleeptime[12] = Convert.ToInt16(textBox33.Text);
sleeptime[13] = Convert.ToInt16(textBox35.Text);
string arrtxt1="";
int sendindex1=0;
int sleeptime1=0;
for (int m = 0; m < 14;m++ )
{
for(int j=m+1;j<14;j++)
{
if(sendindex[j]<sendindex[m])
{
sendindex1 = sendindex[j];
arrtxt1 = arraytxt[j];
sleeptime1 = sleeptime[j];
sendindex[j] = sendindex[m];
arraytxt[j] = arraytxt[m];
sleeptime[j] = sleeptime[m];
sendindex[m] = sendindex1;
arraytxt[m] = arrtxt1;
sleeptime[m] = sleeptime1;
}
}
}
return arraytxt;
}
//发送数据的线程函数
public void func_forsend()
{
while (forcanrun)//用于控制当checkbox无效的时候,线程就退出了。
{
for (int i = 0; i < 14; i++)
{
if (sendindex[i] < 20) //如果不想发送,可定义为20或则以上
{
string bb="";
if (crcselectindex > 0)
bb = GetCRCData(arraytxt[i]);//根据要发送的数据,计算crc校验码并添加到最后的字符位置。
else
bb = arraytxt[i];
int n = 0;
//此处可以自己修改,我这里实现的是网络模式和串口模式都兼容的
if (!netflag)//串口模式,具体怎么发送这里就不啰嗦了
{
n = ycomm.Sendstr(bb, Convert.ToInt16(ycomm.HexFlag));
}
else//网络模式
{
if (netclientflag)//客户端模式
n = csocket.Sendstr(bb, csocket.hexflag);
else//服务端模式
{
if(scsocket.islisten)
n = scsocket.SendData(bb);
}
}
string sendstr1 = "";
//如果成功发送,将数据显示到界面上,并增加时标
if (n > 0)
{
if (timebz)
{
DateTime t1 = DateTime.Now;
sendstr1 = "[" + t1.Hour.ToString("00") + ":" + t1.Minute.ToString("00") + ":" + t1.Second.ToString("00") + "." + t1.Millisecond.ToString("000") + "] ";
}
//次数显示数据用委托实现。
ShowThreadDataToRec(sendstr1 + "发→◇: " + bb + "\r\n");
if (savefilebz)//如果寸日志标志有效,保存报文到文件
txtfile.WriteLogFile("发→◇: " + bb + "\r\n", "报文保存", 1);
}
Thread.Sleep(sleeptime[i]);//发送完成后,延时一定时间,放置串口堵塞
}
}
}
}
具体如何使用串口和网络发送数据以及如何计算校验码的实现代码,这里就不萝莉啰嗦的折腾了。