C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)

这篇具有很好参考价值的文章主要介绍了C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、串口通信概述

1.1 串口通信

串口是串行接口(serial port)的简称,也称为 串行通信接口 或 COM接口。
串口通信(serial communication)是指采用串行通信协议在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式。
串口按电气标准及协议来划分,包括RS-232-C、RS-422、RS485等。

1.2 串行通信

在串行通信中,数据在1位宽的单条线路上进行传输,一个字节的数据要分为8次,由低位到高位按顺序一位一位的进行传送。

串行通信的数据是逐位传输的,发送方发送的每一位都具有固定的时间间隔,这就要求接收方也要按照发送方同样的时间间隔来接收每一位。不仅如此,接收方还必须能够确定一个信息组的开始和结束。

常用的两种基本串行通信方式包括同步通信和异步通信。

1.2.1 串行同步通信

同步通信(SYNC:synchronous data communication)是指在约定的通信速率下,发送端和接收端的时钟信号频率和相位始终保持一致(同步),这样就保证了通信双方在发送和接收数据时具有完全一致的定时关系。

同步通信把许多字符组成一个信息组(信息帧),每帧的开始用同步字符来指示,一次通信只传送一帧信息。在传输数据的同时还需要传输时钟信号,以便接收方可以用时针信号来确定每个信息位。

优点:传送信息的位数几乎不受限制,一次通信传输的数据有几十到几千个字节,通信效率较高。
缺点:要求在通信中始终保持精确的同步时钟,即发送时钟和接收时钟要严格的同步(常用的做法是两个设备使用同一个时钟源)。

1.2.2 串行异步通信

异步通信(ASYNC:asynchronous data communication),又称为起止式异步通信,是以字符为单位进行传输的,字符之间没有固定的时间间隔要求,而每个字符中的各位则以固定的时间传送。

在异步通信中,收发双方取得同步是通过在字符格式中设置起始位和停止位的方法来实现的。具体来说就是,在一个有效字符正式发送之前,发送器先发送一个起始位,然后发送有效字符位,在字符结束时再发送一个停止位,起始位至停止位构成一帧。停止位至下一个起始位之间是不定长的空闲位,并且规定起始位为低电平(逻辑值为0),停止位和空闲位都是高电平(逻辑值为1),这样就保证了起始位开始处一定会有一个下跳沿,由此就可以标志一个字符传输的起始。而根据起始位和停止位也就很容易的实现了字符的界定和同步。

显然,采用异步通信时,发送端和接收端可以由各自的时钟来控制数据的发送和接收,这两个时钟源彼此独立,可以互不同步。

下面简单的说说异步通信的数据发送和接收过程。

1.2.2.1 异步通信的数据格式

在介绍异步通信的数据发送和接收过程之前,有必要先弄清楚异步通信的数据格式。

异步通信规定传输的数据格式由起始位(start bit)、数据位(data bit)、奇偶校验位(parity bit)和停止位(stop bit)组成,如图1所示(该图中未画出奇偶校验位,因为奇偶检验位不是必须有的,如果有奇偶检验位,则奇偶检验位应该在数据位之后,停止位之前)。
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)

起始位:起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。

数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是5位、7位或8位,标准的ASCII码是0 ~127(7位),扩展的ASCII码是0 ~255(8位)。传输数据时先传送字符的低位,后传送字符的高位。

奇偶校验位:奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。

举例来说,假设传输的数据位为01001100,如果是奇校验,则奇校验位为0(要确保总共有奇数个1),如果是偶校验,则偶校验位为1(要确保总共有偶数个1)。

由此可见,奇偶校验位仅是对数据进行简单的置逻辑高位或逻辑低位,不会对数据进行实质的判断,这样做的好处是接收设备能够知道一个位的状态,有可能判断是否有噪声干扰了通信以及传输的数据是否同步。

停止位:停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。

空闲位:空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。

1.2.2.2 异步通信的数据发送过程

清楚了异步通信的数据格式之后,就可以按照指定的数据格式发送数据了,发送数据的具体步骤如下:

初始化后或者没有数据需要发送时,发送端输出逻辑1,可以有任意数量的空闲位。

当需要发送数据时,发送端首先输出逻辑0,作为起始位。

