- 博客(48)
- 资源 (4)
- 收藏
- 关注

原创 10年工程师的Modbus总结
我们来看下PLC是如何定义的,首先看一个PLC的变量地址,比如D100,这个D100是由D+100组合而成,D是存储区代号,100是地址偏移量,这样的地址模型就直接包含了存储区,这里的D100我们可以理解为绝对地址,而后面的地址偏移量100可以理解为相对地址。任何一个存储区都是有范围的,比如西门子的M区只有8192个字节,三菱的D区有8000个字,高端系列有18000个字,我们电脑硬盘也是,以前500G很大了,现在动辄1T、2T,都终究有个范围,因此Modbus的存储区也是有范围的,不可能无限大。
2025-01-09 13:51:18
1403
原创 上位机多PLC多协议开发思路分析
上位机开发第一步需要有通信库,通信库的本质就是一个类库项目,最终编译成一个dll文件,里面包含了各种协议类,我们可以通过创建通信对象,调用其读写方法,实现与PLC之间的交互。这样对于我们来说,每个PLC就是一个Device对象,我们只需要调用一行代码即可将配置文件解析成设备对象,多个PLC就是设备对象的集合。PLC技术发展多年,不同的制造商在早期都采用了不同的通信协议,随着时间的推移,这些协议已经成为了行业标准,很难在短时间内进行统一。每个Device类中,会有若干个组,单个组抽象成一个Group类。
2025-04-01 08:56:14
391
原创 学会这几招,没有连不上的PLC
S7通信协议是基于TCP/IP的,西门子PLC作为TCP服务器,端口号是102,上位机作为TCP客户端。一般情况下,如果可以Ping通,一定是可以连接上的,除非IP地址弄错了,因为西门子PLC的102端口是自动开放的。因此M区是西门子PLC都自带的存储区,DB存储区需要手动创建,当然读取I和Q也可以。那么接下来,我们打开网络调试助手去连接PLC,看看能不能连接上。此外,如果可以读到数据,但是值不对,那就是数据解析的问题了。首先,我们要排除网络的问题,保证可以Ping通。如果可以连接上,那么我们进入下一步。
2025-04-01 08:52:46
414
原创 使用C#创建安装Windows服务程序
5、点击添加安装程序之后,会自动添加一个ProjectInstaller界面,里面有两个组件,分别是serviceProcessInstaller和serviceInstaller。7、接着选择ProjectInstaller进行设置,主要设置Account,指示用来运行此服务的账户类型,可以设置为LocalSystem。在实际工作中,如果我们需要开发一个运行在后台,无需用户交互,不需要界面的应用程序,我们可以通过Windows服务来实现。接下来,我们使用这个exe来进行安装和卸载Windows服务。
2025-03-20 09:06:42
750
原创 Modbus协议的一些不足之处
如果在这两次交互时间差之间,其他位的值发生了改变,那么第二次交互时会将其他恢复回第一次读取到的值,因此如果必须使用寄存器位操作,要注意变量的重要性,以免造成一些严重的后果。Modbus协议主要应用在设备层的一些仪表及控制层的一些PLC控制器中,所以大部分情况下都是局域网的应用,因此基本上不会出现黑客攻击或者数据篡改之类的问题。那么意味着字节计数的最大值是255,返回报文中的字节计数是读取寄存器数量的2倍,因此读取寄存器的数量最大值是255/2=127。Modbus的功能码中,是没有针对寄存器位写入的。
2025-03-15 16:04:01
359
原创 三菱PLC的MC通信协议报文解析
其中0x0A 0x00 0x14 0x00 0x1E 0x00 0x28 0x00 0x32 0x00即表示D0-D4的值,进行数据解析处理后的值分别为10、20、30、40、50,与PLC数据一致。通信编码格式有ASCII和二进制两种方式,通过二进制编码数据进行的通信与通过ASCII编码数据进行的通信相比,前者的通信数据量约为后者的二分之一,因此二进制编码的方式通信效率更高。很多人在学习三菱PLC通信协议时,很头疼的是三菱PLC有很多种通信帧类型,每种通信帧又有ASCII和二进制两种编码格式。
2025-03-15 16:00:18
1553
原创 上位机与西门子PLC通信掌握这几点,效率翻倍
但是MaxPDUSize并不是一次性可以读取的字节数,是报文的长度,实际读取的字节数,需要在此基础上减去包头的18个字节,因此S7-200Smart/S7-1200/S7-300一次可以读取222个字节,S7-400一般是462个字节,S7-1500一般是942个字节。我们可以看到,这个是通信库底层做了分包处理,比如读取1000个字节,会分成222-222-222-222-112五次去读,然后将结果拼到一起返回,虽然可以读取,但是耗时仍然会是单次通信周期的五倍。
2025-03-14 09:31:30
930
原创 C#上位机基于SMTP实现邮件报警通知
SMTP是一种提供可靠且有效的电子邮件传输的协议,是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。发送者邮箱需要开启SMTP相关服务,这个一般在邮箱的设置中,可以找到。开启服务之后,会生成一个授权码,这个授权码很重要,后面代码中会使用到。今天跟大家分享一下C#上位机如何基于SMTP协议实现邮件报警通知。我们结合前面介绍过的沿信号检测来做个报警发送邮件到指定邮箱的案例。首先我们要准备2个邮箱,一个作为发送者邮箱,一个作为接收者邮箱。
2025-03-14 09:29:24
551
原创 C#上位机实现沿信号检测
首先我们需要创建一个类,这个类就像PLC编程中的指令一样,拖一个指令到PLC程序中,相当于实例化这个类的实例,其实C#代码的实现和PLC指令的实现原理是一样的,只不过在PLC中,是厂家封装好了,我们直接使用。我们可以参考上述代码编写一个下降沿检测的类,也可以将上升沿和下降沿检测放到同一个类中,通过构造方法传值来判断为上升沿或下降沿。三、在实际应用中,我们可能需要考虑信号抖动的情况,可以在原来的基础上,增加一个防抖动的功能,同时,为了考虑线程安全,加上锁处理。下降沿是指信号从高电平到低电平的变化瞬间。
2025-03-13 11:31:20
532
原创 WinForm实现窗体自适应缩放
二、在FormAutoSize类的构造方法中,初始化宽度、高度和窗体对象,同时将各个控件的宽度、高度、左边距、上边距以及字体大小,按照指定的格式(这里使用分号拼接)存储到AccessibleDescription属性里,因为AccessibleDescription属性很少使用,所以存储到这个属性里。三、接下来就是如何重置窗体控件布局,这里将当前的宽度高度与初始宽度高度进行相除,会得到比例系数scaleX/scaleY,然后将这个系数叠加进去,得到新的宽度高度等属性值,然后重新设置控件属性即可。
2025-03-13 11:27:57
942
原创 Modbus这样学,没有理由学不会的
第九阶段就是要去编写一个ModbusTCP协议的上位机,我们之前做过西门子S7协议版本的加压站,那么就可以很轻松改成ModbusTCP协议的,这里我们使用西门子和三菱PLC,其他PLC,只要支持ModbusTCP协议,也是类似的。第七阶段就是要写ModbusTCP通信库了,ModbusTCP通信库其实是以太网通信与ModbusTCP报文的融合,学会ModbusTCP通信库,其他以太网通信协议都可以触类旁通了。9、ModbusTCP-10功能码读取输出线圈。4、ModbusTCP-03功能码读取输出线圈。
2025-03-12 13:28:57
1103
原创 基于NSIS轻松实现上位机项目打包
首先要准备好要打包的程序,一般我们开发的WinForm或WPF项目,可以直接把Debug或Release文件夹复制过来即可,一定要确保双击文件夹里的exe应用程序,可以正常打开程序,对于.Net环境建议单独安装。2、支持大多数 Windows 平台,包括:Windows 10,Windows 8,Widows 7,Windows NT,Windows 2000,Windows XP,Windows 2003。4、在NSIS脚本向导中,按照提示填写应用程序的相关信息,这些信息不是必填项,然后点击下一步。
2025-03-12 13:26:50
469
原创 电脑直接EtherCAT就可以直接控制伺服
8、点击打开之后,回到从磁盘安装界面,点击确定,然后一直下一页即可,最终我们可以在设备管理器中,看到ZMotion_Device,下面有个ZMotionRT Controller,即说明控制器驱动安装完成。7、点击【浏览】,在前面下载的MotionRT7文件夹,找到rt1028_signed文件夹,再选择driver_signed文件夹,选择ZMotionRt64.inf,点击打开。1、点击我的电脑,右击选择【管理】,选择【设备管理器】,在右侧的设备列表中,任意选中一个。
2025-03-11 17:15:58
681
原创 C#调用SQLite数据库经常遇到的一种错误
2、对于SQLite来说,System.Data.SQLite.dll是通用的,不通用的是SQLite.Interop.dll,因此,我们会把32位和64位的SQLite.Interop.dll放在两个不同的文件夹x64和x86里,这两个文件夹里放的都是SQLite.Interop.dll,但是两者是不同的,我们通过文件大小也能看出来。大家在学习过程中,遇到问题首先要看错误提示,虽然有的错误提示会比较鸡肋,但是大部分情况下,都要根据错误提示来分析。
2025-03-11 17:14:12
287
原创 C#上位机与PLC通信心跳的实现方法
3、心跳程序编写:心跳地址数据变化只需要定时写入值即可,心跳检测程序,可以采用接通延时定时器来检测值的变化,如果在规定的时间内未收到心跳信号,系统应该及时发出警告或采取措施。如果我们想让PLC知道连接状态,那么上位机就必须定时给心跳地址写不同的值,这样PLC就可以通过检测这个地址值是否发生变化,来判断连接是否正常。如果我们想让上位机知道连接状态,那么PLC需要定时给心跳地址一个变化的值,上位机通过检测心跳地址的值是否发生变化,来判断PLC是否在线。心跳地址为布尔:定时给心跳地址取反写入,然后检测变化。
2025-03-10 15:09:11
398
原创 一行代码解决离线安装VS2022
2、创建一个文件夹路径,文件夹所在盘符至少要保留10G的空间,这里使用的是D盘,文件夹名称为VS2022Professional_offline,这个名称自己定义即可。第三行到第五行是安装组件,此处针对的是.NET Web 和 .NET 桌面开发,如果需要安装其他组件,需要做相应添加。1、首先将下载VS2022的在线安装包,放到桌面上,本文以VS2022专业版为例,其他版本操作步骤是基本一样的。
2025-03-10 15:08:27
412
原创 C#上位机与台达ES3系列PLC通信
DVP-ES3 系列采用全新ISPSoft软件进行编程,操作直观简单,除了支持IEC61131-3编程语言外,还支持在线编辑、在线校验、台达FB功能块,程序加密等功能,方便客户程序开发。1、软件安装过程就不做过多说明了,安装完成后,首先打开COMMGR,进行通信驱动程序设置,PLC出厂IP是192.168.1.5,这里端口号设置为502。近几年来,国产PLC的市场占有率在逐步提升,包括台达、信捷、汇川等各大品牌,都有了很大的发展。2、第二步:读取Y存储区数据。1、第一步:连接PLC。
2025-03-08 15:43:28
467
原创 深度剖析VS里的代码片段【快捷键】
5、Snippet部分是重点内容,从结构上来看,主要包括Declarations和Code两个部分,Declarations,顾名思义就是声明变量,而Code就是核心代码,Code中会应用到Declarations中声明的一些变量。当我们已经知道Snippet的原理之后,我们会发现了,自带的关于异常捕获的有try和tryf两个,但是这两个都无法表示try-catch-finally的逻辑,所以,我们可以尝试做一个try-catch-finally的Code Snippet。
2025-03-08 15:41:39
796
原创 手撸一个ico文件制作工具
我现在一般的做法,都是先去阿里巴巴矢量库里下载png图片,然后通过自己用C#写的这个ico转换工具,转换成ico格式的,使用起来非常方便。我记得之前分享过几个ico文件的网站,好像都倒闭了。前几天有个学员问,有没有ico格式的图标下载地址?
2025-03-06 15:32:51
139
原创 PLCSIM-Advanced实现西门子PLC开放式TCP通信
第二种方式使用PLCSIM-Advanced,不仅可以仿真S7通信协议,还可以仿真开放式TCP/UDP、ModbusTCP、OPCUA等以太网协议,但是仅支持S7-1500和ET200SP,无法仿真其他型号PLC。第一种方式使用NetToPLCsim,不仅可以仿真S7-1500,还可以仿真S7-1200/S7-300/S7-400,但是只能仿真S7通信协议,无法仿真其他通信协议。
2025-03-06 15:31:32
846
原创 西门子博图V17及仿真器安装及注意事项
大部分初学者在学习C#上位机编程时,当需要实现与西门子PLC通信时,如果手上没有PLC实物,就可以通过仿真的方式来搭建PLC环境。在前面解压的目录下找到Start.exe重新安装,选择修复,如果提示再次重启,继续重新删注册表,然后再用管理员身份启动安装即可。1、西门子软件授权的方式是通用的,这里针对博图TIA V17和PLCSIM-Advanced做授权处理。2、安装前最好关闭其他所有软件,可以重启一下电脑,纯净系统尤佳,这里也可以选择使用虚拟机。
2025-03-04 14:16:34
2299
原创 基于Nettoplcsim搭建西门子PLC仿真环境
第二种方式使用PLCSIM-Advanced,不仅可以仿真S7通信协议,还可以仿真开放式TCP/UDP、ModbusTCP、OPCUA等以太网协议,但是仅支持S7-1500和ET200SP,无法仿真其他型号PLC。第一种方式使用NetToPLCsim,不仅可以仿真S7-1500,还可以仿真S7-1200/S7-300/S7-400,但是只能仿真S7通信协议,无法仿真其他通信协议。这篇文章主要针对PLCSIM+NetToPLCsim这种方式来实现西门子PLC的仿真环境搭建。
2025-03-04 14:15:06
364
原创 学习上位机通信,必须要弄清楚通信三要素
我们以ModbusRTU通信为例,一般叫做主站和从站,就是我们常说的Master和Slave,Master对应主站,Slave对应从站,一般情况下,上位机充当主站的角色,PLC充当从站的角色,因为是上位机想要PLC的数据,当然这也不是绝对的,PLC作主站,上位机做从站,也是可以实现通信的。当我们解决了通信介质的问题,那么我们就可以进行连接了,接下来会存在一个问题,就是如何进行沟通,就像人和人通话一样,电话拨通之后,我们该用什么语言,该说什么话,那么这个语言和说话的内容,就叫做通信协议。
2025-03-03 09:23:42
719
原创 基于C#实现文本读取的7种方式
文本读取在上位机开发中经常会使用到,实现的方式也有很多种,今天跟大家分享一下C#实现读取读取的7种方式。以上7种方式主要是分别基于FileStream、File和StreamReader这三种来实现的,这三种方式的区别在于:FileStream类可以对任意类型的文件进行读取操作,而且我们也可以按照需要指定每一次读取字节长度,以此减少内存的消耗,提高读取效率。StreamReader的特点是,它只能对文本文件进行读写操作,可以一行一行的写入和读取。
2025-01-20 10:20:19
260
原创 浅谈单例模式
什么是单例模式?单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)上面是百度百科给出的解释。大家都知道,面向对象的思想就是我们可以把一个类实例很多次,每次实例出来的都是一个对象,意味着你可以创建很多个基于这个类的对象。单例模式,说白了,就是这些对象本质都是同一个,整个程序中,不管在哪里用,使用的都是同一个实例对象。如果我们创建了一个China类,我们可以一直new吗?
2025-01-20 10:18:22
996
原创 C#如何获取电脑中的端口号和硬件信息
如果我们不需要获取带硬件信息的端口号集合,那么usefullname传入False,默认参数是False,不填的话,就是False。我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。思路就是通过读取设备管理器里的条目来实现,我这里给大家封装好了一个通用的方法。如果我们需要获取带硬件信息,那么usefullname传入True即可。那么如果我们使用C#编写软件时候,如何获取到串口的硬件信息呢?
2025-01-19 15:58:03
572
原创 C#上位机程序开机自动启动
代码已经写好,直接复制过去,在主程序里调用一下即可。实现很简单,通过C#操作注册表来实现。如何实现上位机程序开机自动启动呢?
2025-01-19 15:52:37
113
原创 基于C#实现多线程启动停止暂停继续
但是如果希望这个对象与多线程有所联系,必须要在多线程的方法里体现这个对象的作用,这个是调用这个对象的WaitOne方法,表示在调用的地方阻塞住,通过判断True或者False来决定是否继续执行,就像大家开车过高速收费站一样,即使现在普遍采用ETC了,在入口也需要减速,有一个ETC识别的过程,识别成功才会抬杆,识别不对,杆子是不会自动抬起的,这个是一样的道理。因此,多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。
2025-01-18 16:50:03
1244
原创 基于C#实现对象序列化的3种方案
在上位机开发过程中,我们可能经常要实现一个数据对象的持久化,将对象保存到具体的文件中,今天给大家介绍常用的3种方案,大家根据实际情况,选择适合的方案。我们通过序列化可以将对象转换成一个字符串进行存储,同时通过反序列化可以将该字符串转成一个对象,对象序列化与反序列化是一个相互转换的过程。
2025-01-18 16:48:36
549
原创 SQL Server 2022中文软件下载安装过程
8、双击上面的SSMS-Setup-CHS.exe文件,出现下面的界面,建议都选默认路径,不要修改(因为即使修改了,安装时绝大部分文件还是在默认的路径里面,没有多大意义,如果磁盘空间不够请想办法解决)。如果正常安装成功后,界面如下,点击【关闭】即可。提示:我们这里用的是Express版本,这个版本是专门的免费学习版,其他版本均为商业付费版本。12、如果Windows身份可以登录上,基本上就说明安装没有问题,可以进行后面的学习。2、点击【继续】按钮,等待下载,完成后自动打开各种安装选项窗口。
2025-01-17 11:33:48
1655
原创 Visual Studio 2022中文软件下载安装过程
如果想再次“创建账户”,可通过【帮助】菜单,选择“注册Visual Studio”即可注册和登录账户,如下所示,过程不再赘述。5、然后点击【单个组件】,建议把下面的都选上,保证.NET Framework 4.6一定要勾选上,最后点击【安装】。11、不管是登录成功,还是暂时跳过此项,都会返回到开发设置界面,开发设置选择“常规”,颜色主题可以选择自己喜好的即可。7、安装成功后,会弹出“安装完毕”对话框,点击【确定】,再选择【启动】按钮。选择社区版,点击免费下载,下载后的文件如下,文件比较小,只有几兆。
2025-01-17 11:32:50
3529
原创 WinForm实现无边框拖动的两种方式
Winform作为桌面应用程序的一个代表,可以说是C#初学者快速入门最好的一种方式,然而随着我们的开发能力的提升,我们对UI界面的要求变得越来越高,于是我们开始不断优化、升级我们的UI界面。Winform无边框设计是我们开发漂亮的UI界面非常常用的一种方式,无边框设计意味着没有了应用程序的标题栏,也就无法直接拖动,今天主要给大家介绍两种实现窗体无边框拖动的方式。
2025-01-16 15:26:59
468
原创 C# WinForm自定义仪表盘控件开发教程
2、绘制过程:绘制过程就是根据实现思路来实现,通过代码依次实现绘制基础圆、绘制扇形、绘制内圆、绘制文字,具体代码如下所示。1、我们使用VS2022创建一个项目,项目模板选择Windows窗体控件库(.NET Framework)。2、项目名称修改为xbd.MeterPlate,框架选择.NET Framework 4.6,点击创建即可。3、项目创建完成后会自动创建一个自定义控件,将自定义控件名称改成MeterPlater。Windows 窗体支持三种类型的用户定义的控件:复合控件、扩展控件和自定义控件。
2025-01-16 11:40:09
1069
原创 C#轻松实现ModbusTCP服务器接口
大家好!我是付工。通透!终于把ModbusRTU弄明白了这样看来,ModbusTCP协议太简单了太简单了!C#轻松实现Modbus通信前面给大家介绍了一系列关于Modbus和ModbusTCP的知识,主要针对的是ModbusTCP客户端。在实际开发过程中,有可能会需要开放数据接口给PLC或第三方厂家。今天给大家分享一下,如何基于C#来ModbusTCP服务器接口。一、NModbus4ModbusTCP服务器的本质就是TCP服务器,根据识别ModbusTCP请求报文,返回对应的
2025-01-15 15:47:33
1003
原创 揭秘10种主流PLC在ModbusTCP通信中的速度表现!
三菱FX5U PLC,我们采用的是FX5U-32MT/ES,三菱FX5U PLC是直接支持ModbusTCP的,但是需要做下配置,在以太网配置里加上ModbusTCP连接设备,端口号设置为502。ModbusTCP默认端口号是502,所以不同设备仅仅只是IP地址不同而已,为了保证数据的准确性,我们使用循环读取的方式,循环三组,每组连续读取10000次,观察总耗时。信捷PLC,我们采用的是信捷XD5E,国产PLC对Modbus协议支持比较好,不需要额外写PLC程序。
2025-01-15 10:43:57
1962
原创 C#轻松实现条形码二维码生成及识别
一、前言大家好!我是付工。今天给大家分享一下,如何基于C#来生成并识别条形码或者二维码。二、ZXing.Net实现二维码生成的库有很多,我们这里采用的是http://ZXing.Net。ZXing是一个开放源码的,用Java实现的多种格式的一维二维条码图像处理库,而http://ZXing.Net是ZXing在.Net平台下的实现。我们通过Nuget搜索http://zxing.net即可搜索安装。三、BarCodeHelper安装好http://ZXing.Net后
2025-01-14 13:37:04
887
2
原创 我对上位机通信的理解
编程对于我们很多做PLC开发的人来说,是一个从0到1的过程,很多人没有学习下去的原因就是因为第一关编程就没过,但是编程又是一个工具,没有这个工具,纵使你有再多的想法,也无济于事。我们学习上位机的目的就是为了能够独立开发项目,但是项目的范畴很广,项目的难点在于变化,不同项目的需求程度是不一样的,客户的要求也越来越高,既要界面好看,又要使用稳定。我从2017年开始研发这个通信框架,已经使用这个通信框架开发了上百个项目,最终我们的代码会很简单,这样我们就可以专心编写项目业务逻辑了。更重要的是,框架会越来越成熟。
2025-01-14 13:34:52
331
原创 开源免费的上位机数据转换库
这其中就涉及到了各种数据类型之间的相关转换,很多非科班出身的电气工程师,经常会因为弄不清楚各种数据类型之间的转换关系,导致无法获取到自己想要的数据。这上面罗列了通信库的所有的类和每个类对应的方法,每个类和方法都有对应的注释,然后通过表格输入正确的数据,点击执行结果,即可得到对应的结果。整个数据转换库总共包含15个类,包含了各种常用各种数据类型之间的互相转换,每个转换类中的方法都增加了注释,使用起来会很方便。大家下载的源码中,运行的界面是基于这个转换库开发的一个测试工具,主要是使用反射和特性来实现的。
2025-01-13 16:42:55
989
原创 上位机能不能替代PLC呢?
大家好!我是付工。之前有个学员问了这样的一个问题:学会了上位机,是不是就可以不用PLC了呢?今天跟大家分享一下上位机能不能代替PLC?二、网络架构首先我们看下这张网络架构图。从图中可以看到:上位机属于过程监控层,PLC属于现场控制层。PLC作为下位机,上位机与下位机进行通信,实现整个控制系统的运作。因此正常情况下,上位机不是用来替代PLC的。但是,有些情况下,尤其是在一些运动控制机器视觉的项目场景中,整个项目中并没有使用PLC,那么这个时候,我们能不能通过上位机来实现一些逻辑控制呢三、实现原理。
2025-01-13 16:41:12
778
原创 终于有人把委托说清楚了
Action委托针对无返回值情况,具有Action、Action<T>、Action<T1,T2>、Action<T1,T2,T3>……Action<T1,。,Tresult>17种类型重载,T1。.Net Framework3.5之后开始有了Action和Func,Action和Func是内置委托,也叫系统委托,就是微软的工程师帮我们在底层写好了委托声明,这样我们就不需要声明委托。于是,聪明的他开始搬救兵,找到了你的领导,表示他有一个类似的项目,利润很高,客户很急,需要借用你的程序参考一下。
2025-01-12 13:04:09
847
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人