C#和Modbus通信工程

先介绍一下,这个项目是Modbus和C#关于声音播放器的内容。这篇文章介绍的事ModBus中串口的协议,相信看到这篇文章的都知道ModBus协议,先介绍主流的两种串口和TCP协议。
下载虚拟串口软件地址:https://files.cnblogs.com/files/wxylovejx/%E8%99%9A%E6%8B%9F%E4%B8%B2%E5%8F%A3VSPD6.9.zip

下载调试精灵软件地址:

https://files.cnblogs.com/files/wxylovejx/Modbus%E8%B0%83%E8%AF%95%E7%B2%BE%E7%81%B5-%E7%9B%91%E8%A7%86%E8%B0%83%E8%AF%95%E4%B8%B2%E5%8F%A3%E7%A8%8B%E5%BA%8FV1.024.zip


关于Modbus的内容就不多介绍,我介绍也是去网上查,可以先去查一下Modbus原理。

根据CModbusSlave类。先行下载研究类库:里面有方法读取,编写。根据读取寄存器内容(一个和多个)对应方法。CModbusSlave类下载地址:项目中包含

C#连接串口:

private static void ThreadSendCom()
{
Form1 operform2 = Form1.Instance();
while (true)//线程一直在发送,主程序做好标记,
{
//开始读写模块,功能16写
//把数字量模拟量进行IO分配。
Writing = false;
if (MainAskForStop)
{
Thread.Sleep(100);
continue;
}
try
{
if (!operform2.myserialPort.IsOpen)//避免这个访问无效
Thread.Sleep(500);
else if (operform2.myserialPort.IsOpen)//只要代开串口了,就发
{
Writing = true;
//Zigbee no need
//等待80ms,实际上可以更快,但是一定是完成通信后再继续。如果无法完成。在
//多个模块时,后续无法通信,干脆一直等待。AS3730模块程序可能有问题,有时需要
//关闭,打开串口才能通信。
if (ReciveOK)//20170521,如果没有收到就无限等待。避免485冲突,以后修改为以太网的。
{
//CModbusMasterAndModelConfig.SendDataToAS3700(operform2.myserialPort,0);
if (MainAskForStop)
{
Writing = false;
break;//直接跳出
}
Form1.SendCounter++;//每个模块一次
//SendID[ModelIndex] = 3;//标记
ReciveOK = false;
Thread.Sleep(80);
while (ReciveOK == false && MainAskForStop == false)//不断等待
{
Thread.Sleep(80);//20170521总是AS3700错误,修改到2倍等待时间。,增加到120,8个模块,880ms。以前80ms,等待100ms,再次发送。要求模块不要超过10个,而且模块的返回时间不要超过150ms
}
}
else if (MainAskForStop == false)
{
Thread.Sleep(80);
}

Writing = false;
}
}
catch (Exception ew1)
{
Debug.WriteLine(ew1.ToString());
Writing = false;
}
}//while串口打开的,就不断执行,否则退出。
}