接着就可以开始输出数据位了,发送端首先输出数据的最低位D0,然后是D1,最后是数据的最高位。

如果设有奇偶检验位,发送端输出检验位。

最后,发送端输出停止位(逻辑1)。

如果没有信息需要发送,发送端输出逻辑1(空闲位),如果有信息需要发送,则转入步骤(2)。

1.2.2.3 异步通信的数据接收过程

在异步通信中,接收端以接收时钟和波特率因子决定每一位的时间长度。下面以波特率因子等于16(接收时钟每16个时钟周期使接收移位寄存器移位一次)为例来说明。

开始通信,信号线为空闲(逻辑1),当检测到由1到0的跳变时,开始对接收时钟计数。
当计到8个时钟的时候,对输入信号进行检测,若仍然为低电平,则确认这是起始位,而不是干扰信号。

接收端检测到起始位后,隔16个接收时钟对输入信号检测一次,把对应的值作为D0位数据。
再隔16个接收时钟,对输入信号检测一次,把对应的值作为D1位数据,直到全部数据位都输入。
检验奇偶检验位。

接收到规定的数据位个数和校验位之后,通信接口电路希望收到停止位(逻辑1),若此时未收到逻辑1,说明出现了错误,在状态寄存器中置“帧错误”标志;若没有错误,对全部数据位进行奇偶校验,无校验错时,把数据位从移位寄存器中取出送至数据输入寄存器,若校验错,在状态寄存器中置“奇偶错”标志。

本帧信息全部接收完,把线路上出现的高电平作为空闲位。

当信号再次变为低时,开始进入下一帧的检测。

1.3 串行通讯中的TTL、RS-232、RS-485、COM口、UART、串口

串口、UART口、COM口、USB口是指的物理接口形式(物理硬件)。

而TTL、RS-232、RS-485是指的电平标准(电信号)。

串口:串口是一个泛称,UART,TTL,RS232,RS485都遵循类似的通信时序协议,因此都被通称为串口。

UART接口:通用异步收发器(Universal Asynchronous Receiver/Transmitter),UART是串口收发的逻辑电路,这部分可以独立成芯片,也可以作为模块嵌入到其他芯片里,单片机、SOC、PC里都会有UART模块。

COM口:特指台式计算机或一些电子设备上的D-SUB外形(一种连接器结构,VGA接口的连接器也是D-SUB)的串行通信口,应用了串口通信时序和RS232的逻辑电平。

TTL,RS232,RS485都是一种逻辑电平的表示方式

TTL:TTL指双极型三极管逻辑电路,市面上很多“USB转TTL”模块,实际上是“USB转TTL电平的串口”模块。这种信号0对应0V,1对应3.3V或者5V。与单片机、SOC的IO电平兼容。不过实际也不一定是TTL电平,因为现在大部分数字逻辑都是CMOS工艺做的,只是沿用了TTL的说法。我们进行串口通信的时候从单片机直接出来的基本是都是 TTL 电平。

TTL电平:全双工(逻辑1: 2.4V–5V逻辑0: 0V–0.5V)
硬件框图如下,TTL用于两个MCU间通信
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
‘0’和‘1’表示
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)

RS232:是电子工业协会(Electronic Industries Association,EIA) 制定的异步传输标准接口,同时对应着电平标准和通信协议(时序),其电平标准:+3V~+15V对应0,-3V~-15V对应1。

RS232 的逻辑电平和TTL 不一样但是协议一样。

RS-232电平:全双工(逻辑1:-15V–5V 逻辑0:+3V–+15V)

硬件框图如下,RS232用于MCU与PC机之间通信
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
‘0’和‘1’表示
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
RS485:RS485是一种串口接口标准,为了长距离传输采用差分方式传输,传输的是差分信号,抗干扰能力比RS232强很多。两线压差为-(26)V表示0,两线压差为+(26)V表示1

RS-485:半双工、(逻辑1:+2V–+6V 逻辑0:-6V—2V)这里的电平指AB 两线间的电压差。

硬件框图如下
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
‘0’和‘1’表示
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)

1.4 串口通讯协议

串口协议是一种基于串行通信的数据传输协议。它通过串口接口将数据以串行的方式传输。串口协议通常包括物理层、数据链路层和应用层三个部分,其中物理层主要定义了串口接口的电气特性,数据链路层定义了数据的传输方式和错误检测机制,应用层定义了具体的数据格式和通信协议。

