赞
踩
单位是【bit】
【SOF】占1bit(起始位),1bit长度的逻辑0,表示帧开始
【identifier】占11bit(帧id),帧id就是从站地址【其中4bit功能码,7bit从站地址】
【RTR】占1bit(远程帧)0为数据帧,1为远程帧【用于让从站发一个数据帧回应】
【IDE】占1bit(帧id长度选择)0标准帧【11bit】,1扩展帧【29bit】
【R0】占1bit()保留【隐性1】
【DLC】占4bit(有效字节数0~8)表示数据包内有效字节数,
【0-8字节数据】固定占64bit(数据包64bit)就算不用,也得发64个0
- 表示【数据包】,固定64bit长度(且数据包内有效字节由DLC值决定)
-
- DLC的值:0~8:决定64bit数据包内多少字节是有效的。byte0》byte1》2》3......byte7
-
- 数据区域【0-8字节数据】:实际就是数据包,固定64bit长度。【就算不用,也得发64个0】
- 比如: DLC=0 数据包= 00 00 00 00 00 00 00 00
【EOF】占7bit(帧结束)连续7bit长度逻辑1,表示帧结束。
标准帧的bit数是固定的 1+11+3+4+64+16+3+7=109bit 【9174帧/秒】
【1Mbps】1000 000 ÷ 109 ≈ 9174.311帧/秒
- 在二次开发中,只用到3个变量:
-
- 帧id:一般用标准帧 【11bit】
- DLC:数据包内有效字节
- 数据包:【固定64bit,低字节先发 D0。。D7】
- //===============================
- 编程一般用148字节格式存取【数据帧】对象
- 1表是DLC(byte)
- 4表示帧id(11或29bit)
- 8表示数据包(固定64bit)
-
- 台达can伺服从站【0x01~0x7F】1~127,所以使用标准帧id,11bit【其中4bit是功能码,7bit是从站地址】
- 台达A2当modbus站号为0xFF时,从站具有自动回复功能。
单个bit的逻辑定义:
隐性【逻辑1】HL都为+2.5V
显性【逻辑0】H3.5V,L1.5V
伺服CAN电压和数据帧_canopen读电压_cfqq1989的博客-CSDN博客
- CAN用差分信号。
- HL线对于0v而言,电压有3态【H大于L】【H小于L】【H等于L】
- 没数据的时候:逻辑true 【H等于L】电压相等,都是2.5v
- 有数据的时候:逻辑false【H大于L】HL电压差大于1.5v
- 逻辑分析仪下,HL线,电平始终是反的,【跟跷跷板一样】H线高电压,那L线就是低电压。
- 帧id=全0时,权限最高。
- 帧id有11bit(标准帧), 29bit(扩展帧)
- CAN伺服用的都是标准帧【11bit】
-
- 如果4芯差分
- TX+,TX-,RX+,RX-
- 把TX-和RX-短接
- TX+和RX+就是差分电压,对应A,B信号
- 差分信号AB电压始终对着干,A是白天,那B就是夜里
11bit(帧id)定义:有时需要拆成 4+7(4bit为功能码,7bit为从站地址)
伺服使用标准帧【帧id总长11bit】
NMT,SYNC和TIME 帧id是固定的。
NMT:总线命令 发00h (帧id=0x00)
SYNC:同步命令 发80h (帧id=0x80)
EMCY:从站故障帧 回80h+从站地址
TIME:时间命令 发100h(帧id=0x100)
PDO1:批量读写寄存器 发200h+回180h+(属于指针命令,批量写寄存器)
PDO2:批量读写寄存器 发300h+回280h+
PDO3:批量读写寄存器 发400h+回380h+
PDO4:批量读写寄存器 发500h+回480h+
SDO:读写单个寄存器设置 发600h+回580h+(读写单个寄存器)
从站心跳帧【从站状态】:回700h+从站id 【0x1017心跳ms】
-
- SDO属于读写单个寄存器
- PDO批量读写离散寄存器
- PDO属于指针,指向寄存器(批量读写寄存器)因为数据包是64bit,所以单帧可以同时写好几个寄存器值
- 通讯最小单位是一帧,如果64bit只读写一个寄存器,就显得很浪费,所以PDO能最大利用64bit
- 0x1016 【主站】喂狗从站心跳帧监视,时间≥1017h 心跳生产时间×2
- 0x1017 【从站】从站生产心跳时间_ms【循环生产心跳】
-
- 关闭从站心跳:
-
- Set_Send(0x08, 0x600 + Address, 0x00000000010172b);
-
- 603 //从站id = 3
- 08 //DLC = 8
- 2b 17 10 00 00 00 00 00
-
- 远程帧:
- 主站发【Set_Send(0x08, 0x700 + Address, 0x0000000000000000);】
- 从站回帧【0x01, 0x700 + Address, 0x000000000000007F);】 ' 7F表示待机模式'
寄存器【0x1017心跳ms】
先看从站回帧 700h+从站地址 , 8字节数据包(BYTE8)
【DLC】【帧id】【64bit数据包】
01,701,0000000 0000007F(表示:帧id=0x701,从站1状态7F:待机状态)
01,701,0000000 00000005(表示:从站1状态05:工作状态)
01,77F,0000000 0000007F(表示:从站127状态7F:待机状态)
01,77F,0000000 00000005(表示:从站127状态05:工作状态)
【01】【0700+从站id】【00000000 000000AA】
-
- 【回帧状态码】//回帧由从站发出,报告从站当前状态
- //===========================
- DLC=0x01 //有效字节1个【64bit数据包内只使用1个字节】
- 帧id =【700h+从站id】
- Byte8: 8字节数据包。
- //===========================
- byte0:定义如下(从站状态值bit6~bit0)
- 0x00 正在初始化//(伺服还在上电中...)
- 0x01 未连接
- 0x02 连接
- 0x03 预备
- 0x04 停止状态(只受NMT控制)
- 0x05 工作状态(PDO有效)可批量读写寄存器(运动控制)【电机运行中】
- 0x7F 待机状态(PDO失效)只能用SDO配置寄存器【电机配置参数中】
- 注:由0x1017寄存器控制回帧周期ms,默认2000ms
- //=======================================
- RTR: 1远程帧,0数据帧
- 远程帧:呼叫远方从站【你还活着吗?】从站会应答一个【700h+帧id】的数据帧
- 远程帧:【00】【700h+帧id】【0000000000000000】
- 回帧: 【01】【700h+帧id】【00000000000000AA】
- //======================================
- 从站心跳: 0x1017 _ms //从站心跳间隔,
- 监视主机: 0x1016 _ms //监视主机心跳,第1帧开始激活。【大于1.8倍生产者时间】

NMT总线命令 00h+B0+B1
【02】【0000】【000000000000BBAA】
-
- 00h B0 B1
- 总线NMT: 命令字:AA 从站地址:BB
- 帧id=0x00 0x01【工作】从站(回05h) 01~0x7F从站地址(1~127)
- 0x02【停止】从站(回04h) 00广播(所有从站)
- 0x80【预操作】(回7fh)//SDO专用
- 0x81从站复位(回7fh)
- 0x82通讯复位(回7fh)
- //=======================
- NMT是总线命令:(可以把从站踢下去)
- DLC长度固定2字节 (DLC=0x02)
- 11bit的值,固定为 0x00 (帧id=0x00)
- //=======================
- Byte0:功能码 (64bit数据包)
- Byte1:从站地址
-
- 就是说11bit的值,固定为0x00,并且只有主站才使用这个数据帧。(帧id=0x00)
- 全0的帧id是权限最高的。
- DLC=0x02:8字节数据包内,只使用2字节
-
- byte0:01h 从站启动(回帧05h运行模式)PDO有效
- 02h 从站停止(回帧04h停止模式)只有NMT有效
- 80h 从站预运行(回帧7Fh预运行模式)PDO失效【伺服配置参数时,用这个模式】
- 81h 从站重启(一般从站伺服报警后才用,或重启才能生效的参数)(回帧7Fh预运行模式)
- 82h 从站通讯重连(回帧 7Fh预运行模式)
- byte1:00h 所有从站
- 01~7f 从站地址(1~127)
- //==============================================
- plc开机发送: 02-0000-0000000000000081
- // DLC=0x02,帧id=0x00,Byte8(从站重启命令81,所有从站00)
- //====节点保护======【节点/寿命】============================
- 主站定时发送一个站号的心跳包: 02-077F-0000000000000005;//从站127,从站工作状态05
- 节点保护:上位机查询从站。
- 寿命保护:从站监听主站帧或其他从站帧。
- 0x100C保护时间 主站每隔100C时间询问从站【700h+从站id】,从站必须应答RTR=1
- 0x100D寿命因子
-
-
- ————————————————
- 版权声明:本文为CSDN博主「cfqq1989」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- 原文链接:https://blog.csdn.net/cfqq1989/article/details/128308808

【00】【0080】【0000000000000000】
-
- 0x1005 关80h,开40000080h【次高位】//从站做SYNC的生产者,【注:全网只能有一个sync生产者】
- 0x1006 同步周期_us
- 0x1007 忽略n个同步帧后,开始同步【同步齿轮】
- 0x100C 节点守护时间u16
- 0x100D 寿命因子u8【参考1.8倍】
- 00-0080-0000000000000000;
- //DLC有效字节0,帧id=0x0080,Byte8数据包=全0【64个0】;
- 上位机周期性发送SYNC (单位:微秒 us) 周期>2ms
- //=======================
- DLC=0x00
- 帧id=0x80:帧id值固定为0x80,8字节数据包值无效(全0)
- Byte8=全0;
- //=======================
- pdo设置好所有从站后,0x80触发从站PDO参数生效(或动作)【1400-02=0~240时】
- 0x6040寄存器值需要上升沿触发时:【先赋值低电平,SYNC(1),再高电平,SYNC(1)。】
-
- 同步对象 COB-ID 的次高位决定是否激活同步发生器。【200h+从站id】

【06】【0100】【0000FFEEDDCCBBAA】
-
- 06-0100-0000XXxx XXxxXXxx
-
- //=======================
- DLC=0x06; // 长度使用6字节
- 帧id=0x100:帧id值固定为0x100;
- Byte8=0x 0000112233445566; // 6字节有效【 8字节数据值(64bit时间值)】
- //=======================
- 广播时间(跟PLC时间64bit一样,由时间设备广播) 1970-01-01 + u64值
- CAN大部分驱动器不支持,由主站或时间设备按周期循环广播。
- //================================== C#
- DateTime dateTime = DateTime.Now;
- Int64 now = dateTime.ToBinary();
- TIME(now);// DLC=6字节
【08】【0080+从站id】【CCCC CCCC CCBB AAAA】
【08】【0082】【0000000004118120】//雷赛,从站2故障,错误被动模式
【08】【00FF】【0000000011807305】//台达,从站127故障 【11】【80】【7305】
0x603F=0x7305;//应急故障码 【LSB是低字节】
0x1001=0x80; // 错误寄存器
=0x11; // 台达伺服LED故障码:AL.011 位置檢出器異常
-
- 0x1014最高位【1关】【0开】//EMCY功能开关
- 由从站设备发出:
- 从站故障后,会上传 80h+从站地址的帧
- //==================
- DLC=08;
- 帧id= 0x80+从站号;
- Byte8= // 0x0000000004118120
- //===================
- B1 B0 应急错误代码= 0x8120 //寄存器 0x603F
- B2 故障码=0x11 //寄存器 0x1001
- B4 B3 厂家故障码=0x04 //寄存器 【禾川是0x213F】
-
- 最近错误记录 0x1003数组
- 0x1001故障码:
- bit0 一般性错误
- bit1 电流//
- bit2 电压
- bit3 温度
- bit4 通讯//
- bit5 协议402
- bit6 保留
- bit7 厂家
- //=====================================
- 台达A2
- 【08】【00FF】【0000000011 80 7305】
- //=========================
- DLC=0x08
- 帧id=0xFF【0x80+127】//从站127故障
- B1 B0=0x7305//寄存器 0x603F
- B2=0x80 //寄存器 0x1001
- B7 B3=0x11 //LED显示AL.011【位置检出故障,编码器线断】