private void OpenComm()
{
//if (MasterComPort > 0 && MasterComPort < 255)
//{
// try
// {
// //lock (m_locker)
// //{
// if (myserialPort.IsOpen)
// {
// myserialPort.Close(); //如果是打开的,则关闭一次
// }
// myserialPort.PortName = "COM" + MasterComPort.ToString();
// myserialPort.BaudRate = 115200;// 20160525修改为115200,以前是9600;
// myserialPort.Parity = Parity.None;
// myserialPort.DataBits = 8;
// myserialPort.StopBits = StopBits.One;
// myserialPort.Encoding = Encoding.ASCII;// Encoding.ASCII;
// myserialPort.ReceivedBytesThreshold = 1;//一个数据就中断
// myserialPort.WriteTimeout = 1000;
// myserialPort.ReadTimeout = 1000;
// //打开串口,主站采用线程不断发送
// if (myserialPort.IsOpen == false)//如果=0,可能没有设置,就没有从站
// {
// myserialPort.Open();
// if (thIsStart == false)
// {
// Thread th = new Thread(new ThreadStart(ThreadSendCom)); //也可简写为new Thread(ThreadMethod);
// th.Name = "CIS_AS3700_COM_SEND";
// th.Start(); //启动线程
// thIsStart = true;//只启动一次
// }
// }
// //}

// }
// catch (Exception ew1)
// {
// if (hadShowComError == false)
// {
// MessageBox.Show("指定的IO模块通信串口COM" + MasterComPort + "异常,可能不存在或已经打开", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// hadShowComError = true;
// }
// Debug.WriteLine(ew1.ToString());
// }
//}
if (SlaveComPort > 0 && SlaveComPort < 255)
{
if (myserialPortS.IsOpen) myserialPortS.Close(); //如果是打开的,则关闭一次
myserialPortS.PortName = "COM" + SlaveComPort.ToString();
myserialPortS.BaudRate = 115200;// 20160525修改为115200,以前是9600;
myserialPortS.Parity = Parity.None;
myserialPortS.DataBits = 8;
myserialPortS.StopBits = StopBits.One;
myserialPortS.Encoding = Encoding.ASCII;
myserialPortS.ReceivedBytesThreshold = 1;
//打开从站串口,但是没有必要开启线程。
try
{
if (myserialPortS.IsOpen == false)
{
myserialPortS.Open();
}
}
catch (Exception ew2)
{
if (hadShowComError == false)
{
MessageBox.Show("指定的Modbus从站串口" + SlaveComPort + "异常,可能不存在或已经打开", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
hadShowComError = true;
}
}
}
}

 C#接受数据:

private void myserialPortS_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
SerialPort a = myserialPortS;//传递到静态的CModbusSlave

try//20170626出现串口是关闭的。
{
byte[] b = new byte[myserialPortS.BytesToRead];//定义byte数组,serialPort读取数据
myserialPortS.Read(b, 0, b.Length);
bufferSlave.AddRange(b);
if (bufferSlave.Count >= 8) //数据超过45个,所以一定要返回20个数据。0,0,0
{//进行从站分析,并发送数据。
//byte SoundfileIndex = bufferSlave.ToArray()[5];
//if (SoundfileIndex == 1)
//{
// var p3 = new System.Windows.Media.MediaPlayer();
// p3.Open(new System.Uri("C:\\Users\\Administrator\\Desktop\\sound\\到站提示音.mp3"));
// p3.Play();
//}
//if(SoundfileIndex==2)
//{
// var p3 = new System.Windows.Media.MediaPlayer();
// p3.Open(new System.Uri("C:\\Users\\Administrator\\Desktop\\8960.wav"));
// p3.Play();
//}
//var p = new System.Windows.Media.MediaPlayer();
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count))=="0")
{

//p.Open(new System.Uri("C:\\Users\\Administrator\\Desktop\\sound\\地铁关门报警声.mp3"));
// p.Stop();
wmp.controls.stop();
}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "1")
{
//p.Open(new System.Uri("C:\\Users\\Administrator\\Desktop\\sound\\地铁关门报警声.mp3"));
//p.Play();
// wmp.URL = "C:\\Users\\Administrator\\Desktop\\sound\\地铁关门报警声.mp3";
wmp.URL =listView1.Items[0].Tag.ToString();
wmp.controls.play();
}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "2")
{
//p.Open(new System.Uri("C:\\Users\\Administrator\\Desktop\\sound\\火车到站鸣笛声.mp3"));
//p.Play();
wmp.URL = listView1.Items[1].Tag.ToString();
wmp.controls.play();

}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "3")
{

wmp.URL = listView1.Items[2].Tag.ToString();
wmp.controls.play();
}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "4")
{

wmp.URL = listView1.Items[3].Tag.ToString();
wmp.controls.play();
}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "5")
{

wmp.URL = listView1.Items[4].Tag.ToString();
wmp.controls.play();
}
if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "6")
{

wmp.URL = listView1.Items[5].Tag.ToString();
wmp.controls.play();
}

bufferSlave.RemoveRange(0, bufferSlave.Count);//全部删除
}
}
catch (Exception ew1)
{
}
}

 

项目下载地址:https://files.cnblogs.com/files/wxylovejx/SoundPlayback.zip

posted @ 2018-01-30 15:05  FakLove  阅读(7355)  评论(1编辑  收藏  举报