1.4.1 物理层

串口协议的物理层主要定义了串口接口的电气特性,包括传输速率、数据位、停止位、奇偶校验等。常见的串口接口有RS-232、RS-422、RS-485等。

1.4.2数据链路层

串口协议的数据链路层定义了数据的传输方式和错误检测机制。串口通信采用异步传输方式,即每个数据字节之间没有固定的时间间隔。在数据传输时,每个字节都以一个起始位和一个或多个停止位作为帧定界符,以便接收端能够识别每个字节的开始和结束。

串口协议还包括奇偶校验机制和流控制机制。奇偶校验机制可以检测数据传输过程中的错误,流控制机制可以控制数据的传输速率,防止数据丢失或溢出。

1.4.3 应用层

串口协议的应用层定义了具体的数据格式和通信协议。常见的串口协议有Modbus(ascii,RTU)、三菱FX系列编程口专用协议、西门子S7-200系列PLC PPI专用协议、西门子USS协议(USS协议(USS Protocol)是西门子公司推出的用于控制器(PLC/PG/PC)与驱动装置之间数据交换的通信协议)、自定义协议等等。不同的应用场景需要使用不同的串口协议。

二、三菱FX3U编程口通讯协议概述

三菱FX3u编程口用于PLC程序的下载和上传、程序调试监控、和其它设备(变频器、上位机、打印机等等)的通信,数据通信使用三菱FX3u编程口专用协议。

通过专用协议,可以实现:

  • PLC内部存储区(X、Y、M、S、T、C、D)数据的单个、批量读、写操作
  • PLC程序的上传和下载
  • 控制PLC的run、stop状态
    具体的通信数据格式参考《三菱FX编程口协议.pdf》链接地址

三、 C#上位机与三菱FX3UPLC实现异步伪实时串口通信

3.1 通信库

根据《三菱FX编程口协议.pdf》文档,可以手动封装各读写命令数据帧,也可以使用第三方通信库。

这里使用HslCommunication通信库,官方网址链接,能够实现三菱PLC的读写、西门子PLC的读写、欧姆龙PLC读写、Modbus Tcp读写、Modbus服务器开发、日志记录功能。

HslCommunication通信库的使用可以参考1)C# Demo源代码地址;2)通讯库使用说明blog。

3.2 UI界面设计

(1). 新建工程
打开vs2019,新建windowsForm应用。
(2). 使用nuget添加HslCommunication通信库
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
打开Form1.cs代码编辑器界面,添加HslCommunication相关命名空间的引用

using HslCommunication;
using HslCommunication.Profinet.Melsec;

(3). UI界面设计
在UI界面设计器中,使用label、Textbox、ComboBox、button、groupBox设计如下的界面。
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
其中端口号使用textbox控件,使用时根据使用计算机com口实际使用端口号,手动输入。
波特率comboBox手动添加两个item,9600和115200。
(4) 添加全局字段

        //定义PLC对象
        private MelsecFxSerial FxSerial = new MelsecFxSerial();
        //定义obj用于进程锁
        private object obj = new object();
        //定义定时器,用于周期读取X、Y、M区变量
        System.Timers.Timer timer = new System.Timers.Timer();

3.3 PLC的连接和断开

3.3.1 PLC的连接

为“连接”按钮添加如下代码:

        /// <summary>
        /// 连接串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            FxSerial.SerialPortInni(sp =>
            {
                sp.PortName = tbx_port.Text;
                sp.BaudRate = int.Parse(cbx_baud.Text) ;
                sp.DataBits = 7;
                sp.StopBits = System.IO.Ports.StopBits.One;
                sp.Parity = System.IO.Ports.Parity.Even;
            }
            );
            try
            {
                FxSerial.Open();
                timer.Start();
                MessageBox.Show("串口打开!");
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }

        }

3.3.2 PLC的断开

为“断开”按钮添加如下代码:

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            FxSerial.Close();
            FxSerial.Dispose();
            timer.Stop();
            MessageBox.Show("串口关闭");
        }

3.4 为Form1的load事件添加相关初始化代码