CAN 网络主站通过远程帧,可以检查每个节点的当前状态。
用于呼叫从站,然后从站返回一个数据帧。
- 上位机发 SDO 读从站 0x1000 寄存器
-
- 从站回帧 580h+
【08】【PDO码+从站id】【AAAAAAAAAAAAAAAA】
-
- TXPDO1(发送) 0011+7bit(从站id) 0x180+从站地址 (方向是:伺服发送到上位机)
- RXPDO1(接收) 0100+7bit(从站id) 0x200+地址
-
- TXPDO2(发送) 0101 0x280+地址
- RXPDO2(接收) 0110 0x300+地址 (方向是:上位机发送到伺服)
- TXPDO3(发送) 0111 0x380+地址
- RXPDO3(接收) 1000 0x400+地址
- TXPDO4(发送) 1001 0x480+地址
- RXPDO4(接收) 1010 0x500+地址
- ————————————————
- (帧id)11bit拆开使用(4bit+7bit)其中4bit表示功能码,7bit表示从站地址
- 版权声明:本文为CSDN博主「cfqq1989」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- 原文链接:https://blog.csdn.net/cfqq1989/article/details/128009555
-
- PDO是批量读写寄存器,有4路
- PDO是需要先映射寄存器地址后,才能使用,对映射的寄存器批量读写。(PDO相当于快捷键)
- 去洗脚城点8号技师,(8号技师,可以是老板娘,也可以是小姨子,看寄存器指针怎么绑定)
-
- // 写信(上位机到下位机)
- 参数开关 地址绑定
- rPDO1(200h+)(主→从伺服) 1400h 1600h
- rPDO2(300h+) 1401h 1601h
- rPDO3(400h+) 1402h 1602h
- rPDO4(500h+) 1403h 1603h
-
- 注:1400-00【子索引个数】子索引总数5(只读5)
- 流程:
- 1400-01【PDO配置】先关(1<<31),等1600配置好后,1400-01再开启(b31=0开;b30=1RTR强置关,b29=0标准帧11位,b10~0:标准帧id受控码样式200h+从站)
- (注站2: 1400-01= 0x 40000202)//b31=0表示使能rPDO1功能,b30是RTR位
- // b29位=1是扩展帧,b10~0位rPDO1功能码0x202 从站2(200h+2)
- //============================
- 1400_【00】:[子索引个数]有5个子索引(只读5)
- 【01】:[PDO配置]bit31(0开,1关rPDO1)
- b30=1(RTR强置关,不应答远程帧)
- bit28~0= //有些伺服支持扩展帧,扩展帧29bit位
- bit10~0=200h+从站id(帧id受控码样式200h+从站号)//对应11位标准帧id
- 例bit10~0=0x0203;表示站3伺服受控0x203功能码。
- 【02】:[0~240](0~F0)在1个SYNC信号后,rPDO值才生效。
- [254或255]rPDO值立即生效(不需要sync同步信号)。
- //【241~251】保留【252~253】不受rPDO命令控制
-
- 【03】:[抑制时间,单位100us]连续2个PDO间隔最小时间(过滤干扰信号)12轴8.67ms
- 【04】:(保留)【不使用】
- 【05】:[事件定时器,单位1ms]0关,其他值:【定时时间】时间到,就生效rPDO设置的值。
-
- 1600_【00】有8个子索引:00:指针有效个数(把64bit分割给0~8个寄存器)
- 【01】绑定指针1(一般绑 0x6040控制字)0x60400010
- bit31~16寄存器编号(比如 6040h)
- bit15~8 子索引 00h
- bit7~0 寄存器类型bit(8h,10h,20h)8位,16位,32位
-
- 【02】绑定指针2(0x607A目标位置)
- 【03】绑定指针3(0x6060工作模式1位置3速度4扭矩6回零7补间位置)
- 【04】绑定指针4
- 【05】绑定指针5
- 【06】绑定指针6
- 【07】绑定指针7
- 【08】绑定指针8
-
- // 回信(下位机到上位机)
- 参数开关 地址绑定
- tPDO1(180h+)(主←从) 1800h 1A00h
- tPDO2(280h+) 1801h 1A01h
- tPDO3(380h+) 1802h 1A02h
- tPDO4(480h+) 1803h 1A03h
- 注:
- 1800_【00】:[子索引个数]有5个子索引(只读5)
- 【01】:bit31(0开,1关tPDO)先关,绑好后再开
- bit30(0rtr开,1关,远程帧)
- bit28~0(扩展帧29位,回帧样式 180h+从站id)
- bit10~0(标准帧11bit,回帧样式 180h+从站id)回帧id样式
- //比如收到SYNC信号,伺服回帧 183h 【tPDO1站3】
- 【02】:[0]值改变,且接收到一个同步帧,则发送该 tPDO;
- [1~240]个SYNC同步帧后上传回帧(tPDO帧)
- [254,255]值改变或定时器到就上传回帧(tPDO帧)
-
- 【03】:帧间隔 0.1ms倍数(400是40ms)用于两个tPOD上传间隔时间
- 【04】:保留
- 【05】:[定时触发器,单位1ms] (0:关)触发tPDO回帧【只在02=254,255时有效】
- 【x1ms】u16,时间到就上传tPDO帧。如:5000是每5秒上传tPDO帧
-
- 1A00_【00】:1A00有8个子索引:00:指针有效个数(64bit中寄存器占用个数1~8)
- 【01】:绑定指针1(一般绑 0x6041状态字)0x60410010;
- bit31~16寄存器编号 6041h
- bit15~8 子索引 00h
- bit7~0 有效bit(8h,10h,20h)8位,16位,32位
-
- 【02】:绑定指针2(0x6064PUU电机编码器回授位置)
- 【03】:绑定指针3(0x6063回授命令位置)
- 【04】:绑定指针4
- 【05】:绑定指针5
- 【06】:绑定指针6
- 【07】:绑定指针7
- 【08】:绑定指针8
-
- 异步通讯响应最快。(值改变就生效,立即回tPDO帧)
-
- 例子:寄存器0x1600子索引01赋值0x60400010;
- 状态流:
- 先设置 1400h-01=1<<31;// 关闭rPDO1
- 1600h-00h = 0;//关闭绑定
- 1600h-01h = 0x6040 00 10;//0x60400010;绑定寄存器0x6040子00长度bit16
- RPDO1指针,指向寄存器0x6040,00子索引,10(16bit)
- 再设置 1400h-01=0<<31;// 使能rPDO1
-
- 08h(8bit)
- 10h(16bit)// 例子中 10 指 寄存器0x6040是16bit的
- 20h(32bit)// 0x20
-
- 例子2: 寄存器0x1A00子索引01赋值0x60410010;
-
- 0x1A00-01是伺服上传(TPDO1)
- 0x6041是把TPOD1和寄存器0x6041绑定
- 00是寄存器0x6041的子索引
- 10是寄存器的类型 16bit
- 作用:伺服上传 寄存器0x6041-00的数据
-
- //========================
- 寄存器0x1400-01
- bit31: PDO1总开关(0开,1关)//进行设置的时候先关,再开。 1600也是如此(1600-00先设置0)
- bit28:地址bit长度(0:11bit 1:29bit)
-
- 寄存器0x1400-02 //表示在下一个SYNC同步信号80h发生之后CANopen驱动器生效接收到的数据
- 0~0xF0 延时us //雷赛用0x01us,0h立即,0xFE由SDO动作,0xFF事件立即响应
-
- //========================================
- #region PDO1 // 6040和607A目标位置
- //写信
- PDO_Struct pdor = new PDO_Struct();
- pdor.rPDO命令触发器 = 240;//【0~240】在1个SYNC后,rPDO值才生效。【254或255】rPDO值立即生效(不需要SYNC信号)
- //【241~251】参数无效【252~253】rPDO命令失效(不受rPDO命令控制)
- pdor.rPDO禁止时间_100us = 10;// 1ms
- pdor.UseRegNum = 2;
- pdor.Reg1 = 0x60400010;// 16bit
- pdor.Reg2 = 0x607A0020;// 32bit
- PDO_Config(PDO_Type.配置rPDO1, pdor);
- //回信
- PDO_Struct pdot = new PDO_Struct();
- pdot.tPDO上传触发器 = 7;
- pdot.tPDO禁止时间_100us = 10000;//1秒
- pdot.tPDO计时触发器_1ms = 0;//【单位1ms】只在tPDO异步时生效【x1ms】(254,255)异步,定时上传u16【最大65535ms】
- pdot.UseRegNum = 2;//绑定2个寄存器
- pdot.Reg1 = 0x60410010;// 16bit
- pdot.Reg2 = 0x60640020;// 32bit
- PDO_Config(PDO_Type.配置tPDO1, pdot);
-
- #endregion

- //h1400-01定义
- 【d31 rPDO总开关 0开,1关】【d30 保留】【d29(0标准帧11bit),(1扩展帧29bit)】【d28~0 帧id】
-
- //h1800-01定义
- 【h1800-01】定义【d31 tPDO 0开,1关】【d30 RTR 0开,1关】【d29 0标准帧,1扩展帧】【d28~0 帧id】
- // RTR:远程帧回应
-
-
-
- //写信
- PDO_Struct pdor = new PDO_Struct();
- pdor.rPDO命令触发器 = 1;//【0~240】在1个SYNC后,rPDO值才生效。【254或255】rPDO值立即生效(不需要SYNC信号)
- //【241~251】参数无效【252~253】rPDO命令失效(不受rPDO命令控制)
- pdor.rPDO禁止时间_100us = 10; // 1ms内,不听命令
-
- pdor.UseRegNum = 2;
- pdor.Reg1 = 0x60400010;// 16bit
- pdor.Reg2 = 0x60FF0020;// 32bit // 速度设定obj
- sta = PDO_Config(PDO_Type.配置rPDO1, pdor);
-
- //回信
- PDO_Struct pdot = new PDO_Struct();
- pdot.tPDO上传触发器 = (Byte)(Address * 2);// 错开上传帧【注意254/255】
- pdot.tPDO禁止时间_100us = (UInt16)(Address * 500);//6553.5ms //65ms 【帧间隔】
- pdot.tPDO定时触发器_1ms = 10000;//.tPDO上传触发器= [254,255]时才有效
-
- pdot.UseRegNum = 2;
- pdot.Reg1 = 0x60410010;// 16bit
- pdot.Reg2 = 0x606C0020;// 32bit //【速度值】
- sta &= PDO_Config(PDO_Type.配置tPDO1, pdot);
- return sta;