主要完成两个任务:1)定时器初始化;2)3组label的初始化(因为相关属性基本一致,使用代码完成属性设置更快;这里每个label的mouseDown事件调用同一个方法)。
X、Y、M三组label的text属性和变量地址对应

        private void Form1_Load(object sender, EventArgs e)
        {
            //定时器初始化
            timer.Elapsed += new System.Timers.ElapsedEventHandler(onTimerTrig);
            timer.AutoReset = true;
            timer.Interval = 500;
            timer.Enabled = false;

            lbl_y0.BackColor = Color.Red;
            lbl_y1.BackColor = Color.Red;
            lbl_y2.BackColor = Color.Red;
            lbl_y3.BackColor = Color.Red;
            lbl_y4.BackColor = Color.Red;
            lbl_y5.BackColor = Color.Red;
            lbl_y6.BackColor = Color.Red;
            lbl_y7.BackColor = Color.Red;

            lbl_y0.MouseDown += Lbl_MouseDown;
            lbl_y1.MouseDown += Lbl_MouseDown;
            lbl_y2.MouseDown += Lbl_MouseDown;
            lbl_y3.MouseDown += Lbl_MouseDown;
            lbl_y4.MouseDown += Lbl_MouseDown;
            lbl_y5.MouseDown += Lbl_MouseDown;
            lbl_y6.MouseDown += Lbl_MouseDown;
            lbl_y7.MouseDown += Lbl_MouseDown;

            lbl_m0.BackColor = Color.Red;
            lbl_m1.BackColor = Color.Red;
            lbl_m2.BackColor = Color.Red;
            lbl_m3.BackColor = Color.Red;
            lbl_m4.BackColor = Color.Red;
            lbl_m5.BackColor = Color.Red;
            lbl_m6.BackColor = Color.Red;
            lbl_m7.BackColor = Color.Red;

            lbl_m0.MouseDown += Lbl_MouseDown;
            lbl_m1.MouseDown += Lbl_MouseDown;
            lbl_m2.MouseDown += Lbl_MouseDown;
            lbl_m3.MouseDown += Lbl_MouseDown;
            lbl_m4.MouseDown += Lbl_MouseDown;
            lbl_m5.MouseDown += Lbl_MouseDown;
            lbl_m6.MouseDown += Lbl_MouseDown;
            lbl_m7.MouseDown += Lbl_MouseDown;
        }

Lbl_MouseDown方法代码:

        private void Lbl_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            {
            	//根据label的text属性值作为变量地址,根据背景色决定即将写入的bool值
                Write_Bool(((Label)sender).Text, (((Label)sender).BackColor == Color.Red) ? true : false);
            }
        }
        
        private bool Write_Bool(string addr,bool bVal)
        {
            bool res = false;
            //FxSerial同一时间只能有一个线程独占使用,使用lock语句获取并独占对FxSerial的使用权
            lock (obj)
            {
                if (FxSerial.IsOpen() == true)
                {
                    OperateResult Write_res = FxSerial.Write(addr, bVal);
                    if (Write_res.IsSuccess)
                    {
                        //MessageBox.Show("写入成功");
                        res=  true;
                    }
                }
                else
                {
                    timer.Stop();
                    MessageBox.Show("串口已关闭");
                }
                return res;
            }
        }

3.5 异步、多线程实现C#上位机周期读取三菱FX3UPLC存储区

3.5.1 定义更新ui方法

        /// <summary>
        /// X区、Y区、M区 lbl背景色更新(用来指示各存储区位变量状态)
        /// </summary>
        /// <param name="bool_res"></param>
        /// <param name="addrType"></param>
        public void UpdateForm(bool[] bool_res, string addrType)
        {
            switch (addrType)
            {
                case "X":
                    if (this.IsHandleCreated)
                    {
                        this.Invoke(new Action(() =>
                        {
                            foreach (var c in groupBox3.Controls)
                            {
                                if (c is Label)
                                {
                                    ((Label)c).BackColor = bool_res[int.Parse(((Label)c).Text.Substring(1, 1))] ? Color.Green : Color.Red;
                                }
                            }
                        }));
                    }
                    break;
                case "M":
                    if (this.IsHandleCreated)
                    {
                        this.Invoke(new Action(() =>
                        {
                            foreach (var c in groupBox5.Controls)
                            {
                                if (c is Label)
                                {
                                    ((Label)c).BackColor = bool_res[int.Parse(((Label)c).Text.Substring(1, 1))] ? Color.Green : Color.Red;
                                }
                            }
                        }));
                    }
                    break;
                case "Y":
                    if (this.IsHandleCreated)
                    {
                        this.Invoke(new Action(() =>
                        {
                            foreach (var c in groupBox4.Controls)
                            {
                                if (c is Label)
                                {
                                    ((Label)c).BackColor = bool_res[int.Parse(((Label)c).Text.Substring(1, 1))] ? Color.Green : Color.Red;
                                }
                            }
                        }));
                    }
                    break;
                default:
                    break;
            }

        }