-
- #region PDO配置: 指针绑定
- //========快捷指针寄存器受控码
- //rPDO1 200h+ tPDO1 180h+
- //rPDO2 300h+ tPDO1 280h+
- //rPDO3 400h+ tPDO1 380h+
- //rPDO4 500h+ tPDO1 480h+
-
- /// <summary>
- /// 2023.6.25 rPDO配置【1400控制,1600绑定】
- /// 祁成qq750273008
- /// SET到伺服8字节,这是寄存器快捷键1400h,1600h
- /// </summary>
- bool PDOr_Config(PDOtype PDOn, PDO_Struct obj)// PDO配置
- {
- bool sta = true;
- byte zu = (byte)(PDOn);
- short h1400 = (short)((zu - 1) + 0x1400);// 确定组队【队伍】
- short h1600 = (short)((zu - 1) + 0x1600);
-
- //1 PDO总开关:关闭 子索引5
- //h1400-01定义【d31 rPDO总开关】【d30 保留】【d29(0标准帧11bit),(1扩展帧29bit)】【d28~0 帧id29bit】
- sta &= set_region(h1400, 0x01, 1 << 31); // 关闭 rPDO 功能(原值: 0x4000 0200h + 从站地址)// 0x40000202
-
- //2 1400配置
- sta &= set_region(h1400, 0x02, obj.rPDO命令触发器); //【0~240】(第1次SYNC帧后,生效设定值)【原值:0xFF】254,255为事件,值不同立即生效
- sta &= set_region(h1400, 0x03, 0);// (死区ms)接收PDO1命令过滤间隔,单位0.1ms 雷赛40ms(原值:0x00)
- //set_region(h1400, 0x04, 0);// 不存在
- //sta &= set_region(h1400, 0x05, 0);// 是定时触发器(原值:0x00)【不用于RPDO】
-
- //3 1600寄存器绑定
- sta &= set_region(h1600, 0x00, 0x00); // 寄存器指针:关闭 (原值:0x02)
-
- if (obj.Reg1 != 0) sta &= set_region(h1600, 1, obj.Reg1); // 指针1 0x60400010 控制字u16
- if (obj.Reg2 != 0) sta &= set_region(h1600, 2, obj.Reg2); // 指针2 0x607A0020 目标位置u32 PDO4:0x60FF0020 目标速度u32
- if (obj.Reg3 != 0) sta &= set_region(h1600, 3, obj.Reg3); // 指针3
- if (obj.Reg4 != 0) sta &= set_region(h1600, 4, obj.Reg4); // 指针4
- if (obj.Reg5 != 0) sta &= set_region(h1600, 5, obj.Reg5); // 指针5
- if (obj.Reg6 != 0) sta &= set_region(h1600, 6, obj.Reg6); // 指针6
- if (obj.Reg7 != 0) sta &= set_region(h1600, 7, obj.Reg7); // 指针7
- if (obj.Reg8 != 0) sta &= set_region(h1600, 8, obj.Reg8); // 指针8
- // 所有寄存器加起来不能超过64bit
- if (obj.UseRegNum > 8) obj.UseRegNum = 8;// 不能超过64bit
- sta &= set_region(h1600, 0x00, obj.UseRegNum); // 寄存器指针有效数量
-
- //4 rPDO使能 bit31【PDO总开关,0:开】 bit10~0【帧id 11bit,受控码】
- sta &= set_region(h1400, 0x01, 0x40000000 + 0x100 + (0x100 * zu) + Address); // 开启PDO1功能 // 0x40000202
-
- return sta;
- }
- /// <summary>
- /// 2023.6.25 tPDO配置【1800配置,1A00绑定】
- /// 祁成qq750273008
- /// </summary>
- /// <param name="PDOn"></param>
- /// <param name="obj"></param>
- /// <returns></returns>
- bool PDOt_Config(PDOtype PDOn, PDO_Struct obj)
- {
- bool sta = true;
- byte zu = (byte)(PDOn);
- short h1800 = (short)((zu - 1) + 0x1800);// 确定组队【队伍】
- short h1A00 = (short)((zu - 1) + 0x1A00);
-
- //1 PDO总开关:关闭 子索引5个
- sta &= set_region(h1800, 0x01, 1 << 31); // 关闭 tPDO 功能(原值: 0x4000 0180h + 从站地址)// 0x40000182
-
- //2 1800配置
- sta &= set_region(h1800, 0x02, obj.tPDO上传触发器); //【0】非循环(值有变化,sync后上传),【1~240】SYNC到(设置值)次数后上传tPDO,【254或255】值变或计时到就上传。
- sta &= set_region(h1800, 0x03, obj.tPDO禁止时间_100us);// (死区ms)回帧失败等待间隔,单位0.1ms 雷赛40ms(原值:0x00)
- //=set_region(h1400, 0x04, 0);// 不存在
- sta &= set_region(h1800, 0x05, obj.tPDO定时触发器_1ms);//【原值:0x00】//【tPDO上传触发器=255时】时间到就上传tPDO
-
- //3 1A00寄存器绑定
- sta &= set_region(h1A00, 0, 0x00); // 寄存器指针:关闭 (原值:0x01)
-
- if (obj.Reg1 != 0) sta &= set_region(h1A00, 1, obj.Reg1); // 指针1 0x60410010 状态字u16
- if (obj.Reg2 != 0) sta &= set_region(h1A00, 2, obj.Reg2); // 指针2 0x60640020 电机位置u32
- if (obj.Reg3 != 0) sta &= set_region(h1A00, 3, obj.Reg3); // 指针3 0x606C0020 当前速度u32
- if (obj.Reg4 != 0) sta &= set_region(h1A00, 4, obj.Reg4); // 指针4
- if (obj.Reg5 != 0) sta &= set_region(h1A00, 5, obj.Reg5); // 指针5
- if (obj.Reg6 != 0) sta &= set_region(h1A00, 6, obj.Reg6); // 指针6
- if (obj.Reg7 != 0) sta &= set_region(h1A00, 7, obj.Reg7); // 指针7
- if (obj.Reg8 != 0) sta &= set_region(h1A00, 8, obj.Reg8); // 指针8
- // 所有寄存器加起来不能超过64bit
- if (obj.UseRegNum > 8) obj.UseRegNum = 8; //if (obj.UseNum > 8) obj.UseNum = 8;
- sta &= set_region(h1A00, 0, obj.UseRegNum); // 寄存器指针有效数量
- //4 PDO使能 40000182
- sta &= set_region(h1800, 1, 0x40000000 + 0x80 + (0x100 * zu) + Address); // 开启tPDO功能 // 0x40000182
- return sta;
- }
- public bool PDO_Config(int Slave_id, PDO_Type type, PDO_Struct pdo)
- {
- Address = (byte)Slave_id;
- bool sta = true;
- switch (type)
- {
- case PDO_Type.配置rPDO1:// 命令下达寄存器(命令)
- sta &= PDOr_Config(PDOtype.PDO1, pdo);
- break;
- case PDO_Type.配置rPDO2:
- sta &= PDOr_Config(PDOtype.PDO2, pdo);
- break;
- case PDO_Type.配置rPDO3:
- sta &= PDOr_Config(PDOtype.PDO3, pdo);
- break;
- case PDO_Type.配置rPDO4:
- sta &= PDOr_Config(PDOtype.PDO4, pdo);
- break;
- case PDO_Type.配置tPDO1:// 状态回帧寄存器(回答)
- sta &= PDOt_Config(PDOtype.PDO1, pdo);
- break;
- case PDO_Type.配置tPDO2:
- sta &= PDOt_Config(PDOtype.PDO2, pdo);
- break;
- case PDO_Type.配置tPDO3:
- sta &= PDOt_Config(PDOtype.PDO3, pdo);
- break;
- case PDO_Type.配置tPDO4:
- sta &= PDOt_Config(PDOtype.PDO4, pdo);
- break;
-
- default:
- break;
- }
- return sta;
- }
- public bool PDO_Config(PDO_Type type, PDO_Struct pdo)
- {
-
- 写信
- //PDO_Struct pdor = new PDO_Struct();
- //pdor.rPDO命令触发器 = 255;//【0~240】在1个SYNC后,rPDO值才生效。【254或255】rPDO值立即生效(不需要SYNC信号)
- 【241~251】参数无效【252~253】rPDO命令失效(不受rPDO命令控制)
- //pdor.rPDO禁止时间_100us = 10;// 1ms过滤
-
- //pdor.UseRegNum = 2;
- //pdor.Reg1 = 0x60400010;// 16bit
- //pdor.Reg2 = 0x607A0020;// 32bit
- //PDO_Config(PDO_Type.配置rPDO1, pdor);
-
- 回信
- //PDO_Struct pdot = new PDO_Struct();
- //pdot.tPDO上传触发器 = 7;// 第n个SYNC帧后,触发tPDO帧
- //pdot.tPDO禁止时间_100us = 5000;// 【上传失败用】上传帧间隔
- //pdot.tPDO定时触发器_1ms = 0;//【tPDO上传触发器=255时】时间到就上传tPDO
-
- //pdot.UseRegNum = 2;
- //pdot.Reg1 = 0x60410010;// 16bit
- //pdot.Reg2 = 0x60640020;// 32bit
- //PDO_Config(PDO_Type.配置tPDO1, pdot);
-
-
- //=========================================
- return PDO_Config(Address, type, pdo);
- }
-
- #region 作废
- public void PDO_EN()
- {
- //6040
- //0 Switch on 转换开
- //1 Enable voltage电压开
- //2 Quick Stop快停
- //3 Enable operation 启用操作
- //4 pp新设定点(正触发) hm回零操作开始(正触发)
- //5 pp立即更改集合
- //6 pp绝对(0)/相对(1)
- //7 Fault reset 故障复位
- //8 Halt 暂停 hm回零停止运行(0x10F)
-
- //执行回零 bit4
- PDO(PDOtype.PDO1, 0x2F);// 准备回零 bit4 上升沿触发
- SYNC();
- PDO(PDOtype.PDO1, 0x3F);
- SYNC();
- }
-
- #endregion
- #endregion