3.5.2 定义带参数的委托

        /// <summary>
        /// 声明一个带参数的委托
        /// </summary>
        /// <param name="bool_res"></param>
        /// <param name="addrType"></param>
        public delegate void MyInvoke(bool[] bool_res,string addrType);

3.5.3 定时器事件处理程序/方法

        /// <summary>
        /// 定时器事件处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void onTimerTrig(object sender, ElapsedEventArgs e)
        {
            //周期读取变量
            //这里的sw用于计算以下代码执行时间
            sw.Restart();
            lock (obj)
            {
                if (FxSerial.IsOpen() == true)
                {
                    // 读M区
                    try
                    {
                        OperateResult<bool[]> Read_res = FxSerial.ReadBool("m0", 8);
                        if (Read_res.IsSuccess)
                        {
                            bool[] read_bool_res = Read_res.Content;
                            MyInvoke mi = new MyInvoke(UpdateForm);
                            this.BeginInvoke(mi, new Object[] { read_bool_res, "M" });
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }

                    // 读Y区
                    try
                    {
                        OperateResult<bool[]> Read_res = FxSerial.ReadBool("y0", 8);
                        if (Read_res.IsSuccess)
                        {
                            bool[] read_bool_res = Read_res.Content;
                            MyInvoke mi = new MyInvoke(UpdateForm);
                            this.BeginInvoke(mi, new Object[] { read_bool_res, "Y" });
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }

                    // 读X区
                    try
                    {
                        OperateResult<bool[]> Read_res = FxSerial.ReadBool("x0", 8);
                        if (Read_res.IsSuccess)
                        {
                            bool[] read_bool_res = Read_res.Content;
                            MyInvoke mi = new MyInvoke(UpdateForm);
                            this.BeginInvoke(mi, new Object[] { read_bool_res, "X" });
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }

                }
                else
                {
                    MessageBox.Show("串口已关闭");
                    timer.Stop();
                }

            }
            //这里的sw用于计算以下代码执行时间
            sw.Stop();
            Console.WriteLine("time= {0}", sw.ElapsedMilliseconds.ToString());
        }

4. 运行测试

运行后,初始化界面如下:
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
运行操作动画:
主要演示了PLC的连接和关闭;
PLC改变存储区变量值,上位机可以同步修改;在上位机右键单击Y区和M区label,对应的label标签背景色相应反转,同时PLC对应地址值也发生变化。操作过程中界面无卡顿。
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)
通过输出窗口,可以看到定时器事件处理程序一次执行大概消耗130ms。
C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)

5 源码下载链接

单击打开源码下载链接
不定期分享c#、wpf上位机开发学习经验,欢迎交流。
点赞、收藏加关注,让你永远不迷路。文章来源地址https://www.toymoban.com/news/detail-420086.html

到了这里,关于C#上位机与三菱FX3UPLC实现异步伪实时串口通信机制(串口类通信可参考)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【】三菱FX3U-48MT/ES PLC 控制台达ASDA-B2伺服驱动器

    (对此篇文章有任何疑问,欢迎一起交流) 1. 控制前提条件与控制原理 1 .1   三菱 F X3U-48MT/ES 控制伺服驱动器的前提条件 1.1.1 三菱FX3U-48MT/ES可以进行程序的上传、下载。 1.1.2 理解伺服电机与减速器、脉冲量、以及电子轮比之间的关系。 1.1.3 PLC与伺服驱动器接线正确,伺服

    2024年02月12日
    浏览(42)
  • C# 三菱PLC上位机开发环境搭建

    一、安装软件 用到两个三菱的软件: 1. MX Component(下载地址 也可以直接在官网上搜索,注意MX后面有空格) 用于连接PLC 2. GX Works2(下载地址 用GX Works3也行) 这个软件主要是电气做PLC编程,我们用来作为仿真,省去开发时摆弄真实PLC 序列号:117-570766844 二、配置软件 MX

    2023年04月18日
    浏览(50)
  • C#上位机与西门子PLC数据交互

    拉了换一个简单的界面 我新建了一个DB数据块【DB1】,右键【DB1】,点击【属性】项,【优化的块访问】默认是勾选,要想显示数据块中地址偏移量,需要把【优化的块访问】勾选取消 1、右键项目名,选择图中【管理NuGet程序包】 2、在搜索框输入【S7netplus】,我安装的是第

    2024年02月13日
    浏览(49)
  • C#上位机与欧姆龙PLC的通信12----【再爆肝】上位机应用开发(WPF版)

    继上节完成winform版的应用后,今天再爆肝wpf版的,看看看。 可以看到,wpf的确实还是漂亮很多,现在人都喜欢漂亮的,颜值高的,现在是看脸时代,作为软件来说,是交给用户使用的,UI自然是要讲究,可以看出,wpf比winform漂亮多了,因为wpf使用样式css来美化界面,虽然这

    2024年01月16日
    浏览(45)
  • C#上位机与欧姆龙PLC的通信11----【爆肝了】上位机应用开发(Winform版)

    前面10讲,让你爽煹了肝,已经进入最后收尾阶段,这节来个常规应用,让前面的技能直接飞上天,我们要做的界面软件是这样的,虽然没有潘金莲漂亮,但也是爆抱: 这里经过与PLC电气硬件工程师沟通,明确了这3个区的寄存器代表的含义,具体哪些寄存器存放的是什么数据

    2024年01月23日
    浏览(50)
  • C#学习笔记9:winform上位机与西门子PLC网口通信_上篇

    今日继续我的C#学习笔记,今日开始学习打开使用千兆网口来进行与西门子PLC的通信: 文章提供整体代码、解释、测试效果截图、整体测试工程下载: 主要包含的知识有: 下载NuGet程序包、 西门子PLC及通信协议、搭建虚拟的S7通信仿真环境、C#与西门子S7的六大通信库了解 其

    2024年04月14日
    浏览(47)
  • 实现上位机与FPGA uart交互

    前言  初学者学习记录 目的:实现上位机与FPGA uart交互 开发环境:quatus prime 18.1,芯片 altera :EP4CE15F23C8。 实验现象: 1.使用uart:bps=9600(参数可调整),8n1数据结构发送和接收数据。 2.上位机与FPGA 64位数据通讯,16bit head+16地址(最高位0:写;1:读)+32数据。 3.  驱动数

    2024年02月14日
    浏览(36)
  • 二、赛普拉斯EZ-USB FX3示例烧录验证

    一、简介                  本人使用的是CYUSB3KIT-003开发板,之后的示例也是基于上面验证的。 图1.0开发板实物图 二、驱动安装         步骤: ① 把开发板的跳线帽都接上。                     ② 把USB3.0线插入开发板,另一端连接电脑,此时会有一个电源灯亮

    2024年02月09日
    浏览(33)
  • 三菱PLC通过三菱FX1N-232BD模块与威纶通触摸屏设置

    1.PLC编程设置,通过GX Developer编程软件设置PLC参数如图1 所示 注意红色框设置选择的参数设置,绿色框参数设置配置要和威纶通EasyBuilder Pro的参数一直即可。 注意:PLC参数设置完成后,下载到PLC中,然后PLC需要断电,在启动设置的参数才能生效。 2.维纶触摸屏编程软件EasyBu

    2024年02月12日
    浏览(117)
  • CClink IE转Modbus TCP网关连接三菱FX5U PLC

    捷米JM-CCLKIE-TCP 是自主研发的一款 CCLINK IE FIELD BASIC 从站功能的通讯网关。该产品主要功能是将各种 MODBUS-TCP 设备接入到 CCLINK IE FIELD BASIC 网络中。 捷米JM-CCLKIE-TCP网关连接到 CCLINK IE FIELD BASIC 总线中做为从站使用,连接到 MODBUS-TCP 总线中做为主站或从站使用。   1.2.2 MODBUS-TCP

    2024年02月13日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包