【08】【600+从站id】【DDDDDDDDCCBBBBAA】
DLC=08,帧id=0x600+从站id
低字节先发。 AA操作码 ,BBBB寄存器地址,CC子索引,DDDDDDDD寄存器值
-
- 600h+ rSD0 (set到驱动器)
- 580h+ tSD0 (get回帧)
-
- GOB_ID B0 B1B2 B3 B4B5B6B7
- 601(600h+从站地址)
-
- 2F写 8bit 1032寄存器(0x3210) 10子索引 10 (0x10)设定值
- 2B写 16bit 1032寄存器(0x3210) 10子索引 10 32 (0x3210)
- 27写 24bit 1032寄存器(0x3210) 10子索引 10 32 54(0x543210)
- 23写 32bit 1032寄存器(0x3210) 10子索引 10 32 54 76 (0x76543210)
- 40读寄存器 1032寄存器(0x3210) 10子索引 空0x00000000
- 回帧0x60是成功,0x80是故障
- 1032寄存器地址(0x3210)
- 10子索引(0x10是16,一般是0~3)
- //或错误码
- 数值10 32 54 76(0x76543210)
- ————————————————
- 版权声明:本文为CSDN博主「cfqq1989」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- 原文链接:https://blog.csdn.net/cfqq1989/article/details/128009555

上位机到伺服:【写伺服】
伺服到上位机:【读伺服】
80h的 中止代码 【u32】
- string get_Error_str( Int32 reg, Int32 Son, Int32 errcode)
- {
- string errorString = string.Empty;
- string str1 = $"Reg{reg.ToString("X4")}h-{Son.ToString("X2")}= 0x{errcode.ToString("X8")};_";
- switch (errcode)
- {// 80h b3b2b1b0
- case 0x05030000: errorString = str1 + "触发位没有交替变化! "; break;
- case 0x05040000: errorString = str1 + "SDO 协议超时! "; break;
- case 0x05040001: errorString = str1 + "无效/ 未知的命令字! "; break;
- case 0x05040002: errorString = str1 + "无效的块大小(仅块传输模式)! "; break;
- case 0x05040003: errorString = str1 + "无效的序号(仅块传输模式)! "; break;
- case 0x05040004: errorString = str1 + "CRC 错误(仅块传输模式)! "; break;
- case 0x05040005: errorString = str1 + "内存溢出! "; break;
- case 0x06010000: errorString = str1 + "对象不支持访问! "; break;
- case 0x06010001: errorString = str1 + "试图读只写对象! "; break;
- case 0x06010002: errorString = str1 + "试图写只读对象! "; break;
- case 0x06020000: errorString = str1 + "对象不存在! "; break;
- case 0x06040041: errorString = str1 + "对象不能映射到PDO内! "; break;
- case 0x06040042: errorString = str1 + "映射的对象的数目和长度超出 PDO 长度! "; break;
- case 0x06040043: errorString = str1 + "一般性参数不兼容! "; break;
- case 0x06040047: errorString = str1 + "一般性设备内部不兼容! "; break;
- case 0x06060000: errorString = str1 + "硬件错误导致对象访问失败! "; break;
- case 0x06060010: errorString = str1 + "数据类型不匹配,服务参数长度不匹配! "; break;
- case 0x06060012: errorString = str1 + "数据类型不匹配,服务参数长度太长! "; break;
- case 0x06060013: errorString = str1 + "数据类型不匹配,服务参数长度太短! "; break;
- case 0x06070010: errorString = str1 + "数据型态不符;参数长度不符! "; break;
- case 0x06090011: errorString = str1 + "子索引不存在! "; break;
- case 0x06090030: errorString = str1 + "超出参数的值范围(写访问时)! "; break;
- case 0x06090031: errorString = str1 + "写入参数数值太大! "; break;
- case 0x06090032: errorString = str1 + "写入参数数值太小! "; break;
- case 0x06090036: errorString = str1 + "最大值小于最小值! "; break;
- case 0x08000000: errorString = str1 + "一般性错误! "; break;
- case 0x080000A1: errorString = str1 + "读EEPROM错误! "; break;
- case 0x080000A2: errorString = str1 + "写EEPROM错误! "; break;
- case 0x080000A3: errorString = str1 + "存取EEPROM超出范围! "; break;
- case 0x080000A4: errorString = str1 + "存取EEPROM错误! "; break;
- case 0x080000A5: errorString = str1 + "密码错误! "; break;
- case 0x08000020: errorString = str1 + "数据不能传送或保存到应用! "; break;
- case 0x08000021: errorString = str1 + "由于本地控制导致数据不能传送或保存到应用! "; break;
- case 0x08000022: errorString = str1 + "对象使用中! "; break;
- case 0x08000023: errorString = str1 + "对象字典不存在! "; break;
- //0800 0023H
- //对象字典动态产生错误或对象字典不存在(例如通过文件生成对象字典,但由于文件
- //损坏导致错误产生)
- default:
- errorString = str1 + "从站错误。检查通讯? ";
- break;
- }
- return errorString;
- }

数组:
-
- 上位机发 0x40读 寄存器地址 寄存器子索引
- 伺服回帧 0x41 寄存器地址 寄存器子索引 + 32bit【该寄存器值 b0在前..b4】
-
- 伺服回帧 0x80【操作失败】 寄存器地址 寄存器子索引 + 32bit【该寄存器值,故障码】
- 伺服回帧 0x60【操作成功】
-
- while(条件)
- {
- 上位机发0x60继续
- 伺服回帧0x00
- 上位机发0x70继续
- 伺服回帧0x10
- }
-
- 速率 与 距离
- 1 Mbps 25 m
- 750 Kbps 50 m
- 500 Kbps 100 m
- 250 Kbps 250 m
- 125 Kbps 500 m
- 台达A2-can伺服:上位机发帧id=0xff,从站会自动回复
- 6093-01齿轮比.分子(只适用于台达)//汇川0x6091
- 6093-02齿轮比.分母
- 关系 1280000/分母*分子 // 如果一圈是5万(分母128万,分子5万)
-
- //齿轮比
- sta &= set_region(0x6093, 1, zi); //"P1.044"分子 乘以N ,齿轮 分zi(编码器最大值)
- sta &= set_region(0x6093, 2, mu); //"P1.045"分母
- //速度
- 400转 x 编码器分辨率 / 60
-
- 扭矩模式:
- 0x6060=4;//扭矩模式
- 0x6061//当前伺服工作模式
- 0x6040//控制字
- 0x6041//状态字
- 0x6071//目标扭矩 -3000~3000
- 0x6074//最高扭矩
- 0x6075//电机额定电流
- 0x6077//回授:电机扭矩
- 0x6078//回授:电机电流mA
- 0x6087//扭矩斜率
-
- 定位模式:
- 6093-01分子(只适用于台达) 雷赛在(0x2001-00)
- 6093-02分母
- 0x6060=1;//1定位模式 3速度 4力矩 6回零 7插补
- 0x607A//目标位置
- 0x6081//目标速度
- 0x6082//起跳速度
- 0x6083//加速
- 0x6084//减速
- 0x6064//电机位置
- 0x6062//命令位置
- 0x6063//实际位置
-
- 0x6065//误差范围 //位置误差报警阀值 AL009 (60F4h当前位置误差值)
- 0x60F4//当前误差值
- 0x60FC//位置需求值-1
- 0x6067//定位完成,确认范围
- 0x6068//定位完成,时间范围
-
- 插补模式:
- 6060=0x07
- 周期写 60C1-01=绝对坐标

- 0000h 保留
- 0001h ~ 025Fh 数据类型定义
- 0260h ~ 0FFFh 保留
- 1000h ~ 1FFFh 通讯协议区【PDO,SDO,SYNC,NMT,TIME,EMCY等总线命令定义】
- 2000h ~ 5FFFh 设备参数区【设备厂家自定义】
- 6000h ~ 9FFFh 运动控制寄存器区【0x6040等】
- A000h ~ AFFFh 网络变量【IEC61131-3】
- B000h ~ BFFFh 路由器网关变量
- C000h ~ FFFFh 保留
-
-
- cia401 i/o模块行规
- cia402 伺服运动控制
- cia403 人机接口行规
- cia404 测量设备与闭环控制行规
- cia406 编码器行规
- cia408 比例液压行规

-
- 保存:
- 0x1010-01=0x65766173;//【保存所有参数】保存参数
- 恢复:
- 0x1011-01=0x64616F6C;//【恢复所有参数】雷赛不支持
- 0x1011-02=0x64616F6C;//【恢复从1000h到1FFFh】雷赛,断电重启生效(不要执行保存)【禾川0x1011-02】
- 0x1011-03=0x64616F6C;//【恢复从6000h到9FFFh】雷赛不支持
- 0x1011-04=0x64616F6C;//【伺服厂家自定义】雷赛用4,断电重启生效(不要执行保存)
-
- 注:0x1011-04设置恢复后,拔掉电源,重新上电后,所有参数就复位了
-
- PLC发的指令是 0x1011-02
CANopen协议,上位机开发(C#)_c# canopen_cfqq1989的博客-CSDN博客
-
- 1000h 【u32】驱动器机种码 0x0B02 0192 //0192伺服 0B02台达B3系列 04020192:A2
- 1001h 【u8】 错误寄存器 b4通讯 b3温度b2电压b1电流b0一般错误
- 1003h-00【u32】故障记录表(4组)
- -01 0x58120
- -02 0
- -03 0
- -04 0
-
- 1005h 【同步帧】功能码 【0x80】
- 1006h 【同步帧】循环周期us 【0】0关闭SYNC
- 1007h 【同步帧】同步窗口长度【0】
- 1008h 设备名称【台达A2】
- 1009h 硬件版本
- 100Ah 软件版本
- 100Ch 【0】保护时间ms【100c乘以100d的值,构成看门狗时间】
- 100Dh 【0】寿命倍数,看门狗时间 100Ch的倍数(范例:若 OD 100Ch = 5 ms, OD 100Dh = 10,则寿命 Life time 等于 50 ms。)
-
- 1010h -00 【4】有4组
- -01 保存所有参数
- -02 保存通信参数1000h~1fffh
- -03 保存驱动器参数
- -04=0x65766173【必须看厂家手册】
-
- 1011h -00 【4】有4组
- -01 恢复所有默认段落。
- -02 恢复通讯命令参数。1000h~1fffh
- -03 恢复伺服出厂参数。
- -04=0x64616F6C【重置参数,厂家:出厂参数】
-
- 1014h EMCY故障帧 【80h+从站id】 如从站3是 0x83;
-
- 1016-01h 【u32】断网保护ms(b15~0 ms b23~16 从站)AL180故障【监听上位机心跳】
- -02h 心跳消费
- -03h 消费者心跳时间
- -04h 消费者心跳时间
- -05h 消费者心跳时间
-
- 1017h 【u16】生产者心跳ms默认2000ms 【700h+从站id】如从站3【帧id=703h 包0f】
-
- 1018-00h 4
- -01h 【u32】辨识对象【厂家id,0x331
- -02h 【u32】 产品id,0x8200
- -03h 【u32】 版本id,0x100
- -04h 【u32】 序列号id】0x01
-
- 1200h SDO受控功能码 -01=【600h+从站id】 -02=【580h+从站id】
-
- // PDO的配置【rPDO和tPDO】
- 1400h(主→从)rPDO1功能码-00h 【5】
- -01h 【40000203】【u32】b31:rPDO1总开关(最高位0开)【帧id】b10~0:功能码(200h+从站地址)
- -02【u8】【0~240】在1次SYNC后,生效rPDO设定值,【255】立即生效参数
- -03【u16】命令过滤时间
- -04 空
- -05 【0】触发定时器
- 1401h(主→从)rPDO2功能码【配置】
- 1402h(主→从)rPDO3功能码
- 1403h(主→从)rPDO4功能码
- 1600h PDO1批量写寄存器(指针绑定寄存器数量)
- 1601h PDO2批量写寄存器【配置】
- 1602h PDO3批量写寄存器
- 1603h PDO4批量写寄存器
-
- 1800h(主←从)tPDO功能码-01【u32】b31:tPDO1总开关(最高位0开) b10~0:功能码(180h+从站地址)
- -02 【0~240】在1~240次SYNC后,上传tPDO帧
- -03 上传失败后,重发数据帧的间隔时间【0.1ms】
- -04 空
- -05 定时器(02=255时,值改变或定时时间到,上传tPDO帧)【1ms】
- 1801h(主←从)tPDO2功能码【配置】
- 1802h(主←从)tPDO3功能码
- 1803h(主←从)tPDO4功能码
- 1A00h tPDO1批量读寄存器(指针绑定寄存器数量)
- 1A01h tPDO2批量读寄存器
- 1A02h tPDO3批量读寄存器
- 1A03h tPDO4批量读寄存器
- //汇川,公式
- 【200A+BB】//2000h段公式: H2.16对应【0x2002+ 子索引】 0x2002-16
- //台达,公式
- 【200A+BB】//2000h段公式: P2.16对应【0x2002+ 子索引】0x2016

-
- 603fh 最后错误码u16
- 6040h 控制字
- 00关》06待机》07使能》0f工作》1f动作(b4上升沿,b5旧命令,b6 0绝对位置1相对位置)
- b0启动(上升沿)
- b1电压输出
- b2急停(0急停报警)
- b3命令(上升沿)
- //===B3~0伺服命令
- b4运动命令(上升沿)
- b5 0等待旧命令位置完成
- b6 0绝对位置 1相对位置【6F》SYNC》7F》SYNC】
- b7上升沿复位
- b8 1暂停 0继续(Halt)
- b9 1使用上次的旧速度
- 6040=相对运动6F》7F; =绝对运动2F》3F; =停止10F;
- (例如:速度模式0x6060=3;0x1400-02=240;
- 》0x6040=0x06;
- 》SYNC();
- 》0x6040=0x0f;
- 》SYNC();
- )电机就转了
- 6041h 状态字 b0 准备启动 1637定位完成, 1237定位中
- b1 准备完成
- b2 伺服使能
- b3 异常
- b4 电压输出
- b5 急停
- b6 伺服关闭
- b7 警告
- b8 保留
- b9 远程控制
- b10 位置到达
- b11 内部限制激活(不支持)
- b12 pp:已收到位置命令
- b13 pp:跟踪误差
- b14 正转禁止
- b15 反转禁止
- 605Ah 急停时【刹车速度】
- 605Bh 停机下:0使能关闭 1开启动态刹车
- 605Eh 停机下:0使能关闭 1曲线刹车 2急刹
- //===================================
- 6060h 伺服模式:0保留1位置3速度4扭矩6回零7补间位置8CSP位置(Ecat)9速度10转矩
- 6061h 当前伺服模式
- 6062h 命令位置
- 6063h 编码器位置(A2电机一圈 1280000 pulses,A3-B3 电机一圈 16777216 pulses)
- 6064h 电机位置
- 6065h 位置误差报警阀值 AL009 (60F4h当前位置误差值)
- 6067h 位置到达精度(位置小于精度,定位完成)
- 6068h 位置到达停留时间ms(超过停留时间,定位完成)
- 606Bh 命令速度
- 606ch 速度回授
- 606dh 速度到达范围
- 606eh 速度到达时间
- 606fh 零速准位
- 6071h 目标扭矩 -3000~3000
- 6072h 最大扭矩
- 6074h 内部扭矩值(千分比)
- 6075h 电机额定电流(mA)
- 6076h 电机额定扭矩
- 6077h 回授扭矩
- 6078h 回授电流
- 607Ah 目标位置 int32位
- 607Ch 原点偏移
- 607Dh 软限位 -01负限位(-2147483648) -02正限位
- 607Eh 指令极性
- 607fh 最高【命令速度】
- 6080h 最高【电机速度】
- 6081h 定位巡航速度,ACC速度
- 6082h 起跳速度(冲击速度)【Jerk】
- 6083h 加速度
- 6084h 减速度
- 6085h 急停斜率,急停速度
- 6087h 扭矩斜率
- 6091.01h 齿轮比分子
- 6091.02h 齿轮比分母
- 6093h 齿轮比 -01分母 -02分子 (适用于台达)
- 6098h 回零模式 35当前位置为零点
- 6099h 回零速度 -01高速(1~2000) -02低速(1~500)
- 609Ah 回零加速度
- 60FCh位置需求值-1
- 60fdh DI输入信号(b0负 b1正 b2原点)
- 60feh DO输出信号(b16 DO1,b17 DO2)
- 60ffh 速度模式:目标速度
-
- 台达: P3.00对应 0x2300 // P1.44对应 0x212C // 2000 + 3.00是 0x2300
-
- //60B0h位置偏移-1
- //60B1h速度偏移-1
- //60B2h扭矩偏移-1
- //60C0h插值子模式选择-1
- //60C1h插值数据记录-1
- //60C2h插值时间段-1
- //60C5h最大加速度-1
- //60C6h最大减速度-1
- //60F2h定位选项代码-1
- //60F4h跟随误差实际值0
- //60FCh位置需求值-1
- //set_region(0x2154, 0, 1);// 输入io电平逻辑 0正逻辑1反
- //60FDh 输入 IO 状态0(bit0:负限位 bit1:正限位 bit2:原点信号 bit16:快速停止
- //60FEh-01 物理输出控制
- //60FEh-02 物理输出使能
- //60FFh目标速度0
- //6502h支持的驱动模式【1支持】d0轮廓位置pp,d1变频调速vl,d2轮廓速度pv,d3轮廓转矩,d5回零,d6插补模式ip,d7周期同步位置csp,d8周期同步速度csv,d9周期同步转矩cst

动作激活 6040= 06》07》0F 》1F
- 输入IO状态 60FD+00【u32】 bit0:负限位 bit1:正限位 bit2:原点信号 bit16:快速停止
- DO 60FE+01
- 60FE+02
- 当 2005+01/02 的功能设置为 bit4 时,IO 输
- 出为主站控制;bit16 对应 out1,bit17 对应
- out2.必须当 60fe+01 和 60fe+02 进行的是
- 与操作
-
- 6060 = // 【1位置 3速度 4扭矩 6回零 7补间
- ===========================【定位】=============
- 定位模式:6060=1
- 分子 6093-2
- 分母 6093-1
- 定位 607a
- 读电机位置 6064
- 定位时速度 6081
- 读电机速度 606c
-
- 起跳速度 6082 【模式 1 起跳速度和停止速度】
- 加速 6083 计算方式:【100转】 = (100 * 圈脉冲)
- 减速 6084
- 速度上限
-
- 位置超差 6065
- 当前超差 60f4
- 到位准位 6067【时间 6068】
-
- ============================【速度】=============
- 速度模式:6060=3
- 设置速度 60ff 【壹x圈脉冲】是每秒一转
- 读取速度 606c
- 零速准位 606f
-
- =============================【回零】============
- 回零模式:6060=6
-
- 回零方式 6098 35当前位置为零点
- 回零高速 6099h 回零速度 -01高速(1~2000)
- 回零低速 -02低速(1~500)
- 回零加/减速度 609A
- 原点偏置 607c
-
-
-
-
-
-
-
- =============================【支持】============
- 1pp 2vl 3pv 4tq 6hm 7ip 8csp 9csv 10cst
-
- 6502h bit0轮廓pp bit1变频vl 2轮廓速度pv 3轮廓转矩pt 4空 5回零hm 6插补ip
- 7同步位置csp 8同步速度csv 9同步力矩cst

-
- using help;
- using Models;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
-
- // 1先引用 CAN_namespace 用于参数类型 // using USB_CAN;
- // 2再引用 help的方法
-
- namespace CAN_namespace
- {
- #region 全局类型:通讯模块接口
- /// <summary>
- /// 全局类型:通讯模块接口
- /// </summary>
- public interface Iface_RTX
- {
- /// <summary>
- /// 连接
- /// </summary>
- /// <typeparam name="T">连接</typeparam>
- /// <param name="a">ip地址</param>
- /// <param name="b">端口</param>
- /// <returns></returns>
- bool connect<T>(T a, T b);
-
-
- /// <summary>
- /// 发送并接收
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="cmd"></param>
- /// <param name="t"></param>
- /// <returns></returns>
- bool sendAndReceive<T>(string cmd, ref T t);//万物皆文本
-
-
- /// <summary>
- /// 接收事件
- /// </summary>
- /// <returns></returns>
- int RXs(ref object obj);
- //int RXs<T>(ref T obj);//测试
-
- /// <summary>
- /// 只发送
- /// </summary>
- /// <param name="cmd"></param>
- /// <returns></returns>
- bool TXs(string cmd);
-
- /// <summary>
- /// 断开
- /// </summary>
- /// <returns></returns>
- bool Close();
-
- }
- #endregion
- #region 对象
- public class Help_USB_CAN : Iface_RTX
- {//作者qq750273008 祁成 更新日期:2023.06.23
- //===============================================
- //[Browsable(true)] //可浏览
- //[Category("自定义属性")] // 属性分栏
- //[Description("属性的说明")] //
- //================================================
- #region 全局
- //1申明委托》委托命令
- public delegate void WT_GET_Data(CiA402 ciA402);//↑ui显示发送命令
- public delegate void WT_SET_Data(byte[] butes, string data);//↓下执行对象
-
- #region CAN参数类型:全局;【设备类型,主板信息,单帧信息,配置表
-
- #region 备用接口声明
- public interface Iface_RTX
- {
- /// <summary>
- /// 连接
- /// </summary>
- /// <typeparam name="T">连接</typeparam>
- /// <param name="a">ip地址</param>
- /// <param name="b">端口</param>
- /// <returns></returns>
- bool connect<T>(T a, T b);
-
-
- /// <summary>
- /// 发和收
- /// </summary>
- /// <param name="cmd"></param>
- /// <returns></returns>
- bool sendAndReceive<T>(string cmd, ref T t);
-
-
- /// <summary>
- /// 接收事件
- /// </summary>
- /// <returns></returns>
- int RXs(ref object obj);
-
- /// <summary>
- /// 只发送
- /// </summary>
- /// <param name="cmd"></param>
- /// <returns></returns>
- bool TXs(string cmd);
-
- /// <summary>
- /// 断开
- /// </summary>
- /// <returns></returns>
- bool Close();
-
-
-
- }
-
- #endregion
-
- /*------------兼容ZLG的数据类型---------------------------------*/
- //1.设备类型
- /// <summary>
- /// 设备类型(单路,双路,以太网CAN)
- /// </summary>
- public enum DeviceType : byte //设备类型【单路,双路,以太网can】
- {
- DEV_USBCAN = 3, // USB单路CAN
- DEV_USBCAN2 = 4,// USB双路CAN
- VCI_USBCAN1 = 3,
- VCI_USBCAN2 = 4,// 我买的属于这个(创新科技CAN-Pro)
- VCI_USBCAN2A = 4,
- VCI_USBCAN_E_U = 20,// 以太网单路CAN
- VCI_USBCAN_2E_U = 21// 以太网双路CAN
- }
- //设备类型
- public enum CAN设备类型 : int
- {
- DEV_USBCAN = 3, // USB单路CAN
- DEV_USBCAN2 = 4,// USB双路CAN
- VCI_USBCAN1 = 3,
- VCI_USBCAN2 = 4,
- VCI_USBCAN2A = 4,
- VCI_USBCAN_E_U = 20,// 以太网单路CAN
- VCI_USBCAN_2E_U = 21// 以太网双路CAN
-
- }
-
- //2.ZLGCAN系列接口卡信息的数据类型。
- /// <summary>
- /// 主板信息
- /// </summary>
- public struct VCI_BOARD_INFO //主板信息
- {
- public UInt16 hw_Version;// 硬件版本号,用16进制表示。比如0x0100表示V1.00。
- public UInt16 fw_Version;// 固件版本号,
- public UInt16 dr_Version;// 驱动程序版本号,
- public UInt16 in_Version;// 接口库版本号,
- public UInt16 irq_Num;// 保留参数。
- public byte can_Num;// 表示有几路CAN通道。
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
- public byte[] str_Serial_Num;// 此板卡的序列号。
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
- public byte[] str_hw_Type;// 硬件类型,比如“USBCAN V1.00”(注意:包括字符串结束符’\0’)
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- public byte[] Reserved;// 系统保留。
- }
-
- //2-1.USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。
- /// <summary>
- /// USB-CAN设备主板信息,该类型为VCI_FindUsbDevice函数的返回参数。
- /// </summary>
- public struct VCI_BOARD_INFO1 // 读取USB主板信息
- {//该类型为VCI_FindUsbDevice函数的返回参数。
-
- public UInt16 hw_Version;// 硬件版本号,用16进制表示。比如0x0100表示V1.00。
- public UInt16 fw_Version;// 固件版本号,
- public UInt16 dr_Version;// 驱动程序版本号,
- public UInt16 in_Version;// 接口库版本号,
- public UInt16 irq_Num;// 保留参数。
- public byte can_Num;// 表示有几路CAN通道。
- public byte Reserved;// 保留。
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] str_Serial_Num;// 此板卡的序列号。
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
- public byte[] str_hw_Type;// 硬件类型,比如“USBCAN V1.00”(注意:包括字符串结束符’\0’)
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
- public byte[] str_Usb_Serial;// usb串口号?
- }
- //3.定义CAN每帧的数据类型。
- /// <summary>
- /// CAN的每一帧详细信息(每帧对象)
- /// </summary>
- public unsafe struct VCI_CAN_OBJ //CAN每帧对象,
- {
- public uint ID;// 帧ID。 u32变量,数据格式为靠右对齐。 详情请参照: 《8.附件1: ID对齐方式.pdf》说明文档。
- public uint TimeStamp; //u32,设备接收到某一帧的时间标识。 时间标示从CAN卡上电开始计时,计时单位为0.1ms。
- public byte TimeFlag; //是否使用时间标识,=1时TimeStamp有效
- public byte SendType; //发送类型。=0时为正常发送(发送失败会自动重发,重发超时时间为4秒, 4秒内没有发出则取消);=1时为单次发送
- public byte RemoteFlag; //是否远程帧标志。 =0时为数据帧, =1时为远程帧(数据段空)。
- public byte ExternFlag; //是否扩展帧标志。 =0时为标准帧(11位ID), =1时为扩展帧(29位ID)。
- public byte DataLen; //数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中有效字节数。
- public fixed byte Data[8]; //如DataLen定义为3,即Data[0]、 Data[1]、 Data[2]是有效的。
- public fixed byte Reserved[3];//系统保留。
- }
-
- //4.定义配置CAN的数据类型
- /// <summary>
- /// USB-CAN2、配置表(参数表)
- /// </summary>
- public struct VCI_INIT_CONFIG // 配置参数
- {
- public UInt32 AccCode;// bit全部匹配,此帧才可以被接收。否则不能接收。(//标准帧右移21bit分析)
- // 相当于机械钥匙,凸起和凹槽必须匹配,才能开锁(接收)
- // b31对应帧id最高位,所以11bit要左移21bit(//分析标准帧时右移21bit)
- public UInt32 AccMask;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
- // 相当于机械钥匙的bit销位,是否失效(bit置1为失效)
- // 。屏蔽码推荐设置为0xFFFFFFFF,即全部接收。
- public UInt32 Reserved;// 保留。
- public byte Filter; //0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
- public byte Timing0; //波特率参数,具体配置,请查看二次开发库函数说明书。(1Mbps):《Timing0=0x00,Timing1=0x14》
- public byte Timing1; // 0x14 波特率参数 1MHz(T0=0x00,T1=0x14)
- public byte Mode; //模式,0表示正常模式,1表示只听模式,2自测模式
- }
- /*------------其他数据结构描述---------------------------------*/
- public struct CHGDESIPANDPORT // 扩展端口?
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
- public byte[] szpwd;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
- public byte[] szdesip;
- public Int32 desport;
-
- public void Init()
- {
- szpwd = new byte[10];
- szdesip = new byte[20];
- }
- }
-
- public struct VCI_FILTER_RECORD //过滤器配置表
- {
- UInt32 ExtFrame;// 过滤的帧类型标志,为1代表要过滤的为扩展帧,为0代表要过滤的为标准帧。
- UInt32 Start;//滤波范围的起始帧ID
- UInt32 End;//滤波范围的结束帧ID
- }
-
- /*------------数据结构描述完成---------------------------------*/
-
-
-
- #endregion
-
- #endregion
- #region 字段
- //private CancellationTokenSource cts;//线程令牌
- //private ManualResetEvent resetEvent = new ManualResetEvent(true);// 暂停业务
- //=====================================================
- Help_String help_String = new Help_String();//文本处理
- //设备类型
- public const int DEV_USBCAN = 3;// USB单路CAN
- public const int VCI_USBCAN2 = 4;// USB双路CAN
- public const int VCI_USBCAN2A = 4;// USB双路CAN
- // E表示以太网
- public const int VCI_USBCAN_E_U = 20;// 以太网单路CAN
- public const int VCI_USBCAN_2E_U = 21;// 以太网双路CAN
-
- public const uint CAN1 = 0;
- public const uint CAN2 = 1;
- uint CAN_inD = 0;// USB设备:编号 【第几个硬件(类似com3)
-
-
-
- #endregion
- #region 属性
- //public Iface_RTX help_rtx { get; set; }// 接口扩展
- /// <summary>
- /// ↑:byte包,文本
- /// </summary>
- static public WT_GET_Data Wt_get;//↑event委托=》呼叫上ui层 让上层显示:发送命令
- /// <summary>
- /// ↓:byte包,文本
- /// </summary>
- static public WT_SET_Data Wt_set;//↓委托=》呼叫下位机执行
-
- /// <summary>
- /// USB设备id
- /// </summary>
- public uint can_deviceID { get => CAN_inD; private set => CAN_inD = value; }
-
-
- #endregion
- #region 构造
-
- #endregion
- #region 事件
-
- #endregion
-
- #region APP方法【打开,关闭,收,发,复位
- /// <summary>
- /// 打开CAN:设备类型,硬件id,CAN通道id,参数表
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <param name="pInitConfig"></param>
- /// <returns></returns>
- public UInt32 set_Open()//(DeviceType deviceType, uint deviceID,uint canX, VCI_INIT_CONFIG Config)// 设备类型,设备id,通道,配置参数
- {//打开CAN:设备类型,硬件索引,CAN通道索引,初始化参数,
-
- UInt32 DeviceType = (uint)CAN设备类型.VCI_USBCAN2;// USB双路CAN
- UInt32 DeviceInd = 0;// 第0个设备
-
- VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();// 参数表
- config.AccCode = 0;//bit钥匙匹配id,(右移21bit分析)b31对应帧id最高位
- config.AccMask = 0xffffffff;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
- config.Filter = 0;//0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
- config.Timing0 = 0x00;//波特率参数 1MHz //波特率参数 1MHz(T0=0x00,T1=0x14)
- config.Timing1 = 0x14;
- config.Mode = 0;//模式,0表示正常模式,1表示只听模式,2自测模式
-
- UInt32 sta = 1;// 故障标记
- sta &= set_Close(DeviceType, DeviceInd);// 关
- sta &= VCI_使能硬件(DeviceType, DeviceInd);// 开
-
- sta &= VCI_初始化硬件(DeviceType, DeviceInd, CAN1, ref config);// CAN 1
- sta &= VCI_初始化硬件(DeviceType, DeviceInd, CAN2, ref config);// CAN 2
-
- sta &= VCI_CAN工作(DeviceType, DeviceInd, CAN1);// CAN 1
- sta &= VCI_CAN工作(DeviceType, DeviceInd, CAN2);// CAN 2
-
- return (uint)(sta == 1 ? 1 : 0);
-
- //================================
- //VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();// 参数表
- //config.AccCode = 0;// bit全部匹配,此帧才可以被接收。否则不能接收。(//标准帧右移21bit分析)
- //config.AccMask = 0xffffffff;//全部接收 // 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
- //config.Filter = 0;//0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
- //config.Timing0 = 0x00;//波特率参数 1MHz(T0=0x00,T1=0x14)
- //config.Timing1 = 0x14;
- //config.Mode = 0;//模式,0表示正常模式,1表示只听模式,2自测模式
-
- //uint i = can.set_Open(Help_USB_CAN.VCI_USBCAN2, 0, 0, ref config);// CAN 1
- //i &= can.set_Open(Help_USB_CAN.VCI_USBCAN2, 0, 1, ref config);// CAN 2
-
- }
- /// <summary>
- /// 关闭CAN:设备类型,硬件id
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <returns></returns>
- public UInt32 set_Close(UInt32 DeviceType, UInt32 DeviceInd)// UInt32 DeviceType, UInt32 DeviceInd
- {
- UInt32 sta = 1;// 故障标记
- //UInt32 DeviceType = (uint)CAN设备类型.VCI_USBCAN2;// USB双路CAN
-
- sta &= VCI_CloseDevice(DeviceType, 0);
- VCI_UsbDeviceReset(DeviceType, DeviceInd, 0);
- return sta;
- }
- public UInt32 set_offLink(UInt32 DeviceType, UInt32 DeviceInd)
- {
- UInt32 sta = 1;// 故障标记
- VCI_UsbDeviceReset(DeviceType,DeviceInd,0);
- return sta;
- }
- /// <summary>
- /// 获取CAN设备厂家信息:设备类型,设备索引,参数表
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="pInfo"></param>
- /// <returns></returns>
- public UInt32 get_Board(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo)
- {
- return VCI_ReadBoardInfo(DeviceType, DeviceInd, ref pInfo);
- //=======================================================
- //VCI_BOARD_INFO info = new VCI_BOARD_INFO();
- //uint i = can.get_Board(4, 0, ref info);
-
- }
- public UInt32 set_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
- {
- uint sta = 1;
- sta &= VCI_ClearBuffer(DeviceType, DeviceInd, CANInd);
- //sta&= VCI_ClearBuffer(DeviceType, DeviceInd, 1);// CAN2
- return sta;
- }
- /// <summary>
- /// 接收:设备类型,设备索引,CAN通道索引,参数表,最大帧数2000,超时时间
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <param name="pReceive"></param>
- /// <param name="Len">不大于2000帧</param>
- /// <param name="WaitTime">保留=0</param>
- /// <returns></returns>
- public Int32 get_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime)
- {//VCI_CAN_OBJ pReceive 设置为数组,2000帧
- return VCI_Receive(DeviceType, DeviceInd, CANInd, ref pReceive, Len, WaitTime);
- }
- /// <summary>
- /// 发送:设备类型,设备索引,CAN通道索引,参数表,要发帧数
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <param name="pSend"></param>
- /// <param name="Len"></param>
- /// <returns></returns>
- public Int32 set_Send(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len)
- {
- return VCI_Transmit(DeviceType, DeviceInd, CANInd, ref pSend, Len);
- }
-
- public UInt32 set_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
- {// 复位can通道
- return VCI_ResetCAN(DeviceType, DeviceInd, CANInd);
- }
- //==以下不再重要=======================================================================
- //==以下不再重要========
-
-
-
-
- /// <summary>
- /// 使能硬件:设备类型,设备id。
- /// </summary>
- /// <param name="DeviceType">Help_USB_CAN.VCI_USBCAN2 = 4;双路CAN</param>
- /// <param name="DeviceInd">第1个CAN通道是0</param>
- /// <param name="Reserved">备用=0</param>
- /// <returns></returns>
- public UInt32 VCI_使能硬件(UInt32 DeviceType, UInt32 DeviceInd)
- {// 相当于 插电
- return VCI_OpenDevice(DeviceType, DeviceInd, 0x00);
- }
- /// <summary>
- /// 初始化硬件:can设备类型,设备索引0,CAN通道索引0,VCI_INIT_CONFIG初始化参数结构
- /// </summary>
- /// <param name="DeviceType">can设备类型</param>
- /// <param name="DeviceInd">设备索引0</param>
- /// <param name="CANInd">CAN通道索引0</param>
- /// <param name="pInitConfig">VCI_INIT_CONFIG初始化参数结构</param>
- /// <returns></returns>
- public UInt32 VCI_初始化硬件(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig)
- {
- return VCI_InitCAN(DeviceType, DeviceInd, CANInd, ref pInitConfig);
- }
- //设备类型。设备索引,CAN通道索引。初始化参数结构。
-
- /// <summary>
- /// CAN工作:设备类型,设备索引,CAN通道索引。(返回值=1,表示操作成功; =0表示操作失败; =-1表示USB-CAN设备不存在或USB掉线。)
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <returns></returns>
- public UInt32 VCI_CAN工作(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
- {
- return VCI_StartCAN(DeviceType, DeviceInd, CANInd);
- }
-
- /// <summary>
- /// CAN发送:设备类型,设备索引,CAN通道索引,VCI_CAN_OBJ数组的首指针,(帧数量 最大为10)
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <param name="pSend"></param>
- /// <param name="Len"></param>
- /// <returns></returns>
- public Int32 VCI_set发送(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len)
- {
- return VCI_Transmit(DeviceType, DeviceInd, CANInd, ref pSend, Len);
- }
-
- public Int32 VCI_get缓存区帧数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
- {
- return VCI_GetReceiveNum(DeviceType, DeviceInd, CANInd);// 缓存区,帧数
- }
- /// <summary>
- /// CAN接收:设备类型,设备id,CAN通道id,VCI_CAN_OBJ数组的首指针,封顶帧数 2000 ,超时时间ms
- /// </summary>
- /// <param name="DeviceType"></param>
- /// <param name="DeviceInd"></param>
- /// <param name="CANInd"></param>
- /// <param name="pReceive"></param>
- /// <param name="Len"></param>
- /// <param name="WaitTime"></param>
- /// <returns></returns>
- public Int32 VCI_get接收(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime)
- {
- //VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];
- //uint i = can.VCI_get接收(4, 0, 1, ref obj[0], 2000, 0);
- return VCI_Receive(DeviceType, DeviceInd, CANInd, ref pReceive, Len, WaitTime);
- }
-
- #endregion
-
- #region 后台方法
- #region 原始库方法
-
- //方法
- /*------------兼容ZLG的函数描述---------------------------------*/
- [DllImport("controlcan.dll")]
- public static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved);
- //使能硬件//(通道不工作)
- [DllImport("controlcan.dll")]
- public static extern UInt32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd);
- //关闭硬件
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig);
- //初始化设备(参数配置)b31对应帧id最高位,所以11bit要左移21bit
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo);
- //读取主板信息
-
- //EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, DWORD RefType, void *pData);
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_SetReference(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, UInt32 RefType, ref VCI_FILTER_RECORD pData);
- //设置智能滤波表。(设备类型,设备id,通道id,参数类型,参数包)
- //RefType=1,添加滤波表 指向VCI_FILTER_RECORD结构的指针
- //RefType=2,可以启用滤波表
- //RefType=3,可以清除滤波表。
-
- [DllImport("controlcan.dll")]
- static extern Int32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
- //缓存区可用帧数(<=2000帧)
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
- //清空缓存区
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
- //CAN启动(启动can通道)
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
- //CAN复位通道
- [DllImport("controlcan.dll")]
- static extern Int32 VCI_Transmit(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len);
- //CAN发送(单次<=10帧)
- [DllImport("controlcan.dll")]
- static extern Int32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime);
- //CAN接收(函数调用间隔至少应设置在5ms以上。)【Len为单次封顶帧数长度的数据被读出
-
-
- /*------------其他函数描述---------------------------------*/
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_ConnectDevice(UInt32 DevType, UInt32 DevIndex);
- //硬件线连接
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_UsbDeviceReset(UInt32 DevType, UInt32 DevIndex, UInt32 Reserved);
- //硬件线断开
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_FindUsbDevice(ref VCI_BOARD_INFO1 pInfo);
- //查找可用usb的设备
- //若计算机中插入多于4个适配器,则使用VCI_FindUsbDevice2函数,最大支持50个USB-CAN适配器。
- [DllImport("controlcan.dll")]
- static extern UInt32 VCI_FindUsbDevice2(ref VCI_BOARD_INFO pInfo);
- //如:VCI_BOARD_INFO pInfo[50]。
- /*------------函数描述结束---------------------------------*/
-
-
- #endregion
- #endregion
-
-
- #region 窗体移动
-
- //private Point mouseOff;//鼠标移动位置变量
- //private bool leftFlag;//标签是否为左键
- //private void Frm_MouseDown(object sender, MouseEventArgs e)//鼠标按下
- //{
- // if (e.Button == MouseButtons.Left)
- // {
- // mouseOff = new Point(-e.X, -e.Y); //得到变量的值
- // leftFlag = true; //点击左键按下时标注为true;
- // }
- //}
- //private void Frm_MouseMove(object sender, MouseEventArgs e)//鼠标移动
- //{
- // if (leftFlag)
- // {
- // Point mouseSet = Control.MousePosition;
- // mouseSet.Offset(mouseOff.X, mouseOff.Y); //设置移动后的位置
- // //Location = mouseSet;//Form 窗体父类字段
- // }
- //}
- //private void Frm_MouseUp(object sender, MouseEventArgs e)//鼠标松开
- //{
- // if (leftFlag)
- // {
- // leftFlag = false;//释放鼠标后标注为false;
- // }
- //}
-
- #endregion
-
- #region 错误
- //try
- //{
- // byte[] buffer = Encoding.Default.GetBytes(data);//以计算机的编码发送
- // serialPort.Write(buffer, 0, buffer.Length);// 开始发送
- //}
- //catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
- #endregion
-
- #region 接口方法
-
- public bool connect<T>(T a, T b)
- {// 打开USB-CAN设备的can1通道
-
- //throw new NotImplementedException();
-
- // 配置表
- VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();
- config.AccCode = 0;// bit的DNA全部匹配,此帧才可以被接收。否则不能接收。(//标准帧右移21bit分析)
- config.AccMask = 0xffffffff;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
- config.Filter = 0;//0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
- config.Timing0 = 0x00;//波特率参数 1MHz(T0=0x00,T1=0x14)
- config.Timing1 = 0x14;
- config.Mode = 0;//模式,0表示正常模式,1表示只听模式,2自测模式
-
- uint sta = 1;
- //sta = VCI_CloseDevice(VCI_USBCAN2, CAN_inD);//设备关
- sta &= VCI_OpenDevice(Help_USB_CAN.VCI_USBCAN2, CAN_inD, 0);//使能设备(开)
- sta &= VCI_InitCAN(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1, ref config);// CAN 1
- sta &= VCI_StartCAN(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1);// 通道(开)
-
- //sta &= VCI_InitCAN(Help_USB_CAN.VCI_USBCAN2, CAN_ind, CAN2, ref config);// CAN 2
- //sta &= VCI_StartCAN(Help_USB_CAN.VCI_USBCAN2, CAN_ind, CAN2);// 通道(开)
- return sta == 1 ? true : false; // 1完成,0故障
- }
-
- public unsafe object sendAndReceive(string stringcmd)
- {//"1803052000018705"
- //"04000006014000200000000000"
- //throw new NotImplementedException();
- stringcmd.Replace(" ", "");//去除空白
- byte[] buffercmd = help_String.StringsToHexBytes(stringcmd);//准备报文 //去除空白 StringsToHexBytes
-
- VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
- string id = stringcmd.Substring(7, 3);// 从站地址
- buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
- buffer[0].SendType = 1;//发送帧类型。=0时为正常发送(发送失败会自动重发,重发超时时间为4秒, 4秒内没有发出则取消);=1时为单次发送
- buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。
-
- buffer[0].Data[0] = buffercmd[5];
- buffer[0].Data[1] = buffercmd[6];
- buffer[0].Data[2] = buffercmd[7];
- buffer[0].Data[3] = buffercmd[8];
- buffer[0].Data[4] = buffercmd[9];
- buffer[0].Data[5] = buffercmd[10];
- buffer[0].Data[6] = buffercmd[11];
- buffer[0].Data[7] = buffercmd[12];
-
- Int32 ret = VCI_set发送(Help_USB_CAN.VCI_USBCAN2, 0, 0, ref buffer[0], 1);
-
-
-
- //byte[] buff = SendAndReceive(buffer, stringcmd);// 收发报文
-
- //if (buff == null) throw new Exception("ACK 未应答。。。");
-
- //if (buff != null)
- //{
- // string str = help_String.BytesToHexStrings(buff);
- // return str;
- //}
- return null;// 发送后未接收
-
-
-
-
-
- }
-
- //public unsafe object RXs()// VCI_CAN_OBJ //CAN帧参数
- //{
- // //throw new NotImplementedException();
-
- // // 缓存区可用帧数=============================
- // uint i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, 0, 0);// can1
- // if (i > 0)// CAN1接收帧数
- // {
- // uint CAN1 = 0;
- // VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收
- // i = VCI_get接收(4, 0, CAN1, ref obj[0], 1, 0);// 注意 CAN1 通道
-
- // #region 取一帧
- // //=================================================
- // byte[] bytes = new byte[13];
- // bytes[0] = obj[0].DataLen; //obj[0].
- // uint id = obj[0].ID; // 帧 id
- // bytes[1] = (byte)(id >> 24);
- // bytes[2] = (byte)(id >> 16);
- // bytes[3] = (byte)(id >> 8);
- // bytes[4] = (byte)(id & 0xff);
-
- // fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节 第一帧
- // {
- // bytes[5] = p_obj->Data[0];
- // bytes[6] = p_obj->Data[1];
- // bytes[7] = p_obj->Data[2];
- // bytes[8] = p_obj->Data[3];
- // bytes[9] = p_obj->Data[4];
- // bytes[10] = p_obj->Data[5];
- // bytes[11] = p_obj->Data[6];
- // bytes[12] = p_obj->Data[7];
- // }
- // return bytes;
-
- // #endregion
- // //return obj;
- // }
- // return null;
- //}
-
- //public unsafe object RXs()// VCI_CAN_OBJ //CAN帧参数
- //{// CAN1 接收
-
- // //throw new NotImplementedException();
-
- // // 缓存区可用帧数=============================
- // //Help_Delay.delayTime(0.005);// usb大概3~5ms
- // int i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1);// can1
- // if (i > 0)// CAN1接收帧数
- // {
- // VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收,间隔5ms以上
- // i = VCI_get接收(4, 0, CAN1, ref obj[0], 2000, 50);// 注意 CAN1 通道
-
- // #region 取一帧 【1 4 8】
- // //=================================================
- // //byte[] bytes = new byte[13];
- // //bytes[0] = obj[0].DataLen; // 【1】有效字节
- // //uint id = obj[0].ID; // 帧 id【4】帧id
- // //bytes[1] = (byte)(id >> 24);
- // //bytes[2] = (byte)(id >> 16);
- // //bytes[3] = (byte)(id >> 8);
- // //bytes[4] = (byte)(id & 0xff);
-
- // //fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节 第一帧
- // //{
- // // bytes[5] = p_obj->Data[0];// 【8】包数据
- // // bytes[6] = p_obj->Data[1];
- // // bytes[7] = p_obj->Data[2];
- // // bytes[8] = p_obj->Data[3];
- // // bytes[9] = p_obj->Data[4];
- // // bytes[10] = p_obj->Data[5];
- // // bytes[11] = p_obj->Data[6];
- // // bytes[12] = p_obj->Data[7];
- // //}
- // //return bytes;
-
- // #endregion
- // return obj;
- // }
- // return null;
- //}
- //public unsafe object TXs(string stringcmd)// "04000006014000200000000000"
- //{//被CanOpen调用
-
- // //throw new NotImplementedException();
-
- // stringcmd.Replace(" ", "");//去除空白
- // byte[] buffercmd = help_String.StringsToHexBytes(stringcmd);//准备报文 //去除空白 StringsToHexBytes
-
- // VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
- // string id = stringcmd.Substring(2, 8);// 从站地址 00000601
- // buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
- // // 重发功能 0开,1关
- // buffer[0].SendType = 0;//0(4秒内有重发) 1只发单次
- // buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。
-
- // buffer[0].Data[0] = buffercmd[5];// byte8
- // buffer[0].Data[1] = buffercmd[6];
- // buffer[0].Data[2] = buffercmd[7];
- // buffer[0].Data[3] = buffercmd[8];
- // buffer[0].Data[4] = buffercmd[9];
- // buffer[0].Data[5] = buffercmd[10];
- // buffer[0].Data[6] = buffercmd[11];
- // buffer[0].Data[7] = buffercmd[12];
-
- // Int32 ret = VCI_set发送(Help_USB_CAN.VCI_USBCAN2, 0, CAN1, ref buffer[0], 1);// 库函数(发送TXs)
- // return ret;
- //}
-
- //public int Close()
- //{
- // //throw new NotImplementedException();
- // return (int)set_Close((UInt32)CAN设备类型.VCI_USBCAN2, CAN_inD);
- //}
-
- public bool sendAndReceive<T>(string cmd, ref T t)
- {
- throw new NotImplementedException();
- }
-
- public int RXs(ref object Obj)
- {
- //throw new NotImplementedException();
- // 缓存区可用帧数=============================
- //Help_Delay.delayTime(0.005);// usb大概3~5ms
- //int i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1);// can1
-
- VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪,单次最大支持2000帧接收,间隔5ms以上
- int num = VCI_get接收(4, 0, CAN1, ref obj[0], 2000, 50);// 注意 CAN1 通道
- if (num > 0)// CAN1接收帧数
- {
- Obj = obj;
- return num;
-
- #region 取一帧 【1 4 8】
- //=================================================
- //byte[] bytes = new byte[13];
- //bytes[0] = obj[0].DataLen; // 【1】有效字节
- //uint id = obj[0].ID; // 帧 id【4】帧id
- //bytes[1] = (byte)(id >> 24);
- //bytes[2] = (byte)(id >> 16);
- //bytes[3] = (byte)(id >> 8);
- //bytes[4] = (byte)(id & 0xff);
-
- //fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节 第一帧
- //{
- // bytes[5] = p_obj->Data[0];// 【8】包数据
- // bytes[6] = p_obj->Data[1];
- // bytes[7] = p_obj->Data[2];
- // bytes[8] = p_obj->Data[3];
- // bytes[9] = p_obj->Data[4];
- // bytes[10] = p_obj->Data[5];
- // bytes[11] = p_obj->Data[6];
- // bytes[12] = p_obj->Data[7];
- //}
- //return bytes;
-
- #endregion
-
- }
-
- return 0;
- }
- //public int RXs<T>(ref T obj)// 待测试
- //{
- // //throw new NotImplementedException();
- // VCI_CAN_OBJ[] obj2 = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收,间隔5ms以上
- // int num = VCI_get接收(4, 0, CAN1, ref obj2[0], 2000, 50);
- // if (num > 0)// CAN1接收帧数
- // {
- // //obj = obj2.ToList<T>();
-
- // return num;
- // }
- // return 0;
-
-
- // }
- unsafe bool CAN_namespace.Iface_RTX.TXs(string cmd)// "08 00000602 4064600000000000"
- {// 1 4 8 (DLC字节,帧id,Byte8数据包)
- //throw new NotImplementedException();
- cmd.Replace(" ", "");//去除空白
- byte[] buffercmd = help_String.StringsToHexBytes(cmd);//准备报文 //去除空白 StringsToHexBytes
- VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
- string id = cmd.Substring(2, 8);// 从站地址 00000602
- // 4
- buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
- // 重发功能 0开,1关
- buffer[0].SendType = 0;//0(4秒内有重发) 1只发单次
- // 1
- buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。
- // 8
- buffer[0].Data[0] = buffercmd[5];// byte8
- buffer[0].Data[1] = buffercmd[6];
- buffer[0].Data[2] = buffercmd[7];
- buffer[0].Data[3] = buffercmd[8];
- buffer[0].Data[4] = buffercmd[9];
- buffer[0].Data[5] = buffercmd[10];
- buffer[0].Data[6] = buffercmd[11];
- buffer[0].Data[7] = buffercmd[12];
- // 上车
- Int32 ret = VCI_set发送(Help_USB_CAN.VCI_USBCAN2, 0, CAN1, ref buffer[0], 1);// 库函数(发送TXs)
- if (ret == 1) return true;
-
- return false;
- }
-
- bool CAN_namespace.Iface_RTX.Close()
- {
- //throw new NotImplementedException();
- if (set_Close((UInt32)CAN设备类型.VCI_USBCAN2, CAN_inD) == 1)
- {
- return true;
- }
- return false;
- }
-
-
-
-
- #endregion
-
- }
-
-
- #endregion
-
-
-
-
- }
-
-
-

- 程序太长,在另一篇文章内。
- Help_CANopen
- Help_PLCopen
-
- 1伺服恢复出厂 0x1011-04= 0x64616f6c;
- 要等待超过1秒才会有回帧。
- 子索引2有效:
- 子索引4有效:回帧60成功
-
-
- 2伺服参数保存 0x1010-01= 0x65766173;
-
-
- //==================================
- 对象1011h:恢复默认参数【0x64616f6c】
- •子索引00h包含支持的最高子索引。
- •子索引01h是指可以恢复的所有参数。
- •子索引02h是指与通信相关的参数(索引从1000h到1FFFh)。
- •子索引03h是指与应用程序相关的参数(索引从6000h到9FFFh)。
- •从04h到7Fh的子指数制造商可以恢复他们个人选择的参数。
- •保留80h至FEh的子索引以备将来使用。
-
- 对象1010h:存储参数【0x65766173】
- •子索引00h包含支持的最高子索引。
- •子索引01h是指可能存储在CANopen设备上的所有参数。
- •子索引02h是指与通信相关的参数(从1000h到1FFFh的索引)。
- •子索引03h是指与应用程序相关的参数(索引从6000h到9FFFh)。
- •从04h到7Fh的子索引制造商可以单独存储他们选择的参数。
- •保留80h至FEh的子索引以备将来使用。

输出:
输入:
1号表示第1片,9号表示第9片。
案例:
- 站号3,第9片,输出D7和D4【0x88】
-
- 数据发:
-
- DLC=8
- 帧id=0x303
- 数据包= 0x88 0x00 0x00 0x00 0x00 0x00 0x00 0x00 【D0..D7】
CAN总线: EM32DX-C2
- 6100H DI输入寄存器 16-bit (16位输入)
- 00H U8 子索引总数
- 01H Unsigned16 IN16bit(上传16位输入值)【读DI 15~0】
- 02H Unsigned16 IN16bit(上传16位输入值)【读DI 31~16】
- 03H Unsigned16 IN16bit(上传16位输入值)【读DI 47~32】
-
- 6300H DO输出寄存器 16-bit
- 00H U8 子索引总数
- 01H Unsigned16 OUT16bit(设置16位输出值)【写DO 15~0】
- 02H Unsigned16 OUT16bit(设置16位输出值)【写DO 31~16】
- 03H Unsigned16 OUT16bit(设置16位输出值)【写DO 47~32】
ECAT总线: EM32DX-E2
- 6000H DI输入寄存器 16-bit (16位输入)
- 00H U8 子索引总数
- 01H Unsigned16 IN16bit(上传16位输入值)【读DI 15~0】
- 02H Unsigned16 IN16bit(上传16位输入值)【读DI 31~16】
- 03H Unsigned16 IN16bit(上传16位输入值)【读DI 47~32】
-
- 7000H DO输出寄存器 16-bit
- 00H U8 子索引总数
- 01H Unsigned16 OUT16bit(设置16位输出值)【写DO 15~0】
- 02H Unsigned16 OUT16bit(设置16位输出值)【写DO 31~16】
- 03H Unsigned16 OUT16bit(设置16位输出值)【写DO 47~32】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。